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翻转完成后在恢复点击事件。好了,问题解决了。

 

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

 

 

你可能感兴趣的:(RecycleView使用心得【2】)