zoukankan      html  css  js  c++  java
  • RecycleView使用心得【2】

    项目需要实现RecycleView的item翻转效果并且同时只能翻转一项,下面是我的代码思路:

    //1,点击事件,调用翻转动画
    case R.id.item_adapter:
      applyRotation(position, 0, 90, holder);//右旋90度
    break;
    
        /*
         *2, 应用变换的方法,里面将会使用之前写好的Rotate3d类
        */
        private void applyRotation(int position, float start, float end, ItemViewHolder holder) {
            // Find the center of the container
            //获取FrameLayout的x、y值。这样图片在翻转的时候会以这个x、y值为中心翻转。
            //这就是为什么我要用FrameLayout的原因。如果直接使用的是父容器RelativeLayout将会以RelativeLayout的中心为轴心
            //翻转。由于我的图片不是处于RelativeLayout的中心,翻转时就会有差错.效果可以看看下面的图片。
            //当然,有时候你就想要那样的效果。你也可以在自行调整centerX和centerY的值来达到你想要的效果
            final float centerX = holder.linearLayout.getWidth() / 2.0f;
            final float centerY = holder.linearLayout.getHeight() / 2.0f;
            final Rotate3d rotation =
                    new Rotate3d(start, end, centerX, centerY, 310.0f, true);
            rotation.setDuration(500);  //可设置翻转的时间,以ms为单位
            rotation.setFillAfter(true);
            rotation.setInterpolator(new AccelerateInterpolator());
            rotation.setAnimationListener(new DisplayNextView(holder, position));
            holder.linearLayout.startAnimation(rotation);  //开始翻转前90度
        }
    
     /*
         *3, 这个类用于监听前90度翻转完成
         */
        private final class DisplayNextView implements Animation.AnimationListener {
            private ItemViewHolder holder;
            private int position;
    
            private DisplayNextView(ItemViewHolder holder, int position) {
                this.holder = holder;
                this.position = position;
            }
    
            public void onAnimationStart(Animation animation) {
            }
    
            public void onAnimationEnd(Animation animation) {
                //前90度翻转完成后,根据图片的状态翻转剩下的90度
                if (list.get(position).isClick()) {//此时是点击状态,显示item,隐藏infp
                    initItem(holder, position);
                    holder.houseInfo.setVisibility(View.GONE);
                    holder.itemAdapter.setVisibility(View.VISIBLE);
                    holder.linearLayout.post(new SwapViews(holder, position));
                
                } else {
                    initView(list.get(position), holder);
                    holder.houseInfo.setVisibility(View.VISIBLE);
                    holder.itemAdapter.setVisibility(View.GONE);
                    holder.linearLayout.post(new SwapViews(holder, position));
                }
            }
    
            public void onAnimationRepeat(Animation animation) {
            }
        }
    
    
     /**
         * 4,这个类用于翻转剩下的90度
         */
        private final class SwapViews implements Runnable {
            private ItemViewHolder holder;
            private int position;
    
            public SwapViews(ItemViewHolder holder, int position) {
                this.holder = holder;
                this.position = position;
                System.out.println("===========翻转的positionh==" + position + " ==holder==" + holder);
            }
    
            public void run() {
                final float centerX = holder.linearLayout.getWidth() / 2.0f;
                final float centerY = holder.linearLayout.getHeight() / 2.0f;
                Rotate3d rotation;
                rotation = new Rotate3d(-90, 0, centerX, centerY, 310.0f, false);
                rotation.setDuration(500);
                rotation.setFillAfter(true);
                rotation.setInterpolator(new DecelerateInterpolator());
                holder.linearLayout.startAnimation(rotation);  //开始翻转余下的90度
             
            }
        }

    其中自己定义了3D翻转动画

    public class Rotate3d extends Animation{  
     private final float mFromDegrees;  
        private final float mToDegrees;  
        private final float mCenterX;  
        private final float mCenterY;  
        private final float mDepthZ;  
        private final boolean mReverse;  
        private Camera mCamera;  
        public Rotate3d(float fromDegrees, float toDegrees,  
                float centerX, float centerY, float depthZ, boolean reverse) {  
            mFromDegrees = fromDegrees;  
            mToDegrees = toDegrees;  
            mCenterX = centerX;  
            mCenterY = centerY;  
            mDepthZ = depthZ;  
            mReverse = reverse;  
        }  
        @Override  
        public void initialize(int width, int height, int parentWidth, int parentHeight) {  
            super.initialize(width, height, parentWidth, parentHeight);  
            mCamera = new Camera();  
        }  
        @Override  
        protected void applyTransformation(float interpolatedTime, Transformation t) {  
            final float fromDegrees = mFromDegrees;  
            float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);  
            final float centerX = mCenterX;  
            final float centerY = mCenterY;  
            final Camera camera = mCamera;  
            final Matrix matrix = t.getMatrix();  
            camera.save();  
            if (mReverse) {  
                camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);  
            } else {  
                camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));  
            }  
            camera.rotateY(degrees);  
            camera.getMatrix(matrix);  
            camera.restore();  
     
            matrix.preTranslate(-centerX, -centerY);  
            matrix.postTranslate(centerX, centerY);  
        }  
    } 

    一开始思路是保存上一个点击的position和holder,后来发现position是正确的,但是hoder因为复用的原因,保存下来的有错位的问题。然后发现了下面的方法:但是有时因为复用的原因holder只能得到显示出来的,其他的得不到,

     for (int i = 0; i < recyclerView.getChildCount(); i++) {
                            RecyclerView.ViewHolder childViewHolder = recyclerView.getChildViewHolder(recyclerView.getChildAt(i));
                            ItemViewHolder itemViewHolder = (ItemViewHolder) childViewHolder;
                            int layoutPosition = itemViewHolder.getLayoutPosition();
                      
                            if (layoutPosition != position && itemViewHolder.houseInfo.getVisibility() == View.VISIBLE && itemViewHolder.itemAdapter.getVisibility() == View.GONE) {
              
                                applyRotation(layoutPosition, 0, 90, itemViewHolder);//右旋90度
                            }
                        }

    所以就需要在OnBindViewHolder中添加判断,根据mposition(此时点击翻转的项)来判断,用来显示个隐藏布局。(但是发现一个问题及时好像滑动很慢的时候这个OnBindViewHolder方法是不走的,希望有人解释一下)。

    写到现在,动画可以翻转了,并且实现了如果itemA已经翻转过了再去翻转itemB,那么itemA会自动翻转回去。但是问题又来了,那就是如果快速的同事点击itemA和itemB就会同时翻转,想了个办法就是当点下翻转一项的时候,禁止其他项的点击事件,等到itemA翻转完成后在恢复点击事件。好了,问题解决了。

    结束语:刚开始写,写的不好,勿喷哦。

     

  • 相关阅读:
    dayjs:js时间插件
    IE:IE请求路径带中文报错
    layui:下载表格为excel文件
    VUE:导出表格为excel文件
    报错:unexpected trailing comma
    node.js报错address not available 192.168.1.4
    js防抖和节流
    mongodb的常用基础命令及操作
    mongodb下载安装及环境搭建
    vue页面缓存
  • 原文地址:https://www.cnblogs.com/blogljj/p/4816469.html
Copyright © 2011-2022 走看看