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. Linux下配置SVN

    1.安装svn yum -y install subversion 2.创建SVN版本库目录 mkdir -p /var/svn/svnrepos (-p参数:如果没有这个目录,则创建这个目录) 3. ...

  2. ArcGIS AddIN之工具不可用

    AddIN做的工具,第一次打开时工具亮起(可用),第一次点击之后工具就灰掉(不可用) 原因:该工具没有找到响应函数 具体原因:之前做的好多工具,好多个项目,好多代码.现在统一放到一个项目中,一个工具条 ...

  3. spring security方法一 自定义数据库表结构

    Spring Security默认提供的表结构太过简单了,其实就算默认提供的表结构很复杂,也无法满足所有企业内部对用户信息和权限信息管理的要求.基本上每个企业内部都有一套自己的用户信息管理结构,同时也 ...

  4. PHP中文函数顺序排列一数组且其序数不变

    函数Abs() 描述: mixed abs (mixed number); Returns the absolute value of number. If the argument number i ...

  5. Spinner的简单学习

    代码分析: package com.mecury.spinnertest; import java.util.ArrayList; import android.support.v7.app.Acti ...

  6. inotify配合rsync实现文件同步

    一.slave端rsync设置在此部署rsync服务和rsync daemon 1.安装rsync   2.配置rsyncd.conf文件#vi /etc/rsyncd.conf配置文件uid = r ...

  7. Java简单类(部门、领导、雇员关系)

    class Dept { private int deptno ; private String dname ; private String loc ; private Emp emps [] ; ...

  8. angularJs实现信息数据提交功能

    如下简单的报名提交的实现 1.数据绑定 2.$http.post()提交数据 一.数据绑定 <!--报名部分--> <div class="attend_box" ...

  9. CentOS6.0(64位)安装Apache+PHP+Mysql教程,安装Magento(解决DOM,Mcrypt,GD问题)完整教程

    CentOS6.0(64位)安装Apache+PHP+Mysql教程,安装Magento(解决DOM,Mcrypt,GD问题)完整教程 0   Posted by :小黑 On : 2012 年 9 ...

  10. 探索.git目录

    .git目录 下面就开始进入.git目录,通过“ls”命令可以看到.git目录中的文件和子目录: 对于这些文件和目录,下面给出了一些基本的描述. hooks:这个目录存放一些shell脚本,可以设置特 ...