简体   繁体   中英

How to use removeView()?

I was trying to create a TextView programatically and add it to my layout by using addView() function, but I get the runtime exception which is saying "The specified child already has a parent. You must call removeView() on the child's parent first". I've looked all the questions asked about this subject, but still couldn't understand how to and when to use removeView() function.

So here's my code:

import android.content.Intent;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

private int maxNumber = 6;
private Integer[] numbers = new Integer[maxNumber];
private Integer[] textSizes = new Integer[maxNumber];
private Integer[] colors = new Integer[8];
private Integer[] randomColors = new Integer[maxNumber];
private Integer[][] margins;
private LayoutParams params[];
private int maxValue = 1000;
private int maxSize = 50;
private int minSize = 15;
private int viewCount = 0;
private int startCount = 3;
private int layoutHeight;
private int layoutWidth;
private int score = 0;
private RelativeLayout layout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    layout = (RelativeLayout) findViewById(R.id.layout);
    LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    layout.setLayoutParams(layoutParams);

    DisplayMetrics displayMetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    layoutHeight = displayMetrics.heightPixels;
    layoutWidth = displayMetrics.widthPixels;


    String[] colorsTxt = getApplicationContext().getResources().getStringArray(R.array.colors);
    for (int i = 0; i < colorsTxt.length; i++) {
        int newColor = Color.parseColor(colorsTxt[i]);
        colors[i] = newColor;
    }

    createTextView(3);
}

private void createTextView(int num)
{
    final TextView tv = new TextView(this);

    createProperties(num);

    eliminateSameRandoms();

    for(int i = viewCount; i < (viewCount + num); i++)
    {
        tv.setLayoutParams(params[i]);
        tv.setText(String.valueOf(numbers[i]));
        tv.setTextColor(randomColors[i]);
        tv.setTextSize(textSizes[i]);
        createListener(tv);
        layout.addView(tv);
    }
    viewCount += num;
}

private void createListener(final TextView textView)
{
    textView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (Integer.parseInt(String.valueOf(textView.getText())) == getBiggest()) {
                score++;
                if(viewCount == startCount * startCount) {
                    startCount++;
                    createTextView(startCount);
                }
                else {
                    createTextView(startCount);
                }
            } else {
                Intent i = new Intent(MainActivity.this, FailActivity.class);
                i.putExtra("score", score);
                startActivity(i);
            }
        }
    });

}

private int getBiggest()
{
    int max = 0;
    for(int i : numbers)
    {
        if(i > max)
        {
            max = i;
        }
    }
    return max;
}

private void createProperties(int num)
{
    createRandoms(num);
    createColors(num);
    createTextSizes(num);
    createMargins(num);
    createParams(num);
}

private void createRandoms(int numRandoms)
{
    for(int i = viewCount; i < (viewCount + numRandoms); i++)
    {
        numbers[i] = new Random().nextInt(maxValue);
    }
}

private void createParams(int numParams)
{
    params = new LayoutParams[numParams];
    for(int i = viewCount; i < (viewCount + numParams); i++)
    {
        params[i] = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        params[i].leftMargin = margins[i][0];
        params[i].topMargin = margins[i][1];
    }
}

private void createMargins(int numMargins)
{
    margins = new Integer[numMargins][2];
    for(int i = viewCount; i < (viewCount + numMargins); i++)
    {
        margins[i][0] = new Random().nextInt(layoutWidth - 40) + 20;
        margins[i][1] = new Random().nextInt(layoutHeight - 40) + 20;
    }
}

private void createTextSizes(int numTextSizes)
{
    for(int i = viewCount; i < (viewCount + numTextSizes); i++)
    {
        textSizes[i] = new Random().nextInt(maxSize - minSize) + minSize;
    }
}

private void createColors(int numColors)
{
    for(int i = viewCount; i < (viewCount + numColors); i++)
    {
        randomColors[i] = colors[new Random().nextInt(colors.length - 1)];
    }
}

private boolean inRange(int position, int other)
{
    int range = 60;
    return !(position - other < range && other - position < range);
}

private void eliminateSameRandoms()
{
    int numRandoms = viewCount;
    int i = 0;
    while(i < numRandoms)
    {
        for(int j = 0; j < numRandoms; j++)
        {
            Log.d("i: " , String.valueOf(i));
            Log.d("j: " , String.valueOf(j));
            if(j != (numRandoms - i))
            {
                while (numbers[j].equals(numbers[numRandoms - (i + 1)]))
                {
                    numbers[j] = new Random().nextInt(maxValue);
                }
                while (randomColors[j].equals(randomColors[numRandoms - (i + 1)]))
                {
                    randomColors[j] = colors[new Random().nextInt(colors.length)];
                }
                while (textSizes[j].equals(textSizes[numRandoms - (i + 1)]))
                {
                    textSizes[j] = new Random().nextInt(maxSize - minSize) + minSize;
                }
                while(inRange(margins[j][0], margins[numRandoms - (i + 1)][0]))
                {
                    margins[j][0] = new Random().nextInt(layoutWidth - 40) + 20;
                }
                while(inRange(margins[j][1], margins[numRandoms - (i + 1)][1]))
                {
                    margins[j][1] = new Random().nextInt(layoutHeight - 40) + 20;
                }
            }
        }
        i++;
    }
}

}

There is only a RelativeLayout in my XML layout which has the id = layout

I tried to use

((ViewGroup)tv.getParent()).removeView(tv);

before

layout.addView(tv);

at various positions in my code but none of them worked.

I've looked this and this but couldn't figure out the solution.

Where and how should I use removeView() ?

You're adding the same TextView over and over again to your layout. After the first time, the TextView has a parent, that's why you get the error. Initialize your TextView in the loop and it will fix your error:

for(int i = viewCount; i < (viewCount + num); i++)
{
    final TextView tv = new TextView(this);
    tv.setLayoutParams(params[i]);
    tv.setText(String.valueOf(numbers[i]));
    tv.setTextColor(randomColors[i]);
    tv.setTextSize(textSizes[i]);
    createListener(tv);
    layout.addView(tv);
}

If you initialize it like this, you create a new TextView every time which does not have a parent yet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM