2

I have a RecyclerView ViewHolder for a RelativeLayout. In my OnBindViewHolder method, I'm updating the height of the entire layout and a contained ImageView, based on a condition. This works fine, however, this new layout is being recycled for subsequent views that don't meet the condition. Thus, producing inconsistent results.

// Involves populating data into the item through holder
@Override
public void onBindViewHolder(RallyAdapter.ViewHolder viewHolder, final int position) {

    //Expand viewholder and thumbnail if rally name takes up multiple lines
    if(rally.getName().length() > 23) {

        RelativeLayout.LayoutParams relParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

        //Original height is 114
        relParams.height = 139

        //where 'relativeLayout' is referencing the base layout
        viewHolder.relativeLayout.setLayoutParams(relParams);

        RelativeLayout.LayoutParams imgParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        //Original height is 117
        imgParams.height = 143

        viewHolder.thumbnail.setLayoutParams(imgParams);
    } else {

        //Need code here to reset layout and thumbnail to original heights 
    }
}

I know I have to have an else to my condition because I'm in the onBindViewHolder function but I just don't know what it's supposed to be.

Faybian
  • 373
  • 2
  • 7
  • 15

1 Answers1

3

If I was to write this. I would probably have two different xml files with two different heights. I can then use getItemViewType() in the adapter to tell which position is of which type. In this way recycler view recycles the correct view for each position that you are in.(You do not need to reset the size of each row)

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

    private final static int TYPE_1=1;
    private final static int TYPE_2=2;
    @Override
    public int getItemViewType(int position) {
        if(rally.getName().length() > 23) {
            return TYPE_1;
        }
        return TYPE_2;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
        View view = LayoutInflater.from(mContext).inflate(/** your layout **/)
        if (i == TYPE_1) {
           RelativeLayout.LayoutParams relParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, 139);
           RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, 143);
           viewHolder.relativeLayout.setLayoutParams(relParams);
           viewHolder.thumbnail.setLayoutParams(imgParams);
           return new RecyclerView.ViewHolder(/**View_height_139**/);
        }
           return new RecyclerView.ViewHolder(/**View_height_114**/);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
        if (viewHolder.getItemViewType() == TYPE_1) {
            // Do the binding for when rally.getName().length > 23
        } else {
            // Do the bindings for the rest
        }
    }

    @Override
    public int getItemCount() {
        return 10.;
    }
}
hoomi
  • 1,882
  • 2
  • 16
  • 17
  • It is not an overkill. This actually performs much better than you try to set the height of each row dynamically in `onBindView` – hoomi Sep 21 '15 at 20:50
  • This solution would mean that I would have to maintain 2 different layout files of the same layout with the only differences being height values. I follow the logic here and the solution seems plausible but I just think there must be a simpler solution. Is there a way that I can just inflate the original layout somehow and then just set the viewholder to use that layout? Also, I'm not notifying that a change has been made, would that have any affect? – Faybian Sep 21 '15 at 21:09
  • Though I HATE the notion of having to maintain separate XML files for such a simple change, this is a working solution and I begrudgingly will accept this answer. However, if anyone has another suggestion, please do tell. – Faybian Sep 22 '15 at 00:35
  • If you want to stilll use the same xml layout, set the height to be 139 in `onCreateViewHolder` for `TYPE_1` – hoomi Sep 22 '15 at 05:08
  • Though we started off a bit rough, you sure turned it around with this update... What an EXCELLENT solution, works perfectly, thanks. – Faybian Sep 22 '15 at 14:26