0

I'm trying to use two layout for my RecyclerView items and I wrote this code for my purpose. It should change layout in odd and even basis numbers

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

private Context context;
private List<Word> words;
public int counter = 1;

public WordListAdaptor(Context context, List<Word> words){

    this.context = context;
    this.words = words;

}


@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view;
    if ( this.counter % 2 == 0) {
        view = LayoutInflater.from(this.context).inflate(R.layout.search_listview_gray, parent, false);
    } else{
    view = LayoutInflater.from(this.context).inflate(R.layout.search_listview_blue,parent,false);}

    this.counter ++;

    return new ViewHolder(view);
}

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

    if ( this.counter % 2 == 0)

        holder.textViewGray.setText(words.get(position).getOrginalWord() + " Pos : " + position);

    else
        holder.textViewBlue.setText(words.get(position).getOrginalWord() + " Pos : " + position);


}

@Override
public int getItemCount() {
    return words.size();
}

class ViewHolder extends RecyclerView.ViewHolder{

    private TextView textViewBlue;
    private TextView textViewGray;
    private ImageButton blueItemStar;
    private ImageButton grayItemStar;

    public ViewHolder(View itemView) {
        super(itemView);
        textViewBlue = itemView.findViewById(R.id.listView_item_textView_blue);
        textViewGray = itemView.findViewById(R.id.listView_item_textView_gray);
        blueItemStar = itemView.findViewById(R.id.blue_item_star);
        grayItemStar = itemView.findViewById(R.id.gray_item_star);
    }
}
}

But for this code, I get this error

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

for one one layout it is working good but after I add a condition to change layout file, I get error.

Artin GH
  • 546
  • 2
  • 10
  • 21
  • it's not an answer to your question but you can rename ViewHolder class (to something like ItemHolder ) becuase it's same with RecyclerView.ViewHolder class – Kapta Jun 03 '18 at 19:58
  • Try to use the better approach to your problem do not hack. RecyclerView is flexible. See examples here : https://guides.codepath.com/android/Heterogenous-Layouts-inside-RecyclerView – Lester L. Jun 04 '18 at 05:29

1 Answers1

0

I'm not sure you can rely on the fact that the holders you create in onCreateViewHolder will hold the same views for the same positions in onBindViewHolder, after all the purpose of a recycler view is to recycle the views. Basically, you might receive previous view holders that went off screen and you have to recycle them. Clean the state and put the new one. You might get lucky that they contain the views you want, but you might not. When you have 2 different views or more, usually the approach is to use view types - see this answer.

In any case, let's assume you can be sure that the holder would have the view you expect. Let's say your recycler view has 1 item. This expression this.counter % 2 == 0 evaluates to true and you create a holder for a "gray" view. Then you're incrementing the value of counter - this.counter ++;. onBindViewHolder gets called and the same condition is evaluated, but now turns out that counter is odd and you're trying to access subviews of your "blue" view that were in fact never inflated. This causes a null pointer exception in holder.textViewBlue.setText.

I suggest to check out the view types and implement them for your use case.

Fred
  • 16,367
  • 6
  • 50
  • 65