2

After implementing a CardView and trying to apply an animation to the arrow text view, the animation is showing unusual behaviour when the arrow is clicked. What can be done to fix the animation and get the result similar to the Expected animation image?

Expected animation

enter image description here

Current animation

enter image description here

recyclerview_item

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:animateLayoutChanges="true"
    android:clickable="true"
    android:focusable="true"
    android:foreground="?android:attr/selectableItemBackground"
    android:id="@+id/cv"
    android:layout_marginBottom="20dp"
    >

    <LinearLayout
        android:id="@+id/cardview_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="10dp"
        android:animateLayoutChanges="true">

        <LinearLayout
            android:id="@+id/cardview_titlerow"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginBottom="2dp"
            android:weightSum="100">

            <TextView
                android:id="@+id/tv_A"
                android:layout_weight="90"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                style="@android:style/TextAppearance.Medium" />

            <TextView
                android:id="@+id/tv_expandcollapsearrow"
                android:clickable="true"
                android:focusable="true"
                android:layout_weight="10"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:textColor="@android:color/white"
                style="@android:style/TextAppearance.Medium" />
        </LinearLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >

            <TextView
                android:id="@+id/tv_B"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                style="@android:style/TextAppearance.Large"
                />

        </RelativeLayout>

    </LinearLayout>
</android.support.v7.widget.CardView>

MyRecyclerAdapter.java

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<MyRecyclerItem> listItems;


    private Animation animationCollapse;
    private Animation animationExpand;

    public MyRecyclerAdapter(Context context, RecyclerViewHeader header, List<MyRecyclerItem> 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_expandcollapsebuttons, 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 MyRecyclerItem 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)
        {
            VHHeader VHheader = (VHHeader)holder;
        }
        else if (holder instanceof VHItem)
        {
            RecyclerViewListItemTransportConnections currentItem = getItem(position-1);
            final VHItem VHitem = (VHItem)holder;

            VHitem.txtA.setText(currentItem.getConnectionMode());
            VHitem.txtB.setText(currentItem.getConnectionName());

            VHitem.txtB.setVisibility(View.GONE);


            VHitem.txtExpandCollapseArrow.setText(R.string.fa_icon_chevron_down);
            VHitem.txtExpandCollapseArrow.setTypeface(iconFont);

            VHitem.txtExpandCollapseArrow.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (VHitem.txtB.getVisibility() == View.VISIBLE) {
                        VHitem.txtB.setVisibility(View.GONE);

                        RotateAnimation rotate = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                        rotate.setDuration(300);
                        rotate.setInterpolator(new LinearInterpolator());

                        VHitem.txtExpandCollapseArrow.startAnimation(rotate);

                        VHitem.txtExpandCollapseArrow.setText(R.string.fa_icon_chevron_down);
                    } else {
                        VHitem.txtB.setVisibility(View.VISIBLE);

                        RotateAnimation rotate = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                        rotate.setDuration(300);
                        rotate.setInterpolator(new LinearInterpolator());

                        VHitem.txtExpandCollapseArrow.startAnimation(rotate);


TransitionManager.beginDelayedTransition(VHitem.cardview);

VHitem.txtExpandCollapseArrow.setText(R.string.fa_icon_chevron_up);
                    }
                }
            });
        }
    }

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

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

    @Override
    public int getItemCount() {
        return listItems.size()+1;
    }

    class VHHeader extends RecyclerView.ViewHolder{
        public VHHeader(View itemView) {
            super(itemView);
        }
    }

    class VHItem extends RecyclerView.ViewHolder{
        CardView cardview;
        TextView txtExpandCollapseArrow, txtA, txtB;

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

            this.cardview = itemView.findViewById(R.id.cv);

            this.txtExpandCollapseArrow = itemView.findViewById(R.id.tv_expandcollapsearrow);

            this.txtA = itemView.findViewById(R.id.tv_A);
            this.txtB = itemView.findViewById(R.id.tv_B);
        }
    }
}

Sourabh's suggestion

enter image description here

wbk727
  • 8,017
  • 12
  • 61
  • 125

2 Answers2

1

A much easier approach would be to set the visibility of hideable views and use TransitionManager to animate those layout changes.

TransitionManager.beginDelayedTransition(rootView) 
// rootView can be the container view of all cards

This will take care of increasing card height and fading those views in. I am not sure if it'll handle rotating the arrow too, but you can try. or you can use RotateAnimation for it

Sourabh
  • 8,243
  • 10
  • 52
  • 98
  • Your suggestion helped a bit so many thanks, although there's a problem. The animation works perfectly when the CardView expands, but not when it collapses. Checkout the 'Sourabh's suggestion' screenshot. Do you know why this happens? – wbk727 Aug 20 '18 at 19:28
  • Didn't dive into it too much but try [this answer](https://stackoverflow.com/questions/41464629/expand-collapse-animation-in-cardview) – Sourabh Aug 21 '18 at 20:12
-2

The expected animation appears to be an vector drawable animation while the method that you have followed animates the view not the drawable .

You need to use Animated Vector drawable to achieve the desired result.

  • It is not a vector drawable, it is a `TextView` containing a vector (FontAwesome) – wbk727 Aug 20 '18 at 18:44
  • Yes thats wat I siad , you are animating a texview presently but , one way in which the effect can be achieved is with animated vector drawable which animate on vector drawables ( rather than the entire viewport ) , if you could change to vector icon. – Aanchal Garg Aug 20 '18 at 18:56
  • using an imageview and setting the animated vector drawable as its background using srcCompact , should surely solve the problem of arrow animation atleast. – Aanchal Garg Aug 20 '18 at 19:05