1

Ich versuche, alle Kontrollkästchen aus meinem RecyclerView abzurufen, um sie zu deaktivieren. Dieser Fehler wird jedoch angezeigt. Im Folgenden sind die Klassen aufgeführt, auf die LogCat verweist.ItemView darf nicht null sein

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

}

Antwort

0

Methode getChildAt Methode von ViewGroup ist, so wird recycler.getChildAt(i)null für Sie sein. In Ihrem Fall sollten Sie die produtos Liste verwenden, über sie iterieren und ihr dem "checked" Status zugeordnetes Feld auf "false" setzen, die Methode notifyDataSetChanged() Ihres Adapters aufrufen und dann onBindViewHolder() automatisch die CheckBox Werte des Inhabers ändern.

Also statt

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

Verwendung dieses:

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

supppose ich Ihre Klasse Projekt ein solches Verfahren hat.

+0

Vielen Dank für Ihre Antwort. Aber meine Checkbox hat keine Verbindung mit Produto. –

+0

@MarceloAugusto, sollte es, weil Element in Recyclerview Modell darstellt, das Produkt in diesem Fall ist. Jede Ansicht in dem Artikel sollte vom Modell (in gutem Design) abgerufen werden. –

+0

Wie ich verstanden habe, stellt das Kontrollkästchen eine Eigenschaft des Elements dar, also könnte es natürlich ein Feld im Produkt sein, und wenn Sie dieses Kontrollkästchen eingeführt haben, wird es irgendwo verwendet, dann ist es sinnvoll, dieses Feld im Produkt zu verwenden, um ein bestimmtes Produkt zu erkennen wird geprüft". –

0

In einer RecyclerView werden die Objektansichten wiederverwendet, sodass Sie nicht so viele Objektansichten wie Objekte in Ihrer Liste haben. Stattdessen werden diese Artikelansichten wiederverwendet und zeigen verschiedene Elemente Ihrer Produktliste.

Ihr Problem ist, dass Sie in einer for-Schleife mit der Länge der Liste sind, aber Sie verwenden diesen Index für den Zugriff auf Artikelansichten, die nicht so viele Elemente hat.

Stattdessen sollten Sie eine Variable in Producto.class definieren und jedes Mal aktualisieren, wenn Sie die CheckBox des Elements aktivieren/deaktivieren. Und setzen Sie diese Variable auf false, wenn Sie alle deaktivieren wollen und rufen

adapter.notifyDataSetChanged(); 

UPDATE:

ProdutoAdapter.java

eine Methode definieren, um die Liste produtos zugreifen und diese aktualisieren onBindViewHolder wie folgt aus:

MainActivity.class Definieren Sie eine ProductoAdapter-Variable und greifen Sie auf die zu aktualisierenden Produkte zu e der boolesche Wert jedes Produktes

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

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

Vielen Dank für Ihre Antwort. Ich habe diese Änderung vorgenommen, aber die Kontrollkästchen werden nicht aktualisiert. –

+0

@MarceloAugusto überprüfen Sie das Update – jorgeavilae

Verwandte Themen