amitairos amitairos - 4 months ago 29
Java Question

Android Expandable RecyclerView different Card height

I have a RecyclerView that contains a list of cards, each of which expand into child cards.

Each card has different text. I want that when the user clicks on a child card, it will expand to show the text inside. The expansion height is based on how much text the card contains.

I tried to measure the target height by using:

view.Measure(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent);


And then expanding the card to the Measured Height (see here).
However, it gives the same Measured Height to all of the cards.

Here is my code, which is based on this (more specifically the Xamarin version):

This is the main Adapter, which creates and binds the parent and the child cards:

public class HalachaExpandableAdapter : ExpandableRecyclerAdapter<HalachaParentViewHolder, HalachaChildViewHolder>, View.IOnClickListener
{
LayoutInflater _inflater;
bool expand;
int targetHeight;
bool wave = false;

public HalachaExpandableAdapter(Context context, List<IParentObject> itemList) : base(context, itemList)
{
_inflater = LayoutInflater.From(context);
}

public override void OnBindChildViewHolder(HalachaChildViewHolder childViewHolder, int position, object childObject)
{
var halachaChild = (HalachaChild)childObject;
childViewHolder.halachaChildTitle.Text = halachaChild.Title.ToString();

targetHeight = childViewHolder.halachaChildCard.Height;
childViewHolder.halachaChildCard.LayoutParameters.Height = 100;
childViewHolder.halachaChildCard.SetOnClickListener(this);
expand = childViewHolder.expand;

}

public override void OnBindParentViewHolder(HalachaParentViewHolder parentViewHolder, int position, object parentObject)
{
var halacha = (HalachaItem)parentObject;
parentViewHolder._halachaTitleTextView.Text = halacha.Title();
parentViewHolder._halachaContentTextView.Text = halacha.Content;
if (halacha.ChildObjectList.Count == 1)
wave = true;
}

public void OnClick(View v)
{
if (v.Height == 100)
{
AnimationCollapse anim = new AnimationCollapse(v, targetHeight, 100);
anim.Duration = 300;
v.StartAnimation(anim);

expand = false;
}
else
{
AnimationCollapse anim = new AnimationCollapse(v, 100, v.Height);
anim.Duration = 300;
v.StartAnimation(anim);

expand = true;
}
}

public override HalachaChildViewHolder OnCreateChildViewHolder(ViewGroup childViewGroup)
{
var view = _inflater.Inflate(Resource.Layout.halachotListItem, childViewGroup, false);
return new HalachaChildViewHolder(view);
}

public override HalachaParentViewHolder OnCreateParentViewHolder(ViewGroup parentViewGroup)
{
var view = _inflater.Inflate(Resource.Layout.halachotListHeader, parentViewGroup, false);
wave = false;
return new HalachaParentViewHolder(view);
}
}


I think this is where the code is needed to be done, but if you need some of the other code of the other classes, I will gladly post them. You can also look at the links above for reference to how this works.

Hope someone can help me.

Thanks!

Answer

I finally managed to solve the problem.
I needed to change the way I measured the view's wrap_content height to this:

v.Measure(MeasureSpec.MakeMeasureSpec(v.Width, MeasureSpecMode.Exactly), MeasureSpec.MakeMeasureSpec(ViewGroup.LayoutParams.WrapContent, MeasureSpecMode.AtMost));

The rest is the same.
Thanks to this post.