package me.weyye.todaynews.ui.adapter; import android.graphics.Bitmap; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.widget.FrameLayout; import android.widget.ImageView; import com.chad.library.adapter.base.BaseMultiItemQuickAdapter; import com.chad.library.adapter.base.BaseViewHolder; import java.util.List; import me.weyye.todaynews.R; import me.weyye.todaynews.listener.OnChannelDragListener; import me.weyye.todaynews.model.Channel; /** * Created by Administrator on 2017/1/5 0005. */ public class ChannelAdapter extends BaseMultiItemQuickAdapter<Channel> { private BaseViewHolder mEditViewHolder; private boolean mIsEdit; private long startTime; // touch 间隔时间 用于分辨是否是 "点击" private static final long SPACE_TIME = 100; private RecyclerView mRecyclerView; public ChannelAdapter(List<Channel> data) { super(data); //默认没有编辑 mIsEdit = false; addItemType(Channel.TYPE_MY, R.layout.item_channel_title); addItemType(Channel.TYPE_MY_CHANNEL, R.layout.item_channel); addItemType(Channel.TYPE_OTHER, R.layout.item_channel_title); addItemType(Channel.TYPE_OTHER_CHANNEL, R.layout.item_channel); } @Override public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { mRecyclerView = (RecyclerView) parent; return super.onCreateViewHolder(parent, viewType); } private OnChannelDragListener onChannelDragListener; public void setOnChannelDragListener(OnChannelDragListener onChannelDragListener) { this.onChannelDragListener = onChannelDragListener; } @Override protected void convert(final BaseViewHolder baseViewHolder, final Channel channel) { switch (baseViewHolder.getItemViewType()) { case Channel.TYPE_MY: //我的频道 //赋值,以便之后修改文字 mEditViewHolder = baseViewHolder; baseViewHolder.setText(R.id.tvTitle, channel.Title) .setOnClickListener(R.id.tvEdit, new View.OnClickListener() { @Override public void onClick(View v) { if (!mIsEdit) { startEditMode(true); baseViewHolder.setText(R.id.tvEdit, "完成"); } else { startEditMode(false); baseViewHolder.setText(R.id.tvEdit, "编辑"); } } }); break; case Channel.TYPE_OTHER: //频道推荐 baseViewHolder.setText(R.id.tvTitle, channel.Title) .setVisible(R.id.tvEdit, false); break; case Channel.TYPE_MY_CHANNEL: //我的频道列表 baseViewHolder .setVisible(R.id.ivDelete, mIsEdit)//编辑模式就显示删除按钮 .setOnLongClickListener(R.id.rlItemView, new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if (!mIsEdit) { //开启编辑模式 startEditMode(true); mEditViewHolder.setText(R.id.tvEdit, "完成"); } if (onChannelDragListener != null) onChannelDragListener.onStarDrag(baseViewHolder); return true; } }).setOnTouchListener(R.id.tvChannel, new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (!mIsEdit) return false;//正常模式无需监听触摸 switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startTime = System.currentTimeMillis(); break; case MotionEvent.ACTION_MOVE: if (System.currentTimeMillis() - startTime > SPACE_TIME) { //当MOVE事件与DOWN事件的触发的间隔时间大于100ms时,则认为是拖拽starDrag if (onChannelDragListener != null) onChannelDragListener.onStarDrag(baseViewHolder); } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: startTime = 0; break; } return false; } }).getView(R.id.ivDelete).setTag(true);//在我的频道里面设置true标示,之后会根据这个标示来判断编辑模式是否显示 baseViewHolder.setText(R.id.tvChannel, channel.Title).setOnClickListener(R.id.ivDelete, new View.OnClickListener() { @Override public void onClick(View v) { //执行删除,移动到推荐频道列表 if (mIsEdit) { int otherFirstPosition = getOtherFirstPosition(); int currentPosition = getViewHolderPosition(baseViewHolder); //获取到目标View View targetView = mRecyclerView.getLayoutManager().findViewByPosition(otherFirstPosition); //获取当前需要移动的View View currentView = mRecyclerView.getLayoutManager().findViewByPosition(currentPosition); // 如果targetView不在屏幕内,则indexOfChild为-1 此时不需要添加动画,因为此时notifyItemMoved自带一个向目标移动的动画 // 如果在屏幕内,则添加一个位移动画 if (mRecyclerView.indexOfChild(targetView) >= 0 && otherFirstPosition != -1) { RecyclerView.LayoutManager manager = mRecyclerView.getLayoutManager(); int spanCount = ((GridLayoutManager) manager).getSpanCount(); int targetX = targetView.getLeft(); int targetY = targetView.getTop(); int myChannelSize = getMyChannelSize();//这里我是为了偷懒 ,算出来我的频道的大小 if (myChannelSize % spanCount == 1) { //我的频道最后一行 之后一个,移动后 targetY -= targetView.getHeight(); } //我的频道 移动到 推荐频道的第一个 channel.setItemType(Channel.TYPE_OTHER_CHANNEL);//改为推荐频道类型 if (onChannelDragListener != null) onChannelDragListener.onMoveToOtherChannel(currentPosition, otherFirstPosition - 1); startAnimation(currentView, targetX, targetY); } else { channel.setItemType(Channel.TYPE_OTHER_CHANNEL);//改为推荐频道类型 if (otherFirstPosition == -1) otherFirstPosition = mData.size(); if (onChannelDragListener != null) onChannelDragListener.onMoveToOtherChannel(currentPosition, otherFirstPosition - 1); } // GlobalParams.mRemovedChannels.add(channel); } } }); break; case Channel.TYPE_OTHER_CHANNEL: //频道推荐列表 baseViewHolder.setText(R.id.tvChannel, channel.Title).setVisible(R.id.ivDelete, false) .setOnClickListener(R.id.tvChannel, new View.OnClickListener() { @Override public void onClick(View v) { int myLastPosition = getMyLastPosition(); int currentPosition = getViewHolderPosition(baseViewHolder); //获取到目标View View targetView = mRecyclerView.getLayoutManager().findViewByPosition(myLastPosition); //获取当前需要移动的View View currentView = mRecyclerView.getLayoutManager().findViewByPosition(currentPosition); // 如果targetView不在屏幕内,则indexOfChild为-1 此时不需要添加动画,因为此时notifyItemMoved自带一个向目标移动的动画 // 如果在屏幕内,则添加一个位移动画 if (mRecyclerView.indexOfChild(targetView) >= 0 && myLastPosition != -1) { RecyclerView.LayoutManager manager = mRecyclerView.getLayoutManager(); int spanCount = ((GridLayoutManager) manager).getSpanCount(); int targetX = targetView.getLeft() + targetView.getWidth(); int targetY = targetView.getTop(); int myChannelSize = getMyChannelSize();//这里我是为了偷懒 ,算出来我的频道的大小 if (myChannelSize % spanCount == 0) { //添加到我的频道后会换行,所以找到倒数第4个的位置 View lastFourthView = mRecyclerView.getLayoutManager().findViewByPosition(getMyLastPosition() - 3); // View lastFourthView = mRecyclerView.getChildAt(getMyLastPosition() - 3); targetX = lastFourthView.getLeft(); targetY = lastFourthView.getTop() + lastFourthView.getHeight(); } // 推荐频道 移动到 我的频道的最后一个 channel.setItemType(Channel.TYPE_MY_CHANNEL);//改为推荐频道类型 if (onChannelDragListener != null) onChannelDragListener.onMoveToMyChannel(currentPosition, myLastPosition + 1); startAnimation(currentView, targetX, targetY); } else { channel.setItemType(Channel.TYPE_MY_CHANNEL);//改为推荐频道类型 if (myLastPosition == -1) myLastPosition = 0;//我的频道没有了,改成0 if (onChannelDragListener != null) onChannelDragListener.onMoveToMyChannel(currentPosition, myLastPosition + 1); } // GlobalParams.mRemovedChannels.remove(channel); } }); break; } } public int getMyChannelSize() { int size = 0; for (int i = 0; i < mData.size(); i++) { Channel channel = (Channel) mData.get(i); if (channel.getItemType() == Channel.TYPE_MY_CHANNEL) { size++; } } return size; } private void startAnimation(final View currentView, int targetX, int targetY) { final ViewGroup parent = (ViewGroup) mRecyclerView.getParent(); final ImageView mirrorView = addMirrorView(parent, currentView); TranslateAnimation animator = getTranslateAnimator(targetX - currentView.getLeft(), targetY - currentView.getTop()); currentView.setVisibility(View.INVISIBLE);//暂时隐藏 mirrorView.startAnimation(animator); animator.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { parent.removeView(mirrorView);//删除添加的镜像View if (currentView.getVisibility() == View.INVISIBLE) { currentView.setVisibility(View.VISIBLE);//显示隐藏的View } } @Override public void onAnimationRepeat(Animation animation) { } }); } /** * 添加需要移动的 镜像View */ private ImageView addMirrorView(ViewGroup parent, View view) { view.destroyDrawingCache(); //首先开启Cache图片 ,然后调用view.getDrawingCache()就可以获取Cache图片 view.setDrawingCacheEnabled(true); ImageView mirrorView = new ImageView(view.getContext()); //获取该view的Cache图片 Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache()); mirrorView.setImageBitmap(bitmap); //销毁掉cache图片 view.setDrawingCacheEnabled(false); int[] locations = new int[2]; view.getLocationOnScreen(locations);//获取当前View的坐标 int[] parenLocations = new int[2]; mRecyclerView.getLocationOnScreen(parenLocations);//获取RecyclerView所在坐标 FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(bitmap.getWidth(), bitmap.getHeight()); params.setMargins(locations[0], locations[1] - parenLocations[1], 0, 0); parent.addView(mirrorView, params);//在RecyclerView的Parent添加我们的镜像View,parent要是FrameLayout这样才可以放到那个坐标点 return mirrorView; } private int ANIM_TIME = 360; /** * 获取位移动画 */ private TranslateAnimation getTranslateAnimator(float targetX, float targetY) { TranslateAnimation translateAnimation = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0f, Animation.ABSOLUTE, targetX, Animation.RELATIVE_TO_SELF, 0f, Animation.ABSOLUTE, targetY); // RecyclerView默认移动动画250ms 这里设置360ms 是为了防止在位移动画结束后 remove(view)过早 导致闪烁 translateAnimation.setDuration(ANIM_TIME); translateAnimation.setFillAfter(true); return translateAnimation; } /** * 获取推荐频道列表的第一个position * * @return */ private int getOtherFirstPosition() { //之前找到了第一个pos直接返回 // if (mOtherFirstPosition != 0) return mOtherFirstPosition; for (int i = 0; i < mData.size(); i++) { Channel channel = (Channel) mData.get(i); if (Channel.TYPE_OTHER_CHANNEL == channel.getItemType()) { //找到第一个直接返回 return i; } } return -1; } /** * 我的频道最后一个的position * * @return */ private int getMyLastPosition() { for (int i = mData.size() - 1; i > -1; i--) { Channel channel = (Channel) mData.get(i); if (Channel.TYPE_MY_CHANNEL == channel.getItemType()) { //找到第一个直接返回 return i; } } return -1; } /** * 开启编辑模式 */ private void startEditMode(boolean isEdit) { mIsEdit = isEdit; int visibleChildCount = mRecyclerView.getChildCount(); for (int i = 0; i < visibleChildCount; i++) { View view = mRecyclerView.getChildAt(i); ImageView imgEdit = (ImageView) view.findViewById(R.id.ivDelete); if (imgEdit != null) { boolean isVis = imgEdit.getTag() == null ? false : (boolean) imgEdit.getTag(); imgEdit.setVisibility(isVis && isEdit ? View.VISIBLE : View.INVISIBLE); } } } }