标签:
项目需要实现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因为复用的原因,保存下来的有错位的问题。然后发现了下面的方法:但是有时因为复用的原因hoder只能得到显示出来的,其他的得不到,
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翻转完成后在恢复点击事件。好了,问题解决了。
结束语:刚开始写,写的不好,勿喷哦。
标签:
原文地址:http://www.cnblogs.com/blogljj/p/4816469.html