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. Maya 脚本控制物体自转

    在Maya中,我们可以用脚本来控制物体的自转方向,速度等等,步骤如下: 选择需要操作的物体object,打开通道盒Channel Box,点击编辑Edit,打开表达式Expressions面板 选择需 ...

  2. Android-----工程文件目录介绍

  3. jq遍历url判断是否为当前页面然后给导航上色

    举例:我们希望在此页面点击“我的头像”从而加亮它的背景颜色,跟“我的爱好”的背景颜色一样. 之前: 之后: 我是这样实现的:通过判断当前url是否存在某字段,遍历字段所在的位置给加上相应的样式,我这么 ...

  4. mysql中字段类型转换排序

    表中字段server_id是varchar类型,现在我们查询数据时想以server_id排一下序,排序后的结果 select server_id from cardserver where game_ ...

  5. Java中this关键字的几种用法

    1 . 当成员变量和局部变量重名时,在方法中使用this时,表示的是该方法所在类中的成员变量.(this是当前对象自己) 如:public class Hello { String s = " ...

  6. 任务中使用wget,不保存文件

    */20 * * * * wget --output-document=/dev/null http://www.domain.com 使用wget每过20分钟访问一次,不保存访问文件内容

  7. PHP检测移动设备类mobile detection使用实例

    目前,一个网站有多个版本是很正常的,如PC版,3G版,移动版等等.根据不同的浏览设备我们需要定向到不同的版本中.不仅如此,我们有时候还需要根据不同的客户端加载不同的CSS,因此我们需要能够检测浏览设备 ...

  8. Codevs 3287 货车运输

    题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过 ...

  9. AFNetworking 3.0+ 启用完整、严格的https证书较验参考代码

    // 1.初始化单例类      AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];     manager.securit ...

  10. mongodb的使用

    1.启动mongodb 启动mongodb在Linux中可以进入mongodb的bin目录下执行      ./mongod -dbpath=所建立的数据文件夹  -logpath=所建立的日志文件 ...