2

以下に2つのレイアウトファイルがあります。実行時にRecyclerViewアダプタを使用してレイアウト画面を変更します

データがリストにある場合は、このレイアウトを表示します。

enter image description here

とリストが空であるとき、私はこのレイアウトを示しています。今

enter image description here

私は、実行時にレイアウトを変更するようでした。これまでユーザーがリストから最後のアイテムを削除すると、2番目のイメージに表示されている「空のカートレイアウト」にレイアウトを変更したかったのです。 RecyclerViewアダプタのgetItemCount()方法で

リストが空またはnullの場合、私は1としてカウント返すそうでない私は、これは私のアダプターのコードですlist.size()

を返します。

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

onBindViewHolderの近くでNullPointerExceptionが発生しています。私はなぜそれが墜落するか分からない。提案をお願いします。

+0

ランタイムレイアウトを設定するにはgetItemViewTypeをオーバーライドする必要があります –

答えて

2

あなたがgetItemViewType()をオーバーライドすることを行うことができます。

@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 
    } 
} 

、データセットの変更およびお使いのアダプタで唯一の1項目がありますが、あなたが希望のレイアウトを示す取得したいとき。

-1

データセットにデータがなくても1を再取得すると、アダプターは空のデータセットからビューをバインドしようとしているため、ヌルポインターを取得しています。

@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 
    } 

} 

**むしろあなたがonCreateViewホルダーにも**

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

にこれを行うことができ、これを行う。..

あなたbindView(で今
@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); 
    } 
} 

)がこれを行います

希望があれば

-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

'getItemCount()'のロジックを公開する必要はありません。 ViewHoldersの初期化が正しくありません。 – azizbekian

+0

あなたは自分の答えが最初は間違っていて、後で更新されている間、この答えをなぜ落としたのですか?私は 'getItemCount()'メソッドを表示していないので、それをどのように公開するのですか?私のViewHolderの初期化は全く間違っていませんでした。あなたが質問を見てみると、ビューは 'layoutInflater.inflate(R.layout.empty_cart、parent、false);で初期化されていました。そして、この 'layoutInflater'はアダプタコンストラクタで初期化されました。そのビューは' ViewHolder'オブジェクトに渡されましたが、これはまったく間違っていません。 – CodeCameo

+0

私は自分の答えを更新していない、あなたの言うことを再確認している。第2に、 'onCreateViewHolder'の中でコードを実行しようとすると、Javaにそのようなコンストラクタがないことがわかります。新しいEmptyViewHolder(...)を実行する必要があります。次に、' viewHolder'はどこにも宣言されません。第3に、宣言されていれば、割り当てを実行していないので、 'viewHolder'が' null'になります。 – azizbekian

関連する問題