Android开发之RecyclerView的交互动画(实现拖拽和删除)
来源:互联网 发布:linux线程挂起与唤醒 编辑:程序博客网 时间:2024/05/20 14:15
做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回调监听时先调用的,用来判断当前是什么动作,比如判断方向(意思就是我要监听哪个方向的拖动) @Override public 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; } @Override public boolean isLongPressDragEnabled() { // 是否允许长按拖拽效果 return true; } //当移动的时候回调的方法--拖拽 @Override public 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; } //侧滑的时候回调的 @Override public void onSwiped(ViewHolder holder, int arg1) { // 监听侧滑,1.删除数据;2.调用adapter.notifyItemRemove(position) moveListener.onItemRemove(holder.getAdapterPosition()); } @Override public 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); } @Override public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) { // 恢复 viewHolder.itemView.setBackgroundColor(Color.WHITE); super.clearView(recyclerView, viewHolder); } @Override public void onChildDraw(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { //dX:水平方向移动的增量(负:往左;正:往右)范围:0~View.getWidth 0~1 float alpha = 1 - Math.abs(dX) / viewHolder.itemView.getWidth(); if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { //透明度动画 viewHolder.itemView.setAlpha(alpha);//1~0 viewHolder.itemView.setScaleX(alpha);//1~0 viewHolder.itemView.setScaleY(alpha);//1~0 } //删掉一个条目之后,恢复原状 if (alpha == 0) { viewHolder.itemView.setAlpha(1);//1~0 viewHolder.itemView.setScaleX(1);//1~0 viewHolder.itemView.setScaleY(1);//1~0 } //此super方法会自动处理setTranslation super.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; @Override protected 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); } @Override public 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); } } @Override public int getItemCount() { return mList.size(); } @Override public void onBindViewHolder(final MyViewHolder holder, int location) { holder.tv.setText(mList.get(location)); holder.iv.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { //传递触摸情况给谁? mDragListener.onStartDrag(holder); } return false; } }); } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem, parent, false); return new MyViewHolder(view); } @Override public boolean onItemMove(int fromPosition, int toPosition) { // 1.数据交换;2.刷新 Collections.swap(mList, fromPosition, toPosition); notifyItemMoved(fromPosition, toPosition); return true; } @Override public boolean onItemRemove(int position) { mList.remove(position); notifyItemRemoved(position); return true; }}
两个简单布局一并贴出:
mainActivity布局:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.fly.rv03.MainActivity"> <android.support.v7.widget.RecyclerView android: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="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:id="@+id/iv" android:layout_width="60dp" android:layout_height="60dp" android:src="@mipmap/ic_launcher" /> <TextView android: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先暂时告一段落,下节课我们学习另外一个知识点,敬请期待。。。
阅读全文
2 0
- Android开发之RecyclerView的交互动画(实现拖拽和删除)
- RecyclerView之使用ItemTouchHelper实现交互动画
- Android ItemTouchHelper实现RecyclerView交互动画
- Android 在RecyclerView中实现拖拽和滑动删除的效果
- Android一步一步带你实现RecyclerView的拖拽和侧滑删除功能
- Android一步一步带你实现RecyclerView的拖拽和侧滑删除功能
- Android一步一步带你实现RecyclerView的拖拽和侧滑删除功能
- Android一步一步带你实现RecyclerView的拖拽和侧滑删除功能
- Android一步一步带你实现RecyclerView的拖拽和侧滑删除功能
- Android一步一步带你实现RecyclerView的拖拽和侧滑删除功能
- Android RecyclerView 详解(三) RecyclerView的动画实现(移除、添加、改变、移动)和自定义动画的实现
- Android-RecyclerView实现Item添加和删除
- Android之RecyclerView的动画详解
- Android开发之实现滑动RecyclerView,浮动按钮的显示和隐藏(一)
- Android开发之实现滑动RecyclerView,浮动按钮的显示和隐藏(二)
- RecyclerView拖拽排序和滑动删除实现
- RecyclerView实现侧滑删除和拖拽排序
- recyclerview实现拖拽排序和侧滑删除
- 解决ScrollView中嵌套ListView或GridView导致的ScrollView自动滚动到ListView或GridView位置的问题
- 详谈jQuery中使用attr(), prop(), val()获取value的异同
- Hbuilder egit插件的安装使用--项目文件丢失的教训
- 【Java EE】--Contexts and Dependency Injection (上下文与依赖注入)04
- (个人总结)C++中int类型与String类型的相互转换
- Android开发之RecyclerView的交互动画(实现拖拽和删除)
- dfgsdfg
- APP加载错误导致FM打开失败
- 程序猿:003每个java程序猿撸代码过程中必写的基础知识
- oracle rman 备份恢复数据库和表空间
- Azkaban 3.0 分布式安装部署文档
- ReactiveCocoa 和 MVVM 入门
- Linux漏洞建议工具Linux Exploit Suggester
- 容器-安装