Recycleview上拉刷新_下拉加载_侧滑删除加强篇
2017-03-25 16:23
288 查看
总有那么几个二比产品,让你上拉刷新下拉加载之后,又想让你可以侧滑删除,我想静静.
产品狗虽然可恨,可是我们还是得乖乖的去实现,没办法,谁让我们是打工的,加油骚年们.
看下我们的效果
首先定义我们最重要的一个侧滑处理类,使用ViewDragHelper来处理的.不懂的可以看下弘扬大神的博客
Android ViewDragHelper完全解析 自定义ViewGroup神器
然后定义我们的两个布局
带侧滑删除的类型
接下来看下我们的适配器
ok,到此我们自定义的侧滑删除功能就实现了,其实并没有太多难点,主要是在viewDragHelper这个类里边
Demo地址
欢迎Fork和Star,如果有问题,记得留言反馈给我啊.谢谢
产品狗虽然可恨,可是我们还是得乖乖的去实现,没办法,谁让我们是打工的,加油骚年们.
看下我们的效果
首先定义我们最重要的一个侧滑处理类,使用ViewDragHelper来处理的.不懂的可以看下弘扬大神的博客
Android ViewDragHelper完全解析 自定义ViewGroup神器
package yuan.kuo.yu.view; import android.content.Context; import android.graphics.Rect; import android.support.v4.widget.ViewDragHelper; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.FrameLayout; /** * Created by yukuoyuan on 2017/3/10. * 这是一个可以侧滑菜单的条目的父布局 */ public class SwipeRecycleviewItemLayout extends FrameLayout { private View menu; private View content; private final ViewDragHelper dragHelper; private boolean isOpen; private int currentState; /** * 构造方法 * * @param context 上下文 * @param attrs 属性集合 */ public SwipeRecycleviewItemLayout(Context context, AttributeSet attrs) { super(context, attrs); /** * 初始化我们自定义处理触摸事件的方法 */ dragHelper = ViewDragHelper.create(this, rightCallback); } private ViewDragHelper.Callback rightCallback = new ViewDragHelper.Callback() { // 触摸到View的时候就会回调这个方法。 // return true表示抓取这个View。 @Override public boolean tryCaptureView(View child, int pointerId) { return content == child; } /** * 重新处理子view的左侧 * @param child * @param left * @param dx * @return */ @Override public int clampViewPositionHorizontal(View child, int left, int dx) { return left > 0 ? 0 : left < -menu.getWidth() ? -menu.getWidth() : left; } /** * 当手指释放的时候回调 * @param releasedChild * @param xvel * @param yvel */ @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { // x轴移动速度大于菜单一半,或者已经移动到菜单的一般之后,展开菜单 if (isOpen) { if (xvel > menu.getWidth() || -content.getLeft() < menu.getWidth() / 2) { close(); } else { open(); } } else { if (-xvel > menu.getWidth() || -content.getLeft() > menu.getWidth() / 2) { open(); } else { close(); } } } /** * view 横向移动的范围 * @param child * @return */ @Override public int getViewHorizontalDragRange(View child) { return 1; } /** *view纵向移动的范围 * @param child * @return */ @Override public int getViewVerticalDragRange(View child) { return 1; } /** * 当ViewDragHelper状态发生变化的时候调用(IDLE,DRAGGING,SETTING[自动滚动时]) * @param state */ @Override public void onViewDragStateChanged(int state) { super.onViewDragStateChanged(state); currentState = state; } }; /** * 处理触摸事件(交给draghelper去处理) * * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { dragHelper.processTouchEvent(event); return true; } /** * 处理触摸事件 * * @param ev * @return */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return dragHelper.shouldInterceptTouchEvent(ev); } /** * 获取当前的状态 * * @return */ public int getState() { return currentState; } private Rect outRect = new Rect(); public Rect getMenuRect() { menu.getHitRect(outRect); return outRect; } /** * 当绘制完毕调用的方法 */ @Override protected void onFinishInflate() { super.onFinishInflate(); menu = getChildAt(0); content = getChildAt(1); } /** * 这是一个关闭菜单的方法 */ public void close() { dragHelper.smoothSlideViewTo(content, 0, 0); isOpen = false; invalidate(); } /** * 这是一个打开菜单的方法 */ public void open() { dragHelper.smoothSlideViewTo(content, -menu.getWidth(), 0); isOpen = true; invalidate(); } /** * 计算滚动事件 */ @Override public void computeScroll() { super.computeScroll(); if (dragHelper.continueSettling(true)) { invalidate(); } } /** * 设置点击事件 * * @param l */ @Override public void setOnClickListener(OnClickListener l) { content.setOnClickListener(l); } public boolean isOpen() { return this.isOpen; } }
然后定义我们的两个布局
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:background="?android:colorBackground" android:layout_height="60dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/item_content" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#49ff0000" android:gravity="center" android:text="小雨来了" android:textColor="@android:color/white" android:textSize="16sp" /> </RelativeLayout> </FrameLayout>
带侧滑删除的类型
<?xml version="1.0" encoding="utf-8"?> <yuan.kuo.yu.view.SwipeRecycleviewItemLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="60dp" android:background="?android:colorBackground"> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="right" android:orientation="horizontal"> <TextView android:id="@+id/delete" android:layout_width="60dp" android:layout_height="match_parent" android:background="#FF6A6A" android:gravity="center" android:text="删除" android:textColor="#fff" android:textSize="18sp" /> <TextView android:id="@+id/ok" android:layout_width="60dp" android:layout_height="match_parent" android:background="#e0e0e0" android:gravity="center" android:text="确定" android:textColor="#fff" android:textSize="16sp" /> </LinearLayout> <include layout="@layout/item_content" /> </yuan.kuo.yu.view.SwipeRecycleviewItemLayout>
接下来看下我们的适配器
package cn.yu.yuan; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; /** * Created by yukuo on 2016/4/30. */ public class DemoSwipeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<SwipeDate> list = new ArrayList<>(); public DemoSwipeAdapter(List<SwipeDate> list) { this.list = list; } public void addReFreshData() { notifyDataSetChanged(); } public void addRLoadMOreData() { notifyDataSetChanged(); } /** * 删除一个数据的方法 * * @param position 索引 */ // TODO 一定要按照这个方式写,不然会crash,希望你有更好的解决方案 public void removeData(int position) { list.remove(position); notifyItemRemoved(position + 1); if (position != list.size()) { if (position == 0) { notifyDataSetChanged(); } else if (position == (list.size() - 1)) { notifyItemRangeChanged(position, 0); } else { notifyItemRangeChanged(position, list.size() - position); } } } @Override public int getItemViewType(int position) { return list.get(position).type; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view; if (viewType == 1) { view = View.inflate(parent.getContext(), R.layout.item_swipe_menu, null); return new MySwipeMenuHolder(view); } else { view = View.inflate(parent.getContext(), R.layout.item_content, null); return new MyHolder(view); } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { if (holder instanceof MyHolder) { MyHolder myHolder = (MyHolder) holder; myHolder.item_content.setText(list.get(position).name); } else if (holder instanceof MySwipeMenuHolder) { MySwipeMenuHolder myHolder = (MySwipeMenuHolder) holder; myHolder.item_content.setText(list.get(position).name + "######" + position); myHolder.item_content.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(), list.get(position).name, Toast.LENGTH_SHORT).show(); } }); myHolder.delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { removeData(position); } }); } } @Override public int getItemCount() { return list.size(); } class MyHolder extends RecyclerView.ViewHolder { private final TextView item_content; public MyHolder(View itemView) { super(itemView); item_content = (TextView) itemView.findViewById(R.id.item_content); } } class MySwipeMenuHolder extends RecyclerView.ViewHolder { private final TextView delete; private final TextView ok; private final TextView item_content; public MySwipeMenuHolder(View itemView) { super(itemView); item_content = (TextView) itemView.findViewById(R.id.item_content); delete = (TextView) itemView.findViewById(R.id.delete); ok = (TextView) itemView.findViewById(R.id.ok); } } }
ok,到此我们自定义的侧滑删除功能就实现了,其实并没有太多难点,主要是在viewDragHelper这个类里边
Demo地址
欢迎Fork和Star,如果有问题,记得留言反馈给我啊.谢谢
相关文章推荐
- XRecycleView实现上啦刷新下拉加载
- RecycleView上拉刷新下拉加载
- RecycleView控件的使用(三) 实现上拉加载更多下拉刷新功能
- 最强RecyclerView,Item侧滑菜单,长按拖拽Item,滑动删除Item。可以和任何下拉刷新框架结合使用
- Recycleview的上拉刷新与下拉加载
- iOS开发 - 让tableView不能下拉刷新,可以上拉加载
- PullToReFresh 实现 RecycleView 横向滑动的刷新和加载更多
- XRecyclerView实现RecyclerView下拉刷新上来加载 自己做了部分修改,使代码更简洁易用
- 支持下拉加载刷新的RecyclerView
- 针对自定义组件上拉刷新下拉加载更多PullToRefreshView的分析(一)
- Android“上拉刷新/下拉加载”与“侧滑菜单”的兼容
- RecyclerView的上拉刷新与下拉加载
- Android自定义View之快速实现下拉刷新, 点击加载更多ListView
- RecyclerView使用详解一代替ListView(点击事件,添加头布局,上拉刷新下拉加载)
- RecycleView与SwipeRefreshLayout实现下拉刷新
- Android RecyclerView+item动画+下拉刷新,上拉加载更多,侧滑删除(易用可定制)
- 详解RecyclerView+BGARefreshLayout实现自定义下拉刷新、上拉加载和侧滑删除效果
- 针对自定义组件上拉刷新下拉加载更多PullToRefreshView的分析(一)
- Android开发之RecyclerView的上拉刷新和下拉加载
- pulltoRefreshSwipeMenuListview-带侧滑的可下拉刷新、上拉加载更多的控件