public abstract class SwipeMenuViewHolder {
/* 从左侧滑出菜单 */
public static final int EDGE_LEFT = 1;
/* 从右侧滑出菜单 */
public static final int EDGE_RIGHT = 2;
/* 默认从右侧滑出菜单 */
private int mTrackingEdges = EDGE_RIGHT;
/* 滑出来的布局 */
private View swipMenuView;
/* 可以拖动的布局 */
private View captureView;
/* 整个条目的布局 */
protected DragLayout itemView; private Context context; private DragViewHolder dragViewHolder; public SwipeMenuViewHolder(Context context, View swipMenuView, View captureView) {
this.swipMenuView = swipMenuView;
this.captureView = captureView;
this.context = context;
initItemView();
} public SwipeMenuViewHolder(Context context, View swipMenuView, View captureView, int mTrackingEdges) {
this.mTrackingEdges = mTrackingEdges;
this.swipMenuView = swipMenuView;
this.captureView = captureView;
this.context = context;
initItemView();
} private void initItemView() {
itemView = new DragLayout(context);
itemView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
itemView.setmTrackingEdges(mTrackingEdges);
itemView.initView(captureView, swipMenuView);
dragViewHolder = new DragViewHolder(this, itemView);
} public boolean isOpen() {
return itemView.state == DragLayout.STATE_OPNE;
} public DragViewHolder getDragViewHolder() {
return dragViewHolder;
} /**
* 初始化控件
*
* @param itemView 条目的布局
*/
public abstract void initView(View itemView); /**
* 获取this
*
* @param viewHolder 获取当前的 ViewHolder
* @return RecyclerViewDragHolder
*/
public static SwipeMenuViewHolder getHolder(RecyclerView.ViewHolder viewHolder) {
return ((DragViewHolder) viewHolder).holder;
} class DragViewHolder extends RecyclerView.ViewHolder { public SwipeMenuViewHolder holder; public DragViewHolder(SwipeMenuViewHolder holder, View itemView) {
super(itemView);
this.holder = holder;
initView(itemView); }
} private class DragLayout extends FrameLayout { private ViewDragHelper mDragHelper;
private View captureView;
private View swipeMenuView; /* 左侧起点 */
private int startX;
/* 可拉出来布局的宽度 */
private int swipeMenuWidth;
private int mTrackingEdges = EDGE_RIGHT;
/* 滑出来的百分比,大于这个值松开自动打开,否则就关闭 */
private float scrollPercent = 0.5f;
/* 当前打开状态 */
protected int state = STATE_CLOSE;
protected static final int STATE_OPNE = 1;
protected static final int STATE_CLOSE = 2; public DragLayout(Context context) {
super(context);
init();
} public DragLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
} public DragLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
} public void initView(View captureView, View swipeMenuView) {
this.captureView = captureView;
this.swipeMenuView = swipeMenuView;
startX = 0;
addView(createBgView(swipeMenuView));
addView(captureView);
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (widthMeasureSpec != 0) {
swipeMenuWidth = swipeMenuView.getWidth();
}
} /* 可以滑出来的布局 */
private View createBgView(View view) {
LinearLayout linearLayout = new LinearLayout(getContext());
linearLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
linearLayout.setGravity(mTrackingEdges == EDGE_RIGHT ? Gravity.END : Gravity.START);
linearLayout.addView(view);
return linearLayout;
} private void init() {
mDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragCallBack());
mDragHelper.setEdgeTrackingEnabled(mTrackingEdges == EDGE_RIGHT ? ViewDragHelper.EDGE_RIGHT : ViewDragHelper.EDGE_LEFT);
} public class ViewDragCallBack extends ViewDragHelper.Callback { public ViewDragCallBack() {
} @Override
public boolean tryCaptureView(View child, int pointerId) {
return child == captureView;
} @Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
if (left != startX) {
if (swipeMenuView.getVisibility() == View.GONE)
swipeMenuView.setVisibility(View.VISIBLE);
} else {
if (swipeMenuView.getVisibility() == View.VISIBLE)
swipeMenuView.setVisibility(View.GONE); }
invalidate();
} @Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
if (releasedChild != captureView)
return;
int endX;
Log.d("captureView.Left", captureView.getLeft() + "");
Log.d("scrollSwipeMenuWidth", (int) ((float) swipeMenuWidth * scrollPercent) + "");
Log.d("state", state + "");
Log.d("mTrackingEdges", mTrackingEdges + "");
Log.d("startX", +startX + "");
if (mTrackingEdges == EDGE_LEFT) {
if (captureView.getLeft() < (int) ((float) swipeMenuWidth * scrollPercent) || state == STATE_OPNE) {
endX = startX;
state = STATE_CLOSE;
} else {
endX = swipeMenuWidth;
state = STATE_OPNE;
// add by wanggeng for post event
postOPNEEvent();
}
} else {//bgView从右边缘滑出
if (captureView.getLeft() > -(int) ((float) swipeMenuWidth * scrollPercent) || state == STATE_OPNE) {//向右滑动关闭bgView
endX = startX;
state = STATE_CLOSE;
} else {//向左滑动拉出bgView
endX = -1 * swipeMenuWidth;
state = STATE_OPNE;
// add by wanggeng for post event
postOPNEEvent();
}
} Log.d("endX", +endX + "");
Log.d("swipeMenuWidth", +swipeMenuWidth + "");
if (mDragHelper.smoothSlideViewTo(captureView, endX, 0)) {
ViewCompat.postInvalidateOnAnimation(DragLayout.this);
}
invalidate();
} @Override
public int getViewHorizontalDragRange(View child) {
return (int) (swipeMenuWidth * scrollPercent);
} /**
* @param child 被拖动到view
* @param left captureView被拖动后距x轴的距离
* @param dx 横向移动的距离
* @return captureView被拖动后距x轴的距离
*/
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
if (mTrackingEdges == EDGE_LEFT) {
if (left > swipeMenuWidth && dx > 0) return swipeMenuWidth;
if (left < 0 && dx < 0) return 0;
} else {
if (left > 0 && dx > 0) return 0;
if (left < -swipeMenuWidth && dx < 0) return -swipeMenuWidth;
}
return left;
}
} @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (state == STATE_CLOSE) {
swipeMenuView.setVisibility(View.GONE);
}
return mDragHelper.shouldInterceptTouchEvent(ev);
} @Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
mDragHelper.processTouchEvent(event);
if (state == STATE_CLOSE) {
if (event.getAction() == MotionEvent.ACTION_UP) {
swipeMenuView.setVisibility(View.GONE);
}
}
return true;
} @Override
public void computeScroll() {
super.computeScroll();
if (mDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
} public void setmTrackingEdges(int mTrackingEdges) {
this.mTrackingEdges = mTrackingEdges;
mDragHelper.setEdgeTrackingEnabled(mTrackingEdges == EDGE_RIGHT ? ViewDragHelper.EDGE_RIGHT : ViewDragHelper.EDGE_LEFT);
}
}
public void scrollToClose() {
if (itemView.mDragHelper.smoothSlideViewTo(captureView, itemView.startX, 0)) {
ViewCompat.postInvalidateOnAnimation(itemView);
}
itemView.invalidate();
} for post event
public void postOPNEEvent() {
final ActionEvent actionEvent = new ActionEvent("STATE_OPNE");
actionEvent.setData(SwipeMenuViewHolder.this);
EventBus.getDefault().post(actionEvent);
}
}

RecycleView可以策划的Item的更多相关文章

  1. RecycleView实现侧滑删除item

    对于列表空间的侧滑操作,网上有很多开源的空间可以使用,Google在它的新控件RecycleView中增加了侧滑的API,完全遵循Material Design设计规范,下面看看效果演示: 下面看看介 ...

  2. 实现RecycleView动态使列表item可以点击或不可点击切换

    效果 这里讲的是第二个button跳转的Activity,这里和上一篇不同之处在于可以item点击.item子控件点击 继承BaseAdapter 同样也要继承BaseAdapter public c ...

  3. android基础开发之RecycleView(1)---基本使用方式

    RecycleView是google为了优化listview,gridview 提供的一个新的控件. 1.android 导入recycleview 在app的gradle里面加入: dependen ...

  4. NestedScrollView嵌套RecycleView发生的小问题

    1.解决方法:嵌套滑动不激活. recycleView.setNestedScrollingEnable(false); 这样做有个弊端,RecycleView的item会一次性加载完,不管是否显示, ...

  5. IAdjustCountOption--动态设置recycleView的itemCount(不须要改动数据源)

    概述 RecycleViewUtil是新增的一个主要针对RecycleView的一个工具类.该工具类中提供了部分RecycleView可能会使用到的方法,当中也包含了一些用来增强HeaderRecyc ...

  6. android UI控件小记

    1.关于text和drawableTop之类的间距 android:drawablePadding="10dp" 2.EditText属性 android:phoneNumber= ...

  7. 拆解轮子之XRecyclerView

    简介 这个轮子是对RecyclerView的封装,主要完成了下拉刷新.上拉加载更多.RecyclerView头部.在我的Material Design学习项目中使用到了项目地址,感觉还不错.趁着毕业答 ...

  8. 如何自定义RecycleView item的间距

    引言 在以前使用ListView和GridView时,设置item之间的间距还是相对比较简单的,因为它们的基本属性里面Android已经定义好了,可以直接设置属性值即可.但Google为了通用性和灵活 ...

  9. Android RecycleView 自定义Item的使用

    自定义布局的RecycleView需要自己实现Adapter,ViewHolder和布局: 自定义Adapter继承RecycleView.Adapter,重写getItemCount(),onBin ...

随机推荐

  1. c#语句 for循环嵌套

    1.打印三角形. 1) 方法一.for嵌套 方法二.只用一个for 2)倒三角 3)后三角 2.求100以内质数的和. 3.一张纸厚度为0.01米,至少对折多少次才能达到珠峰的高度?(用for死循环) ...

  2. 获取Java系统相关信息

    package com.test; import java.util.Properties; import java.util.Map.Entry; import org.junit.Test; pu ...

  3. android之消息机制(二)

    消息通道:Looper 首先编写main.xml文件 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk ...

  4. .net Sql语句批量插入数据库数据

    #region 使用SqlBulkCopy public static bool ExecuteTransactionScopeInsert(DataTable dt, int batchSize) ...

  5. 使用smtp和pop3 协议收发qq邮箱实验

    email系统组件:MTA 消息传输代理,负责邮件的路由,队列和发送SMTP 简单邮件传输协议1 连接到服务器2 登陆3 发出服务请求4 退出POP:邮局协议RFC918 "邮局协议的目的是 ...

  6. File类的createNewFile()与createTempFile()的区别

    最近,在看代码时看到了一个方法, File.createTempFile() ,由此联想到File.createNewFile() 方法,一时间不知道两者到底有什么区别,感觉都是创建新文件嘛,后来查看 ...

  7. java跳出外部循环

    java跳出外部循环两种方法 //用flag标识 boolean flag = true; for(int i=0;i<10&&flag;i++){ for(int j=0;j& ...

  8. ExtJS笔记 Tree

    The Tree Panel Component is one of the most versatile Components in Ext JS and is an excellent tool ...

  9. MyArrayAdapter 比较标准的写法

    ; i < mString.size(); i++) { insert(mString.get(i), i); } } notifyDataSetChanged(); LogUtils.LOGD ...

  10. 请求量限制方法-使用本地Cache记录当前请求量[坑]

    有个需求:需要限制每个账户请求服务器的次数(该次数可以配置在DB,xml文件或其他).单位:X次/分钟.若1分钟内次数<=X 则允许访问,1分钟内次数>X则不再允许访问.   这类需求很常 ...