失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android开发之RecyclerView的交互动画(实现拖拽和删除)

Android开发之RecyclerView的交互动画(实现拖拽和删除)

时间:2019-09-22 21:30:16

相关推荐

Android开发之RecyclerView的交互动画(实现拖拽和删除)

做RecyclerView做相关的动画效果的时候,用的最多的是v7包下的ItemTouchHelper类,这个类很强大,如有兴趣的童鞋可以自行翻看源码,接下来我带领大家实现RecyclerView相关的交互动画。大家看下面的效果(拖拽和删除):

------------------------------------------华丽的分割线---------------------------------------------------------------------

实现原理:通过重写ItemTouchHelper类的callback回调方法,然后itemTouchHelper.attachToRecyclerView(mRecyclerView)来实现item的拖拽和删除。

------------------------------------------华丽的分割线---------------------------------------------------------------------

首先我们需要先定义一个接口

当拖拽的时候回调和当条目被移除的时候回调(详细看代码注释):

public interface ItemTouchMoveListener {/*** 当拖拽的时候回调* 可以在此方法里面实现:拖拽条目并实现刷新效果* fromPosition 从什么位置拖* toPosition到什么位置* 是否执行了move*/boolean onItemMove(int fromPosition, int toPosition);/*** 当条目被移除是回调* position 移除的位置*/boolean onItemRemove(int position);}

接口完成之后开始重写ItemTouchHelper.Callback,来判断用户的动作滑动方向以及选中状态等....

import android.graphics.Canvas;import android.graphics.Color;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.RecyclerView.ViewHolder;import android.support.v7.widget.helper.ItemTouchHelper;import android.support.v7.widget.helper.ItemTouchHelper.Callback;public class MyItemTouchHelperCallback extends Callback {private ItemTouchMoveListener moveListener;public MyItemTouchHelperCallback(ItemTouchMoveListener moveListener) {this.moveListener = moveListener;}//Callback回调监听时先调用的,用来判断当前是什么动作,比如判断方向(意思就是我要监听哪个方向的拖动)@Overridepublic int getMovementFlags(RecyclerView recyclerView, ViewHolder holder) {//需要监听的拖拽方向是哪两个方向int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;//我要监听的swipe侧滑方向是哪个方向int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;int flags = makeMovementFlags(dragFlags, swipeFlags);return flags;}@Overridepublic boolean isLongPressDragEnabled() {// 是否允许长按拖拽效果return true;}//当移动的时候回调的方法--拖拽@Overridepublic boolean onMove(RecyclerView recyclerView, ViewHolder srcHolder, ViewHolder targetHolder) {if (srcHolder.getItemViewType() != targetHolder.getItemViewType()) {return false;}// 在拖拽的过程当中不断地调用adapter.notifyItemMoved(from,to);boolean result = moveListener.onItemMove(srcHolder.getAdapterPosition(), targetHolder.getAdapterPosition());return result;}//侧滑的时候回调的@Overridepublic void onSwiped(ViewHolder holder, int arg1) {// 监听侧滑,1.删除数据;2.调用adapter.notifyItemRemove(position)moveListener.onItemRemove(holder.getAdapterPosition());}@Overridepublic void onSelectedChanged(ViewHolder viewHolder, int actionState) {//判断选中状态if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {viewHolder.itemView.setBackgroundColor(viewHolder.itemView.getContext().getResources().getColor(R.color.colorAccent));}super.onSelectedChanged(viewHolder, actionState);}@Overridepublic void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {// 恢复viewHolder.itemView.setBackgroundColor(Color.WHITE);super.clearView(recyclerView, viewHolder);}@Overridepublic void onChildDraw(Canvas c, RecyclerView recyclerView,ViewHolder viewHolder, float dX, float dY, int actionState,boolean isCurrentlyActive) {//dX:水平方向移动的增量(负:往左;正:往右)范围:0~View.getWidth 0~1float alpha = 1 - Math.abs(dX) / viewHolder.itemView.getWidth();if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {//透明度动画viewHolder.itemView.setAlpha(alpha);//1~0viewHolder.itemView.setScaleX(alpha);//1~0viewHolder.itemView.setScaleY(alpha);//1~0}//删掉一个条目之后,恢复原状if (alpha == 0) {viewHolder.itemView.setAlpha(1);//1~0viewHolder.itemView.setScaleX(1);//1~0viewHolder.itemView.setScaleY(1);//1~0}//此super方法会自动处理setTranslationsuper.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);}}

接下来还需要个接口该接口主要是回调拖拽效果的

import android.support.v7.widget.RecyclerView.ViewHolder;public interface StartDragListener {/*** 该接口用于需要主动回调拖拽效果的* @param viewHolder*/void onStartDrag(ViewHolder viewHolder);}

然后在mainactivity中实现StartDragListener接口,传递给adapter,同时在实现的接口里设置itemTouchHelper.startDrag(viewHolder);

mainactivy完整代码:

import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.DividerItemDecoration;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.helper.ItemTouchHelper;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity implements StartDragListener {private RecyclerView mRecyclerView;private ArrayList<String> mList;private MyAdapter mAdapter;private ItemTouchHelper itemTouchHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mRecyclerView = (RecyclerView) findViewById(R.id.rv);mRecyclerView.setLayoutManager(new LinearLayoutManager(this));mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));mAdapter = new MyAdapter(getData(), this);mRecyclerView.setAdapter(mAdapter);//条目触摸帮助类ItemTouchHelper.Callback callback = new MyItemTouchHelperCallback(mAdapter);itemTouchHelper = new ItemTouchHelper(callback);itemTouchHelper.attachToRecyclerView(mRecyclerView);}@Overridepublic void onStartDrag(RecyclerView.ViewHolder viewHolder) {itemTouchHelper.startDrag(viewHolder);}public List<String> getData() {mList = new ArrayList<String>();for (int i = 0; i < 20; i++) {mList.add("item" + i);}return mList;}}

然后在Adapter中实现数据的交换刷新和移除。

MyAdapter完整代码:

import android.support.v7.widget.RecyclerView.Adapter;import android.support.v7.widget.RecyclerView.ViewHolder;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import java.util.Collections;import java.util.List;public class MyAdapter extends Adapter<MyAdapter.MyViewHolder> implements ItemTouchMoveListener {private List<String> mList;private StartDragListener mDragListener;public MyAdapter(List<String> list, StartDragListener dragListener) {this.mList = list;this.mDragListener = dragListener;}class MyViewHolder extends ViewHolder {private ImageView iv;private TextView tv;public MyViewHolder(View itemView) {super(itemView);iv = (ImageView) itemView.findViewById(R.id.iv);tv = (TextView) itemView.findViewById(R.id.tv);}}@Overridepublic int getItemCount() {return mList.size();}@Overridepublic void onBindViewHolder(final MyViewHolder holder, int location) {holder.tv.setText(mList.get(location));holder.iv.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {//传递触摸情况给谁?mDragListener.onStartDrag(holder);}return false;}});}@Overridepublic MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem, parent, false);return new MyViewHolder(view);}@Overridepublic boolean onItemMove(int fromPosition, int toPosition) {// 1.数据交换;2.刷新Collections.swap(mList, fromPosition, toPosition);notifyItemMoved(fromPosition, toPosition);return true;}@Overridepublic boolean onItemRemove(int position) {mList.remove(position);notifyItemRemoved(position);return true;}}

两个简单布局一并贴出:

mainActivity布局:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.fly.rv03.MainActivity"><android.support.v7.widget.RecyclerViewandroid:id="@+id/rv"android:layout_width="match_parent"android:layout_height="match_parent" /></RelativeLayout>

item布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><ImageViewandroid:id="@+id/iv"android:layout_width="60dp"android:layout_height="60dp"android:src="@mipmap/ic_launcher" /><TextViewandroid:id="@+id/tv"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center"android:text="text" /></LinearLayout></LinearLayout>

------------------------------------------华丽的分割线---------------------------------------------------------------------

再次体验下效果:

长按移动:

------------------------------华丽的分割线-------------------------------------------------------------------------------

RecyclerView先暂时告一段落,下节课我们学习另外一个知识点,敬请期待。。。

如果觉得《Android开发之RecyclerView的交互动画(实现拖拽和删除)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。