1

RecyclerViewからすべてのチェックボックスを取得しようとしています。ただし、このエラーが表示されます。以下は、LogCatが指し示すクラスです。ItemViewがnullでない可能性があります

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); 
    } 
} 

}

答えて

0

方法getChildAtViewGroupの方法なので、recycler.getChildAt(i)はあなたのためにnullになります。あなたのケースでは、produtosリストを使用して、それを反復し、 "checked"状態に関連付けられたフィールドを "false"に設定し、onBindViewHolder()がホルダーのcheckBox値を自動的に変更します。

ので、代わりの

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); 
       } 
      } 

このいずれかを使用します。私はあなたのクラスのプロジェクトは、このような方法がありますsupppose

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

+0

ありがとうございます。しかし、私のチェックボックスはProdutoとの関連はありません。 –

+0

@MarceloAugusto、これは、recycllerviewの項目がモデルを表します。この場合はProductです。アイテムのすべてのビューはモデルから取得する必要があります(デザインが良い)。 –

+0

私が理解したように、チェックボックスは商品のいくつかの特性を表しているので、もちろん商品のいくつかのフィールドかもしれません。このチェックボックスを導入した場合は、どこかで使用されます。チェックされます。 –

0

RecyclerViewでは、アイテムビューはリサイクルされているので、リスト内のアイテムと同じ数のアイテムビューは表示されません。代わりにそれらのitemviewsはリサイクルされ、あなたのproductosリストのdifferents要素を示しています。

あなたの問題は、あなたがリストの長さを持つforループにありますが、あなたがそのインデックスを使って多くの要素を持たないitemviewsにアクセスしているということです。

代わりに、Producto.classに変数を定義し、アイテムのCheckBoxをチェック/チェック解除するたびに更新する必要があります。あなたはすべてをオフにして、呼び出したいときにはこの変数をfalseに設定し

adapter.notifyDataSetChanged(); 

UPDATE:

ProdutoAdapter.java

onBindViewHolderこのようにリストprodutosとアップデートにアクセスするためのメソッドを定義します。

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をupdatにリストするeは各プロダクトのブール値です。

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

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

あなたの答えをありがとう。私はこの変更を加えたが、チェックボックスは更新されない。 –

+0

@MarceloAugustoアップデートを確認する – jorgeavilae

関連する問題