ItemView可能不为null

时间:2017-03-26 16:07:15

标签: java android checkbox android-recyclerview android-viewholder

我试图从我的RecyclerView中检索所有复选框以取消选中它们。但是,会显示此错误。以下是LogCat指向的类。

java.lang.IllegalArgumentException: itemView may not be null
             at android.support.v7.widget.RecyclerView$ViewHolder.<init>(RecyclerView.java:10314)
             at br.com.ufrn.marceloaugusto.tasklist.adapter.ProdutoAdapter$ProdutosViewHolder.<init>(ProdutoAdapter.java:0)
             at br.com.ufrn.marceloaugusto.tasklist.MainActivity.onOptionsItemSelected(MainActivity.java:93)

MainActivity.java

public class MainActivity extends BaseActivity {

    //private SQLiteDatabase banco;

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

        if (savedInstanceState == null) {
            FragmentProdutos frag = new FragmentProdutos();
            getSupportFragmentManager().beginTransaction().add(R.id.container, frag).commit();
        }

        //FAB
        findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                snack(view, "Adicionar produto");
            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.action_desmarkAll) {
            RecyclerView recycler = (RecyclerView) findViewById(R.id.recyclerView);
            ProdutoAdapter.ProdutosViewHolder holder = null;
            int id = 0;
            for (int i = 0; i < recycler.getAdapter().getItemCount(); i++) {
                holder = new ProdutoAdapter.ProdutosViewHolder(recycler.getChildAt(i)); **//Line 93**
                if (holder.checkBox.isChecked()) {
                    holder.checkBox.setChecked(false);
                }
            }
            return true;
        }
        return super.onOptionsItemSelected(item);
    }} 

ProdutoAdapter.java

public class ProdutoAdapter extends RecyclerView.Adapter<ProdutoAdapter.ProdutosViewHolder> {
private final Context context;
private final List<Produto> produtos;
//Interface para expor os eventos de toque na lista
private ProdutoOnClickListener produtoOnClickListener;
private ProdutoOnCheckListener produtoOnCheckListener;

public ProdutoAdapter(Context context, List<Produto> produtos, ProdutoOnClickListener produtoOnClickListener, ProdutoOnCheckListener produtoOnCheckListener) {
    this.context = context;
    this.produtos = produtos;
    this.produtoOnClickListener = produtoOnClickListener;
    this.produtoOnCheckListener = produtoOnCheckListener;
}

@Override
public int getItemCount() {
    return this.produtos != null ? this.produtos.size() : 0;
}

@Override
public ProdutosViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(context).inflate(R.layout.adapter_produto, parent, false);
    ProdutosViewHolder holder = new ProdutosViewHolder(view);
    return holder;
}

@Override
public void onBindViewHolder(final ProdutosViewHolder holder, final int position) {
    Produto p = produtos.get(position);
    holder.tNome.setText(p.getNome());
    //holder.tPreco.setText(String.valueOf(p.getPreco()));
    if (produtoOnClickListener != null) {
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                produtoOnClickListener.onClickProduto(view, position);
            }
        });
    }
    if (produtoOnCheckListener != null) {
        holder.checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                produtoOnCheckListener.onCheckProduto(view, position);
            }
        });
    }
}

public interface ProdutoOnClickListener {
    public void onClickProduto(View view, int idx);
}

public interface ProdutoOnCheckListener {
    public void onCheckProduto(View view, int position);
}

public static class ProdutosViewHolder extends RecyclerView.ViewHolder {
    public TextView tNome;
    //public TextView tPreco;
    CardView cardView;
    public CheckBox checkBox;
    public ProdutosViewHolder(View view) {
        super(view);
        tNome = (TextView) view.findViewById(R.id.nomeProduto);
        //tPreco = (TextView) view.findViewById(R.id.precoProduto);
        cardView = (CardView) view.findViewById(R.id.card_view);
        checkBox = (CheckBox) view.findViewById(R.id.checkProduto);
    }
}

}

2 个答案:

答案 0 :(得分:0)

方法getChildAtViewGroup的方法,因此recycler.getChildAt(i)将是null。在您的情况下,您应该使用produtos列表,迭代它并将其与“已检查”状态关联的字段设置为“false”,调用适配器的notifyDataSetChanged()方法,然后onBindViewHolder()将自动更改持有者的复选框值。

所以而不是

for (int i = 0; i < recycler.getAdapter().getItemCount(); i++) {
                holder = new ProdutoAdapter.ProdutosViewHolder(recycler.getChildAt(i)); **//Line 93**
                if (holder.checkBox.isChecked()) {
                    holder.checkBox.setChecked(false);
                }
            }

使用这个:

for (Product product : produtos){
     product.setChecked(false);
}
recycler.getAdapter().notifyDataSetChanged();

我认为你的班级项目有这样的方法。

答案 1 :(得分:0)

在RecyclerView中,项目视图被回收,因此您没有列表中项目的项目视图。相反,这些项目视图会被回收并显示产品列表的不同元素。

你的问题是你处于一个带有List长度的for循环中,但你正在使用该索引来访问没有那么多元素的itemviews。

相反,您应该在Producto.class中定义一个变量,并在每次检查/取消选中项目的CheckBox时更新。如果要取消选中所有并调用

,请将此变量设置为false
adapter.notifyDataSetChanged();

<强>更新

ProdutoAdapter.java

定义一个方法来访问列表produtos并更新onBindViewHolder,如下所示:

if (produtoOnCheckListener != null) {
    holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
            produtos.get(position).setCheckBoxState(b);
            produtoOnCheckListener.onCheckProduto(view, position);
        }
    });
}

MainActivity.class定义ProductoAdapter变量并访问列表productos以更新每个producto的布尔值

[...]
ProductoAdapter productoAdapter = new ProductoAdapter();
[...]

for (int i = 0; i < productoAdapter.getItemCount(); i++) {
    productoAdapter.getListProductos().get(i).setCheckBoxState(false);      
}
productoAdapter.notifyDataSetChanged();