CardView not expanding on 2nd click

MacaronLover :

After implementing a custom animation for these CardViews, the first two are not behaving in the way they are supposed to. Item A and Item B won't expand upon the 2nd click, but yet Item C works perfectly fine.

enter image description here

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

    private static final int TYPE_HEADER = 0;
    private static final int TYPE_ITEM = 1;

    private Context mContext;

    RecyclerViewHeader header;
    List<MyRecyclerViewItem> listItems;
    ValueAnimator mAnimator;



    public MyRecyclerAdapter(Context context, RecyclerViewHeader header, List<MyRecyclerViewItem> listItems)
    {
        this.mContext = context;
        this.header = header;
        this.listItems = listItems;    
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if(viewType == TYPE_HEADER)
        {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_header, parent, false);
            return new MyRecyclerAdapter.VHHeader(v);
        }
        else if(viewType == TYPE_ITEM)
        {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item, parent, false);
            return new MyRecyclerAdapter.VHItem(v);
        }
        throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
    }

    private MyRecyclerViewItem getItem(int position)
    {
        return listItems.get(position);
    }


    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        final Typeface iconFont = FontManager.getTypeface(mContext, FontManager.FONTAWESOME);


        if (holder instanceof VHHeader)
        {
            final VHHeader vhHeader = (VHHeader)holder;                
        }
        else if (holder instanceof VHItem)
        {
            MyRecyclerViewItem currentItem = getItem(position-1);
            final VHItem vhItem = (VHItem)holder;

            vhItem.txtA.setText(currentItem.getContinent());
            vhItem.txtB.setText(currentItem.getCountry());

            vhItem.txtB.setVisibility(View.GONE);


            vhItem.txtExpandCollapse.setText(R.string.fa_icon_chevron_down);
            vhItem.txtExpandCollapse.setTypeface(iconFont);

            //Add onPreDrawListener
            vhItem.txtB.getViewTreeObserver().addOnPreDrawListener(
            new ViewTreeObserver.OnPreDrawListener() {

                @Override
                public boolean onPreDraw() {
                    vhItem.txtB.getViewTreeObserver().removeOnPreDrawListener(this);
                    vhItem.txtB.setVisibility(View.GONE);

                    final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
                    final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
                    vhItem.txtB.measure(widthSpec, heightSpec);

                    mAnimator = vhItem.slideAnimator(0, vhItem.txtB.getMeasuredHeight());
                    return true;
                }
            });

            vhItem.cardView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(vhItem.txtB.getVisibility() == View.GONE){
                        vhItem.expand();
                    } else {
                        vhItem.collapse();
                    }
                }
            });
        }
    }

    @Override
    public int getItemViewType(int position) {
        if(isPositionHeader(position))
            return TYPE_HEADER;
            return TYPE_ITEM;
    }

    private boolean isPositionHeader(int position)
    {
        return position == 0;
    }

    // increasing getItemcount to 1. This will be the row of header.
    @Override
    public int getItemCount() {
        return listItems.size()+1;
    }

    class VHHeader extends RecyclerView.ViewHolder{
        Button btnCollapseAll, btnExpandAll;

        public VHHeader(View headerView) {
            super(headerView);

            this.btnCollapseAll = headerView.findViewById(R.id.btn_collapseall);
            this.btnExpandAll = headerView.findViewById(R.id.btn_expandall);
        }
    }

    public class VHItem extends RecyclerView.ViewHolder{
        CardView cardView;
        RelativeLayout mRelativeLayout;
        TextView txtExpandCollapse, txtA, txtB;

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

            this.cardView = itemView.findViewById(R.id.cv);
            this.mRelativeLayout = itemView.findViewById(R.id.tv_rv_relativelayout);
            this.txtExpandCollapse = itemView.findViewById(R.id.tv_rv_expandcollapse);
            this.txtA = itemView.findViewById(R.id.tv_rv_A);
            this.txtB = itemView.findViewById(R.id.tv_rv_B);
        }

        private void expand() {
            // set Visible
            txtB.setVisibility(View.VISIBLE);

            // change direction of chevron to 'up'
            txtExpandCollapse.setText(R.string.fa_icon_chevron_up);

            mAnimator.start();
        }

        private void collapse() {
            // change direction of chevron to 'down'
            txtExpandCollapse.setText(R.string.fa_icon_chevron_down);

            int finalHeight = txtB.getHeight();

            ValueAnimator mAnimator = slideAnimator(finalHeight, 0);

            mAnimator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationEnd(Animator animator) {
                    //Height=0, but it set visibility to GONE
                    txtB.setVisibility(View.GONE);
                }

                @Override
                public void onAnimationStart(Animator animator) {
                }

                @Override
                public void onAnimationCancel(Animator animator) {
                }

                @Override
                public void onAnimationRepeat(Animator animator) {
                }
            });
            mAnimator.start();
        }


        public ValueAnimator slideAnimator(int start, int end) {

            ValueAnimator animator = ValueAnimator.ofInt(start, end);


            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    //Update Height
                    int value = (Integer) valueAnimator.getAnimatedValue();

                    ViewGroup.LayoutParams layoutParams = txtB.getLayoutParams();
                    layoutParams.height = value;
                    txtB.setLayoutParams(layoutParams);
                }
            });
            return animator;
        }
    }
}
Krishna Sharma :

You need to re-initialize mAnimator object.

Try below,

Defind one more member variable in VHItem class to keep the textB height

public class VHItem extends RecyclerView.ViewHolder{
    CardView cardView;
    RelativeLayout mRelativeLayout;
    TextView txtExpandCollapse, txtA, txtB;
    int textBHeight; // new variable
}

Then initialize it from onPreDraw method

public boolean onPreDraw() {
    vhItem.txtB.getViewTreeObserver().removeOnPreDrawListener(this);
    vhItem.txtB.setVisibility(View.GONE);

    final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    vhItem.txtB.measure(widthSpec, heightSpec);

    vhItem.textBHeight = vhItem.txtB.getMeasuredHeight();
    return true;
}

Then initialize the animator before starting

private void expand() {
    txtB.setVisibility(View.VISIBLE);
    txtExpandCollapse.setText(R.string.fa_icon_chevron_up);
    mAnimator = slideAnimator(0,textBHeight); 
    mAnimator.start();
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=81297&siteId=1
Recommended