CardView 中的展开/折叠动画 [英] Expand/collapse animation in CardView

查看:42
本文介绍了CardView 中的展开/折叠动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试做这样的事情:

我设法做我的 cardViewAdapter 但我阻止放大我的卡片.我恢复了这个展开后:

我解决了上面的问题,但如果在我的 cardView 上,我同时显示 10 个元素以显示 50 个列表.如果我展开第一个,数字 11,21,31,41 也会展开.你有什么技巧可以避免这种情况发生吗?

我已经反映过了,这对我来说毫无意义.就在我的 OnClick 方法之前,我显示了一个文本视图,其中文本是位置.但是当我点击 id 是正确的,这意味着当我点击它时会检测到几张卡片的点击.我想我的 OnClickListener 中的视图可能有问题

我的 CardView

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"机器人:layout_margin="5dp"app:cardBackgroundColor="@android:color/white"应用程序:cardCornerRadius="2dp"app:cardElevation="2dp"><!-- Les CardView possèdent des attributs supplementaires dont- 卡片背景颜色- cardElevation pour l'élévation (donc aussi l'ombre)- cardCornerRadius 倒角--><android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><!-- Les CardView agissent comme des FrameLayout,倾倒联合国垂直组织donc rajouter un LinearLayout --><文本视图android:id="@+id/text_cards"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="?android:selectableItemBackground"机器人:填充=20dp"工具:文本=巴黎"android:fontFamily="sans-serif"android:textColor="#333"android:textSize="18sp"/><图像视图android:id="@+id/item_description_game_more"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical|end"android:transitionName="@string/transition_cards_view"app:srcCompat="@drawable/ic_expand_more_black_24dp"/><include layout="@layout/cards_resume_game_expand"/></android.support.design.widget.CoordinatorLayout></android.support.v7.widget.CardView></LinearLayout>

我的新适配器

public class CardsViewAdapter extends RecyclerView.Adapter{私人游戏[] mDataset;私人布尔 isPopupVisible = false;int 旋转角度 = 0;//提供对每个数据项的视图的引用//复杂的数据项每个项可能需要多个视图,并且//您提供对视图持有者中数据项的所有视图的访问公共静态类 ViewHolder 扩展 RecyclerView.ViewHolder {//在这种情况下,每个数据项只是一个字符串公共 TextView mTextView;公共 ImageView imageView;公共 LinearLayout test2;公共 ViewHolder(View v) {超级(五);mTextView = (TextView) v.findViewById(R.id.text_cards);imageView = (ImageView) v.findViewById(R.id.item_description_game_more);test2 = (LinearLayout) v.findViewById(R.id.popup_layout);}}//提供一个合适的构造函数(取决于数据集的种类)公共 CardsViewAdapter(Game[] myDataset) {mDataset = myDataset;}//创建新视图(由布局管理器调用)@覆盖public CardsViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {//创建一个新视图视图 v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cards_resume_game, parent, false);//设置视图的大小、边距、填充和布局参数//...ViewHolder vh = 新的 ViewHolder(v);返回 vh;}//替换视图的内容(由布局管理器调用)@覆盖公共无效 onBindViewHolder(最终 ViewHolder 持有人,int 位置){//- 在这个位置从你的数据集中获取元素//- 用该元素替换视图的内容holder.mTextView.setText(String.valueOf(mDataset[position].getId_game()));holder.imageView.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {//执行点击动作如果(isPopupVisible){isPopupVisible = false;ObjectAnimator anim = ObjectAnimator.ofFloat(v, "rotation",rotationAngle, rotationAngle + 180);动画.setDuration(500);动画开始();旋转角度 += 180;旋转角度 = 旋转角度%360;//CardsAnimationHelper.changeIconAnim((TextView) v, getString(R.string.icon_chevron_up));CardsAnimationHelper.collapse(holder.test2);} 别的 {isPopupVisible = true;ObjectAnimator anim = ObjectAnimator.ofFloat(v, "rotation",rotationAngle, rotationAngle + 180);动画.setDuration(500);动画开始();旋转角度 += 180;旋转角度 = 旋转角度%360;//CardsAnimationHelper.changeIconAnim((TextView) v, getString(R.string.icon_chevron_down));CardsAnimationHelper.expand(holder.test2);}}});}//返回数据集的大小(由布局管理器调用)@覆盖公共 int getItemCount() {返回 mDataset.length;}}

解决方案

您需要创建一个自定义类来扩展 CardView.在该类中放置以下方法:

public void expand() {int initialHeight = getHeight();措施(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);int targetHeight = getMeasuredHeight();int distanceToExpand = targetHeight - initialHeight;动画 a = 新动画(){@覆盖protected void applyTransformation(float interpolatedTime, Transformation t) {如果(插值时间== 1){//展开后执行此操作}getLayoutParams().height = (int) (initialHeight + (distanceToExpand * interpolatedTime));请求布局();}@覆盖公共布尔 willChangeBounds() {返回真;}};a.setDuration((long) distanceToExpand);开始动画(一);}公共无效折叠(intcollapsedHeight){int initialHeight = getMeasuredHeight();int distanceToCollapse = (int) (initialHeight - collapsedHeight);动画 a = 新动画(){@覆盖protected void applyTransformation(float interpolatedTime, Transformation t) {如果(插值时间== 1){//折叠后执行此操作}Log.i(TAG, "Collapse | InterpolatedTime = " + interpolatedTime);getLayoutParams().height = (int) (initialHeight - (distanceToCollapse * interpolatedTime));请求布局();}@覆盖公共布尔 willChangeBounds() {返回真;}};a.setDuration((long) distanceToCollapse);开始动画(一);}

请注意,当您折叠它时,您需要传递您希望它在折叠时的高度.展开时的高度设置为 WRAP_CONTENT.

我还添加了将在动画完成时运行的 if/else 语句.

祝你好运!

I try to do something like this :

I managed to do my cardViewAdapter but I block to enlarge my cards. I resumed the code of this response (Here the name of the class is : CardsAnimationHelper) to do the animation but it's superimposed.

Before expand: After expand:

I solved the problem above but if on my cardView I display 10 elements at the same time for a list of 50. If I expand the first, the numbers 11,21,31,41 will also expand. Do you have a trick for this not to happen?

I have reflected, it makes no sense to me. Just before my OnClick method I display a textview where the text is the position. But when I click id are correct so that would mean that when I click it detects the click on several cards. I think I may have a problem with a view in my OnClickListener

My CardView

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"

        app:cardBackgroundColor="@android:color/white"
        app:cardCornerRadius="2dp"
        app:cardElevation="2dp">

        <!-- Les CardView possèdent des attributs supplémentaires dont
             - cardBackgroundColor
             - cardElevation pour l'élévation (donc aussi l'ombre)
             - cardCornerRadius pour arrondir les angles
         -->

        <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <!-- Les CardView agissent comme des FrameLayout,
             pour avoir une organisation verticale nous devons
             donc rajouter un LinearLayout -->


            <TextView
                android:id="@+id/text_cards"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?android:selectableItemBackground"
                android:padding="20dp"
                tools:text="Paris"
                android:fontFamily="sans-serif"
                android:textColor="#333"
                android:textSize="18sp" />

            <ImageView
                android:id="@+id/item_description_game_more"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical|end"
                android:transitionName="@string/transition_cards_view"
                app:srcCompat="@drawable/ic_expand_more_black_24dp"/>

            <include layout="@layout/cards_resume_game_expand"/>

        </android.support.design.widget.CoordinatorLayout>

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

</LinearLayout>

My New Adapter

public class CardsViewAdapter extends RecyclerView.Adapter<CardsViewAdapter.ViewHolder> {
    private Game[] mDataset;
    private boolean isPopupVisible = false;
    int rotationAngle = 0;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView mTextView;
        public ImageView imageView;
        public LinearLayout test2;

        public ViewHolder(View v) {
            super(v);
            mTextView = (TextView) v.findViewById(R.id.text_cards);
            imageView = (ImageView) v.findViewById(R.id.item_description_game_more);
            test2 = (LinearLayout) v.findViewById(R.id.popup_layout);

        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public CardsViewAdapter(Game[] myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public CardsViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.cards_resume_game, parent, false);
        // set the view's size, margins, paddings and layout parameters
        //...

        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element

        holder.mTextView.setText(String.valueOf(mDataset[position].getId_game()));
        holder.imageView.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click
                if (isPopupVisible) {
                    isPopupVisible = false;

                    ObjectAnimator anim = ObjectAnimator.ofFloat(v, "rotation",rotationAngle, rotationAngle + 180);
                    anim.setDuration(500);
                    anim.start();
                    rotationAngle += 180;
                    rotationAngle = rotationAngle%360;

//                    CardsAnimationHelper.changeIconAnim((TextView) v, getString(R.string.icon_chevron_up));
                    CardsAnimationHelper.collapse(holder.test2);
                } else {
                    isPopupVisible = true;

                    ObjectAnimator anim = ObjectAnimator.ofFloat(v, "rotation",rotationAngle, rotationAngle + 180);
                    anim.setDuration(500);
                    anim.start();
                    rotationAngle += 180;
                    rotationAngle = rotationAngle%360;

//                    CardsAnimationHelper.changeIconAnim((TextView) v, getString(R.string.icon_chevron_down));
                    CardsAnimationHelper.expand(holder.test2);
                }
            }
        });



    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.length;
    }
}

解决方案

You'll need to create a custom class that extends CardView. Inside that class put the following methods:

public void expand() {
    int initialHeight = getHeight();

    measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    int targetHeight = getMeasuredHeight();

    int distanceToExpand = targetHeight - initialHeight;

    Animation a = new Animation() {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            if (interpolatedTime == 1){
                // Do this after expanded
            }

            getLayoutParams().height = (int) (initialHeight + (distanceToExpand * interpolatedTime));
            requestLayout();
        }

        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };

    a.setDuration((long) distanceToExpand);
    startAnimation(a);
}

public void collapse(int collapsedHeight) {
    int initialHeight = getMeasuredHeight();

    int distanceToCollapse = (int) (initialHeight - collapsedHeight);

    Animation a = new Animation() {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            if (interpolatedTime == 1){
                // Do this after collapsed
            }


            Log.i(TAG, "Collapse | InterpolatedTime = " + interpolatedTime);

            getLayoutParams().height = (int) (initialHeight - (distanceToCollapse * interpolatedTime));
            requestLayout();
        }

        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };

    a.setDuration((long) distanceToCollapse);
    startAnimation(a);
}

Note that when you collapse it, you'll need to pass along the height you want it to be when collapsed. The height when expanded is set to WRAP_CONTENT.

I've also added if/else statements that will run when the animation has completed.

Good luck!

这篇关于CardView 中的展开/折叠动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆