这是使用ItemTouchHelper技术实现一个选择相册后,仿微信朋友圈图片拖拽更换位置,拖拽删除的一个功能.希望可以帮到大家.
完整项目地址:https://download.csdn.net/download/hzqit520/12342742
项目演示如下图:
主要的代码如下:
mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public boolean isLongPressDragEnabled () {
return true;
}
@Override
public void onSwiped (@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public int getMovementFlags (@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
int itemViewType = viewHolder.getItemViewType();
if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
viewHolder.itemView.setAlpha(0.7f);
}
return makeMovementFlags(ItemTouchHelper.DOWN | ItemTouchHelper.UP
| ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, 0);
}
@Override
public boolean onMove (@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
//得到item原来的position
try {
int fromPosition = viewHolder.getAdapterPosition();
//得到目标position
int toPosition = target.getAdapterPosition();
int itemViewType = target.getItemViewType();
if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(mAdapter.getData(), i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(mAdapter.getData(), i, i - 1);
}
}
mAdapter.notifyItemMoved(fromPosition, toPosition);
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
@Override
public void onChildDraw (@NonNull Canvas c, @NonNull RecyclerView recyclerView,
@NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
int itemViewType = viewHolder.getItemViewType();
if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
if (null == mDragListener) {
return;
}
if (needScaleBig) {
//如果需要执行放大动画
viewHolder.itemView.animate().scaleXBy(0.1f).scaleYBy(0.1f).setDuration(100);
//执行完成放大动画,标记改掉
needScaleBig = false;
//默认不需要执行缩小动画,当执行完成放大 并且松手后才允许执行
needScaleSmall = false;
}
int sh = recyclerView.getHeight() + mTvDeleteText.getHeight();
int ry = mTvDeleteText.getTop() - sh;
if (dY >= ry) {
//拖到删除处
mDragListener.deleteState(true);
if (isUpward) {
//在删除处放手,则删除item
viewHolder.itemView.setVisibility(View.INVISIBLE);
mAdapter.delete(viewHolder.getAdapterPosition());
resetState();
return;
}
} else {//没有到删除处
if (View.INVISIBLE == viewHolder.itemView.getVisibility()) {
//如果viewHolder不可见,则表示用户放手,重置删除区域状态
mDragListener.dragState(false);
}
if (needScaleSmall) {//需要松手后才能执行
viewHolder.itemView.animate().scaleXBy(1f).scaleYBy(1f).setDuration(100);
}
mDragListener.deleteState(false);
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
}
@Override
public void onSelectedChanged (@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
int itemViewType = viewHolder != null ? viewHolder.getItemViewType() : GridImageAdapter.TYPE_CAMERA;
if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
if (ItemTouchHelper.ACTION_STATE_DRAG == actionState && mDragListener != null) {
mDragListener.dragState(true);
}
super.onSelectedChanged(viewHolder, actionState);
}
}
@Override
public long getAnimationDuration (@NonNull RecyclerView recyclerView, int animationType, float animateDx, float animateDy) {
needScaleSmall = true;
isUpward = true;
return super.getAnimationDuration(recyclerView, animationType, animateDx, animateDy);
}
@Override
public void clearView (@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
int itemViewType = viewHolder.getItemViewType();
if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
viewHolder.itemView.setAlpha(1.0f);
super.clearView(recyclerView, viewHolder);
mAdapter.notifyDataSetChanged();
resetState();
}
}
});
// 绑定拖拽事件
mItemTouchHelper.attachToRecyclerView(mRecyclerView);
底部删除的文字和图片改变是根据拖拽监听,通过接口控制的,代码如下:
mDragListener = new DragListener() {
@Override
public void deleteState (boolean isDelete) {
if (isDelete) {
mTvDeleteText.setText("松手即可删除");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
mTvDeleteText.setCompoundDrawablesRelativeWithIntrinsicBounds(0, R.mipmap.icon_let_go_delete, 0, 0);
}
} else {
mTvDeleteText.setText("拖动到此处删除");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
mTvDeleteText.setCompoundDrawablesRelativeWithIntrinsicBounds(0, R.mipmap.picture_icon_delete, 0, 0);
}
}
}
@Override
public void dragState (boolean isStart) {
int visibility = mTvDeleteText.getVisibility();
if (isStart) {
if (visibility == View.GONE) {
mTvDeleteText.animate().alpha(1).setDuration(300).setInterpolator(new AccelerateInterpolator());
mTvDeleteText.setVisibility(View.VISIBLE);
}
} else {
if (visibility == View.VISIBLE) {
mTvDeleteText.animate().alpha(0).setDuration(300).setInterpolator(new AccelerateInterpolator());
mTvDeleteText.setVisibility(View.GONE);
}
}
}
};