2

Ich habe zwei Layout-Dateien unten gezeigt.Layout-Bildschirm in Laufzeit ändern mit RecyclerView-Adapter

Wenn Daten in der Liste vorhanden sind, dann zeige ich dieses Layout.

enter image description here

und wenn die Liste leer ist, dann zeige ich dieses Layout.

enter image description here

Nun wollte ich das Layout zur Laufzeit ändern. Wenn der Benutzer den letzten Eintrag aus der Liste löscht, wollte ich das Layout in 'leeres Einkaufswagenlayout' ändern, das im zweiten Bild angezeigt wird.

In getItemCount() Methode der RecyclerView Adapter, wenn die Liste leer oder null ist, dann kehre ich als 1 zählen sonst kehre ich list.size()

Dies ist mein Adapter Code.

public class CheckOutAdapter extends RecyclerView.Adapter<CheckOutAdapter.ViewHolder> { 

    public ArrayList<Design> designList; 
    private Context context; 
    private LayoutInflater layoutInflater; 

    public CheckOutAdapter(Context context, ArrayList<Design> designList) { 
     this.designList = designList; 
     this.context = context; 
     this.layoutInflater = LayoutInflater.from(context); 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     if(designList.isEmpty() || designList == null || designList.size() == 0) { 
      View view = layoutInflater.inflate(R.layout.empty_cart, parent, false); 
      return new ViewHolder(view); 
     } else { 
      View view = layoutInflater.inflate(R.layout.checkout_single_design, parent, false); 
      return new ViewHolder(view); 
     } 
    } 

    @Override 
    public void onBindViewHolder(final ViewHolder holder, final int position) { 

     final Design design = designList.get(position); 
     holder.tvQuality.setText(design.qualityName); 
     holder.tvDesign.setText(design.designName); 
     holder.tvShade.setText(design.name); 
     holder.tvAmount.setText("₹ " + design.amount); 
     Picasso.with(context).load(design.image).into(holder.ivDesign); 
     if (design.pcs != 0) { 
      holder.btPcsCount.setText(Integer.toString(design.pcs)); 
     } 

     holder.ivDelete.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       openDialog(design); 
      } 
     }); 
     //other ClickListeners. 
    } 

    @Override 
    public int getItemCount() { 
     if (designList == null || designList.isEmpty() || designList.size() == 0) { 
      return 1; 
     } else { 
      return designList.size(); 
     } 
    } 

    public static class ViewHolder extends RecyclerView.ViewHolder { 

     public LinearLayout llPer; 
     public Button btPlus, btMinus, btPcsCount, btAddCart; 
     public ImageView ivDesign, ivDelete; 
     public TextView tvDesign, tvQuality, tvShade, tvAmount, tvDiscAmt, tvDisPer; 

     public ViewHolder(View itemView) { 
      super(itemView); 

      llPer = (LinearLayout) itemView.findViewById(R.id.llPer); 
      btPlus = (Button) itemView.findViewById(R.id.btPlus); 
      //other findViewByIds 
     } 
    } 

    public void openDialog(final Design design) { 
     AlertDialog.Builder builder = new AlertDialog.Builder(context); 
     builder.setTitle("Confirm"); 
     builder.setMessage("Remove item from cart?"); 
     builder.setPositiveButton("YES", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) { 
       designList.remove(design); 
       notifyDataSetChanged(); 
       saveSharedPref(context, "cart", new Gson().toJson(designList)); 
       Toast.makeText(context, "deleted", Toast.LENGTH_SHORT).show(); 
       dialog.dismiss(); 
      } 
     }); 

     builder.setNegativeButton("NO", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       dialog.dismiss(); 
      } 
     }); 

     AlertDialog alert = builder.create(); 
     alert.show(); 
    } 
} 

Ich bin immer in der Nähe von Nullpointer onBindViewHolder. Ich weiß nicht, warum es abgestürzt ist. Bitte geben Sie Vorschläge.

+0

Sie müssen getItemViewType überschreiben, um Laufzeitlayout zu setzen –

Antwort

2

Sie können das getItemViewType() zwingende tun:

@Override 
public int getItemViewType(int position) { 
    if (designList.size() == 0) return R.layout.empty; 
    else return R.layout.normal_layout; 
} 

@Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false); 
    ViewHolder viewHolder = null; 
    if (viewType == R.layout.empty) { 
     viewHolder = new EmptyViewHolder(view); 
    } else { 
     viewHolder = new NormalViewHolder(view); 
    } 
    return viewholder; 
} 

@Override 
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
    if (holder instanceOf EmptyViewHolder){ 
     // this is empty item, update view appropriately if needed 
    } else { 
     // this is normal item, update view appropriately if needed 
    } 
} 

Nun, wenn Datenmenge ändert und es gibt nur noch 1 Artikel in Ihrem Adapter, können Sie das gewünschte Layout angezeigt bekommen würde.

-1

Schauen Sie ... wenn Sie 1 wiederholen, obwohl Ihr Datensatz keine Daten hat .. Ihr Adapter versucht, eine Ansicht von einem leeren Datensatz zu binden, deshalb erhalten Sie einen Nullzeiger.

** Vielmehr können Sie dies tun **

@Override //add this method to your adapter 
public int getItemViewType(int position) { 
    if(designList.size()==0){ 
     return 1; 
     }else{ 
     return 2; 
    } 
} 

auch in Ihrem onCreateView Inhaber dies tun ..

@Override // modify your onCreate based on viewtype 
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    if(viewType == 1) { //for empty layout 
     View view = layoutInflater.inflate(R.layout.empty_cart, parent, false); 
     return new ViewHolder(view); 
    } else { 
     View view = layoutInflater.inflate(R.layout.checkout_single_design, parent, false); 
     return new ViewHolder(view); 
    } 
} 

in ihrem Bindview() dies tun:

@Override/
public void onBindViewHolder(final ViewHolder holder, final int position) { 

    if(designList.size()>0){ 
     final Design design = designList.get(position); 
    holder.tvQuality.setText(design.qualityName); 
    holder.tvDesign.setText(design.designName); 
    holder.tvShade.setText(design.name); 
    holder.tvAmount.setText("₹ " + design.amount); 
    Picasso.with(context).load(design.image).into(holder.ivDesign); 
    if (design.pcs != 0) { 
     holder.btPcsCount.setText(Integer.toString(design.pcs)); 
    } 

    holder.ivDelete.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      openDialog(design); 
     } 
    }); 
    //other ClickListeners. 
    }else{ 
     //handle the empty layout Add button click listener 
    } 

} 

Hoffe, dass hilft

-1
@Override 
public int getItemViewType(int position) { 
     if ((designList.isEmpty() || designList == null || designList.size() == 0) { 
        return R.layout.empty_cart; 
     } 
     return R.layout.checkout_single_design; 
} 

@Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     if (viewType == R.layout.empty_cart) { 
      return new EmptyViewHolder(layoutInflater.inflate(viewType, parent, false)); 
     } else { 
      return new ViewHolder(layoutInflater.inflate(viewType, parent, false)); 
     } 
    } 
+0

Keine Notwendigkeit, Logiken von 'getItemCount()' zu duplizieren. Falsche Initialisierung von ViewHolders. – azizbekian

+0

Warum Sie diese Antwort abgelehnt haben, während Sie eine eigene Antwort hatten, war zunächst falsch und wurde später aktualisiert !! Ich habe 'getItemCount()' Methode dann nicht gezeigt, wie es veröffentlicht wird? Und meine ViewHolder-Initialisierung war überhaupt nicht falsch. Wenn Sie sich die Frage ansehen, initialisiert eine Ansicht über 'layoutInflater.inflate (R.layout.empty_cart, parent, false);'. Und dieses 'layoutInflater' wurde im Adapterkonstruktor initialisiert, diese Ansicht wurde an das 'ViewHolder'-Objekt übergeben, was überhaupt nicht inkorrekt ist. – CodeCameo

+0

Zuerst habe ich meine Antwort nicht aktualisiert, überprüfen Sie, was Sie sagen. Zweitens, wenn Sie versuchen, den Code innerhalb von 'onCreateViewHolder' auszuführen, werden Sie feststellen, dass es in Java keinen solchen Konstruktor gibt, Sie müssen 'new EmptyViewHolder (...)' ausführen, zweitens wird 'viewHolder' nirgendwo deklariert. Drittens, wenn es deklariert wurde, führen Sie keine Zuweisung durch, was dazu führt, dass "viewHolder" zu "null" wird. – azizbekian

Verwandte Themen