您的位置:首页 > 其它

RecycleView如何设置点击拖动和定时拖动

2017-01-20 17:05 127 查看
今天说说RecycleView的拖拽时间的控制。博主在百度和谷歌上面都进行了无数次的搜索,却没有发现有任何一个是针对RecycleView的拖拽按下什么时候触发拖拽事件的文章。哎,可以说是难为死博主了,最后在大牛的帮助下在源码中找到了出路。废话不多说,接下来贴出源码分析这个难死博主的简单问题。

首先贴出一个大神对RecycleView的拖拽和滑动删除的博客地址,博主也是在这个基础上进行接下来的讲解的。

Android一步一步带你实现RecyclerView的拖拽和侧滑删除功能

这篇文章博主个人认为写更加容易理解一点,所以推荐这篇博客,如果大家是初识RecycleView的话,建议先看这篇文章再看博主的。接下来博主就在大神的基础上接着讲时间的问题

startDrag();

博主一开始的思路是竟然它是长按后会触发拖拽的方法的,博主在callback回中打Log,发现当我们触发长按之后第一个调用的是getMovementFlags()。于是想到我们应该用点击来代替长按,触发此方法。

重点方法一:

贴出第一段代码:

/**
* Starts dragging the provided ViewHolder. By default, ItemTouchHelper starts a drag when a
* View is long pressed. You can disable that behavior by overriding
* {@link ItemTouchHelper.Callback#isLongPressDragEnabled()}.
* <p>
* For this method to work:
* <ul>
* <li>The provided ViewHolder must be a child of the RecyclerView to which this
* ItemTouchHelper
* is attached.</li>
* <li>{@link ItemTouchHelper.Callback} must have dragging enabled.</li>
* <li>There must be a previous touch event that was reported to the ItemTouchHelper
* through RecyclerView's ItemTouchListener mechanism. As long as no other ItemTouchListener
* grabs previous events, this should work as expected.</li>
* </ul>
*
* For example, if you would like to let your user to be able to drag an Item by touching one
* of its descendants, you may implement it as follows:
* <pre>
*     viewHolder.dragButton.setOnTouchListener(new View.OnTouchListener() {
*         public boolean onTouch(View v, MotionEvent event) {
*             if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
*                 mItemTouchHelper.startDrag(viewHolder);
*             }
*             return false;
*         }
*     });

* @param viewHolder The ViewHolder to start dragging. It must be a direct child of
*                   RecyclerView.
* @see ItemTouchHelper.Callback#isItemViewSwipeEnabled()
*/
public void startDrag(ViewHolder viewHolder) {
if (!mCallback.hasDragFlag(mRecyclerView, viewHolder)) {
Log.e(TAG, "Start drag has been called but swiping is not enabled");
return;
}
if (viewHolder.itemView.getParent() != mRecyclerView) {
Log.e(TAG, "Start drag has been called with a view holder which is not a child of "
+ "the RecyclerView which is controlled by this ItemTouchHelper.");
return;
}
obtainVelocityTracker();
mDx = mDy = 0f;
select(viewHolder, ACTION_STATE_DRAG);
}


一眼看去很多东西但是,代码就那么简单几行,所以耐心点。博主再拆分讲解。。。。



这里面的意思大致就是说系统默认的是长按的时候触发拖拽,你可以disable它,然后重写这个方法(当然我们需要实现的功能不必去重写方法,后面会介绍用法。



这段就是一个简单的例子,告诉我们应该怎么去使用这个方法,实现我们需要的功能,点击就触发拖动。



这才是我们的方法,是不是很简单,就两个if语句而已。注意到的是参数是一个ViewHolder, 不要想的太多。简单点,说话的方式简单点,就是直接调用这个方法就可以实现点击就实现拖拽。

到此我们就已经可以实现点击拖拽了。如果想自己控制时间,我想大家都想的到,用handler或者线程的形式,这就不多说了。

显然大家都想进一步了解是怎么去实现的,首先看第一个if语句:

点击hasDragFlag()进入方法:

private boolean hasDragFlag(RecyclerView recyclerView, ViewHolder viewHolder) {
final int flags = getAbsoluteMovementFlags(recyclerView, viewHolder);
return (flags & ACTION_MODE_DRAG_MASK) != 0;
}


很简单的几行代码,继续点击进入getAbsoluteMovementFlags():

final int getAbso
4000
luteMovementFlags(RecyclerView recyclerView,
ViewHolder viewHolder) {
final int flags = getMovementFlags(recyclerView, viewHolder);
return convertToAbsoluteDirection(flags, ViewCompat.getLayoutDirection(recyclerView));
}


到这里也是简单的几行代码,但是博主注意到有一个方法很眼熟。没错getMovementFlags(), 这个方法。当我们根据系统的默认实现长按拖拽实现的时候,我们触发长按之后,第一个触发的就是这个方法,这个方法也是设置拖拽和滑动方向的方法。和博主一开始的思路是对的,系统提供的方法也是触发它。

今天就到这里吧,不知道分析的对与否,当然博主只分析了一小部分,还有其他的没有分析,比如第二个if语句和接下来的三个方法,也都是重点,等博主以后能力提升后会再次改进这篇文章和补全其他几个方法的深入解析。还希望大神可以多多指点。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  源码 博客