问题:addView with ArrayList

时间:2017-03-08 20:57:51

标签: java android

我收到以下错误:

  

java.lang.IllegalStateException:指定的子级已有父级。您必须先在孩子的父母身上调用removeView()。

我从View中移除了Parent,但它无效。

代码:

LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout root = (LinearLayout) linha.findViewById(R.id.ingredientes_sel);
List views = new ArrayList();

View view = inflater.inflate(R.layout.item_obs_carrinho, null);
view.setLayoutParams(
        new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));

if (tipo == 2 || tipo == 3) { //add
    for (int i = 0; i < objetos_add.get(0).length; i++) {
        if (!objetos_add.get(0)[i].equals("")) {
            if (view.getParent() != null)
                ((ViewGroup) view.getParent()).removeView(view);
            TextView n = (TextView) view.findViewById(R.id.item_ingred_carrinho);
            n.setText(objetos_add.get(0)[i]);

            TextView qtd = (TextView) view.findViewById(R.id.quantidade);
            qtd.setText(objetos_add.get(1)[i]);

            views.add(view);
        }
    }
}
if (tipo == 1 || tipo == 3) { //rem
    for (int i = 0; i < objetos_rem.get(0).length; i++) {
        if (!objetos_rem.get(0)[i].equals("")) {
            if (view.getParent() != null)
                ((ViewGroup) view.getParent()).removeView(view);
            TextView n = (TextView) view.findViewById(R.id.item_ingred_carrinho);
            n.setText(objetos_rem.get(0)[i]);

            TextView qtd = (TextView) view.findViewById(R.id.quantidade);
            qtd.setText("");

            ImageView add = (ImageView) view.findViewById(R.id.add_ou_rem);
            add.setImageResource(android.R.drawable.ic_delete);

            views.add(view);
        }
    }
}

for (int i = 0; i < views.size(); i++)
    root.addView((View) views.get(i)); /* <---- ERRO  */

有什么问题?

修改

基于这个问题:Dynamic layout inflator within a loop

1 个答案:

答案 0 :(得分:0)

你做过一次

View view = inflater.inflate(R.layout.item_obs_carrinho, null);

然后你多次调用root.addView(view),因此之前添加的任何view都是完全相同的,因此会有一个父级。

您需要对随后添加到根目录的多个视图进行通知。

所以,你可以提取出这个方法

private View getCustomView(LayoutInflater inflater, int tipo, List<String[]> data, int pos) {
    // Inflate
    View view = inflater.inflate(R.layout.item_obs_carrinho, null);
    view.setLayoutParams(
            new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));

    // Remove parent
    if (view.getParent() != null)
        ((ViewGroup) view.getParent()).removeView(view);

    // Find Views
    TextView n = (TextView) view.findViewById(R.id.item_ingred_carrinho);
    TextView qtd = (TextView) view.findViewById(R.id.quantidade);

    // Set views based on type
    if (tipo == 2 || tipo == 3) { // add
        n.setText(data.get(0)[pos]);
        qtd.setText(data.get(1)[pos]);
    } else if (tipo == 1 || tipo == 3) { // rem
        n.setText(data.get(0)[pos]);
        qtd.setText("");
        ImageView add = (ImageView) view.findViewById(R.id.add_ou_rem);
        add.setImageResource(android.R.drawable.ic_delete);
    }
    return view;
}

然后在这两个循环之间调用它。

final LayoutInflater inflater = LayoutInflater.from(MainActivity.this);

// tipo = 2 or 3
for (int i = 0; i < objetos_add.get(0).length; i++) {
    if (!objetos_add.get(0)[i].isEmpty()) {
        root.addView(getCustomView(inflater, tipo, objetos_add, i));
    }
}

// tipo = 1 or 3
for (for int i = 0; i < objetos_rem.get(0).length; i++) {
    if (!objetos_rem.get(0)[i].isEmpty()) {
        root.addView(getCustomView(inflater, tipo, objectos_rem, i));
    }
}