3

I read How to create RecyclerView with multiple view type? but didn't understand few things.

First of all, my goal is:

  1. I don't understand how getItemViewType (works in my case):

    public int getItemViewType(int position) {
      // Just as an example, return 0 or 2 depending on position
      // Note that unlike in ListView adapters, types don't have to be contiguous
      return position % 2 * 2;
    }
    

    Because, I want to

  2. set Item2 ONLY after the click not right at the beginning. This causes problems for me to understand, how to implement getItemViewType. Any pseudo code/prototype are more than welcome.

CODE: [FIRST APPROACH - Setting every second row as detail layout and try to hide it on default. Change visibility onClick method later on..]

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

private List<Model> items;
FragmentActivity c;


public DifferentRowAdapter(List<Model> items, FragmentActivity c) {
    this.items = items;
    this.c = c;
}


@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view;

    switch (viewType) {
        case MEAL_TYPE:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rec_item, parent, false);
            return new ViewHolder1(view);
        case DETAIL_TYPE:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.detail_test, parent, false);
            return new ViewHolder2(view);
    }
    return null;
}

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

    final Model object = items.get(position);
    final int currentPosition = position;


    if (object != null) {
        switch (object.getmType()) {
            case MEAL_TYPE:
                ((ViewHolder1) holder).mNameTextView.setText(object.getName());
                ((ViewHolder1) holder).img.setImageResource(R.mipmap.ic_launcher);
                break;
            case DETAIL_TYPE:
                ((ViewHolder2) holder).detailsText.setText(object.getDescription());
                break;
        }
    }

}

@Override
public int getItemCount() {
    if (items == null)
        return 0;
    return items.size();
}



@Override
public int getItemViewType(int position) {
       // I need ITEM2 to be at third/sixth/nineth ect. position
       if(position % 3 == 0){
            return DETAIL_TYPE;
       }
       else{
           return MEAL_TYPE;
       }

}

public class ViewHolder1 extends RecyclerView.ViewHolder {

    TextView mNameTextView;
    ImageView img;
    mealsItemClickListener icl;

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

        mNameTextView = (TextView) itemView.findViewById(R.id.name);
        img = (ImageView) itemView.findViewById(R.id.category_image);
    }

    public TextView getmNameTextView() {
        return mNameTextView;
    }
    public void setmNameTextView(TextView mNameTextView) {
        this.mNameTextView = mNameTextView;
    }
    public ImageView getImg() {
        return img;
    }
    public void setImg(ImageView img) {
        this.img = img;
    }
}


public class ViewHolder2 extends RecyclerView.ViewHolder {

    TextView detailsText;
    mealsItemClickListener icl;

    public ViewHolder2(View v) {
        super(v);
        detailsText = (TextView) itemView.findViewById(R.id.desc);
    }

    public TextView getDetailsText() {
        return detailsText;
    }
    public void setDetailsText(TextView detailsText) {
        this.detailsText = detailsText;
    }
}


}

[2 APPROACH - Try to add ITEM2 onClick]

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

private List<Model> items;
FragmentActivity c;


public DifferentRowAdapter(List<Model> items, FragmentActivity c) {
    this.items = items;
    this.c = c;
}


@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view;

    switch (viewType) {
        case MEAL_TYPE:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rec_item, parent, false);
            return new ViewHolder1(view);
        case DETAIL_TYPE:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.detail_test, parent, false);
            return new ViewHolder2(view);
    }
    return null;
}

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

    final Model object = items.get(position);
    final int currentPosition = position;


    if (object != null) {
        switch (object.getmType()) {
            case MEAL_TYPE:
                ((ViewHolder1) holder).mNameTextView.setText(object.getName());
                ((ViewHolder1) holder).img.setImageResource(R.mipmap.ic_launcher);
                break;
            case DETAIL_TYPE:
                ((ViewHolder2) holder).detailsText.setText(object.getDescription());
                break;
        }

        //THIS METHOD WORKS FINE POSITIONING WISE, BUT IT DUPLICATES CLICKED ITEM INSTEAD OF PUTTING ITEM2
        ((ViewHolder1) holder).img.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){

            Toast.makeText(c, "Position: " + currentPosition, Toast.LENGTH_SHORT).show();
                addItem(currentPosition, object);
        }
    });
    }

}

@Override
public int getItemCount() {
    if (items == null)
        return 0;
    return items.size();
}

    @Override
    public int getItemViewType(int position) {
        if (items != null) {
           Model object = items.get(position);
            if (object != null) {
                return object.getmType();
          }
        }
        return 0;
    }

    // Check if clicked item is left/right  
    private boolean isLeft(final int position){
    if (position % 2 == 0){
        return true; // Returns 1 if it's left columns item
    }
    else return false;
    }

    // Add item at wanted position. If left pos+2, if right+1.
    private void addItem(final int position, Model object){
    if(isLeft(position)){
        items.add(position+2, object);
        notifyItemInserted(position+2);
    }
    else{
        items.add(position+1, object);
        notifyItemInserted(position+1);
    }

}


public class ViewHolder1 extends RecyclerView.ViewHolder {

    TextView mNameTextView;
    ImageView img;
    mealsItemClickListener icl;

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

        mNameTextView = (TextView) itemView.findViewById(R.id.name);
        img = (ImageView) itemView.findViewById(R.id.category_image);
    }

    public TextView getmNameTextView() {
        return mNameTextView;
    }
    public void setmNameTextView(TextView mNameTextView) {
        this.mNameTextView = mNameTextView;
    }
    public ImageView getImg() {
        return img;
    }
    public void setImg(ImageView img) {
        this.img = img;
    }
}


public class ViewHolder2 extends RecyclerView.ViewHolder {

    TextView detailsText;
    mealsItemClickListener icl;

    public ViewHolder2(View v) {
        super(v);
        detailsText = (TextView) itemView.findViewById(R.id.desc);
    }

    public TextView getDetailsText() {
        return detailsText;
    }
    public void setDetailsText(TextView detailsText) {
        this.detailsText = detailsText;
    }
}


}

TL;DR ON MY SITUATION:

Approach1: Gives me

java.lang.ClassCastException: com.example.mrti.menuapp.MULTI.DifferentRowAdapter$ViewHolder2 cannot be cast to com.example.mrti.menuapp.MULTI.DifferentRowAdapter$ViewHolder1
                  at     com.example.mrti.menuapp.MULTI.DifferentRowAdapter.onBindViewHolder(DifferentRowAdapter.java:62)

Approach2: Adding item at certain position works fine, but it adds clicked item, not item2. I'd like to focus more on approach2, but if someone can explain first one - I'm okay with that as well. I'm not sure why it is not working, because it should be - or did I miss smth?

PROBABLY APPROACH1 SOLUTION:

In First approach, with the same position value, the value which getItemViewType(position) returns would not same to the value which items.get(position).getmType() returns.

I have to make values of type same in both getItemViewType and onBindViewHolder method;

How to do it tho?

Community
  • 1
  • 1

0 Answers0