* github开源项目DragSortListView使用文档译文,该控件实现了对ListItem的拖放排序和移除,项目地址见:
http://bauerca.github.com/drag-sort-listview
* 日鸟语,学了几十年仍然如屎般恶臭,终于还是给找到一丝散发余热的所在,泪奔;
-----------------------------------------------------------------------------------------------------------------------------------
注意:已不再提供技术支持。
没太多时间专注这个项目了,所以目下不能提供更多后续支持了。抱歉!
【动态】
20130402:
各位亲:如果你们想发送pull请求,请先仔细阅读Contributing部分,多谢!
20130209:
0.6.0版发布。
重新整理了点击移除和甩动移除。
不会再在拖动的过程中意外移除了;
甩动item的任意位置均可移除。
Leszek Mzyk真TM是只大神。
20130110:
0.5.0版发布。
支持ListView的多选和单选两种模式,感谢伟大的Mattias Flodin同志!
帅呆。
赶快检出新的demo吧!
20121123:
额...,介个是神马?→ Gittip :)
20121117:
APP Drag-Sort-Demos在GooglePlay上线!
20121115:
流畅运行!拖动和移除都动画鸟。并且,DragSortController又提供了一个相当好用的点击移除功能(参见XML attrs和RemoveListener部分)。
20121111:
maven化完成。感谢Andreas Schildbach (Goonie)!
20121030:
DragSortCursorAdapter类可助你重新排序基于Cursor的ListAdapter。
请查看API中的ResourceDragSortCursorAdapter和SimpleDragSortCursorAdapter两个类。
20121019:
20121029:
rampage重构中。
向后兼容稍有破坏。
但偶们获得了足够合算的新特性,包括:
floatingView的完全自定义、开始/释放拖动的完全可控、以及一个实现了普通操作(长按开始拖动,甩动移除,等等...)的帮助类供各位看官调用。
感谢伟大的Dan Hulme同志,是他令一切都滚动起来!
将持续更新更多demo和使用说明供各位检出。
20120926:
拖动排序现在具有动画效果了!(当然,这是可选的)其余item将围绕着拖动中的item上下滑行。
【概述】
DragSortListView (DSLV)扩展了安卓原生的ListView,使得用户可以对item进行拖动排序。
它彻底重写了TouchInterceptor(TI)(触屏拦截),赋予了拖动排序以无限优雅的用户体验。
主要特征包括:
1、干净清爽的拖动、释放操作(无任何视觉误差,至少我希望是!)
2、拖动过程中平滑、直观的卷动效果。
3、支持多高度的item共存。
4、提供startDrag()和stopDrag()公有方法接口。
5、提供自定义floatingView的公共接口。
DragSortListView在实现各种【支持用户自定义item优先级】的列表中大有用处,
比如:我的最爱(列表)、播放列表、各种清单,等等。
邮件我们吧!您的各种用例和应用需求,我们都翘首以盼、洗耳恭听。
真心希望这厮能为您所用;大侠们!小弟这厢跪求鸟~一起来帮我们改进这厮吧!
【控件使用方法】
三个主要元素定义了拖动排序的过程。
大体按重要性先后排序,它们是:
1、数据的重排序。
拖动排序实际上重排序了列表下隐藏的数据。
因为DSLV控件本身并不知道你要怎样重新组织你的数据,所以重排序的工作实际上由你亲自完成,途径就是通过给定的监听接口。
2、拖动的开始/释放。
拖动的开始和释放通过调用DSLV实例提供的startDrag()方法和stopDrag()实现。
支持类DragSortController为【开始拖动/释放/移除等普通操作】提供了各种实现支持。
3、Floating View。
floatingView(浮动视图)的表现和行为由FloatViewManager接口的一个实现类来控制。
藉此,你可以将任何View(视图)化身为floatingView,并根据用户的具体触屏操作更新其位置和表现形式。
为了方便起见,帮助类DragSortController同时也实现了该接口。
第一条是最为至关重要的。
至于二、三两条,可以借由帮助类DragSortController来进行处理。
继续阅读此文档,进而跑demo,来学习掌握此控件在各种用例下的具体使用方法。
【XML布局声明】
DragSortListView和原生的ListView一样可以在布局文件中声明。
demo中提供了一些布局文件的声明案例。
除了具有原生ListView的属性外,它还具有自己的特有属性。如下:
<xml attr>: (<datatype>, <default value>) <description>
【XML属性】
√collapsed_height:(dimension,1px)原始拖动位置占位符的高度。不能为零。
√drag_scroll_start:(float,0.3)拖动-卷动的初始区域(通过占DSLV总高度的比例定义,介于0和1之间)。
√max_drag_scroll_speed:(float,0.5)默认的最大拖动-卷动速度,单位像素/毫秒。
√float_alpha:(float, 1.0)floating View的透明度,全透明到不透明0~1之间。
√slide_shuffle_speed:(float,0.7)floating View下方洗牌动画的速度。0代表洗牌动画是完全逐帧移动的,1代表是完全跳动的,即由一个位置突变至另一个位置而完全没有动画过程。
√drop_animation_duration:(int,150)释放动画平滑地由释放位置过度到落定位置,之后floatingView被完全销毁。单位毫秒。
√remove_animation_duration:(int,150)当item被移除时,移除动画的时长,单位毫秒。
√track_drag_sort:(bool,false)调试选项,后面会解释。
√use_default_controller:(bool,true)令DSLV创建一个默认的DragSortController实例,并将以下属性传递过去。如果此项设置为false,则以下属性可以无视。
√float_background_color:(color,BLACK)当使用默认的DragSortController时,设置floatingView的背景色。此时的floatingView是被拖动item的快照。
√drag_handle_id:(id,0)指向item布局的childView或rootView的资源ID。它唯一标识了由谁来进行“拖动处理”,即只有触摸哪一个childView才能开始该item的拖动。当使用默认的DragSortController管理拖动时,该属性必须指定。
√sort_enabled:(bool,true)拖动item是否可以进行排序(有的时候你只想实现强制移除)。
√drag_start_mode:(enum,“onDown”)设置开始拖动的手势。
“onDown”:按下drag-handle时开始拖动。
“onDrag”:按下drag-handle并开始移动时开始拖动(考虑到有点击或长按的可能性)。
“onLongPress”:长按drag-handle时开始拖动(考虑到有点击的可能性)。
√remove_enabled:(bool,false)允许以以下模式移除被拖动的item。
√remove_mode:(enum,“flingRight”)设置移除item的手势。
“clickRemove”:点击带有click_remove_id的childView时移除该item。
“flingRemove”:点击item任意位置进行水平甩动时移除该item。
√click_remove_id:(id,0)点击带有该资源ID的childView时移除该item。注意:remove_enabled必须为“true”,remove_mode必须"clickRemove",是默认的DragSortController在使用该属性。
√fling_handle_id:(id,0)按下并甩动该childView时移除item。注意事项同理参考上一条。
【监听器】
DragSortListView是ListView,因此需要一个ListAdapter坐落于items之间。
此外,拖动排序的表明ListAdapter中的items需要不断地重新组织,而这种重新组织是经由定义在DSLV中的各种事件监听器接口的回调来实现的。
DSLV中的监听器有两种注册方式:
1、通过setXXListener()方法接口绑定。
2、实现你在自定义的ListAdapter中所需监听器的接口;
当DragSortListView.setAdapter(customListAdapter)被调用时,DSLV会自动探测哪个监听器接口被实现了,然后在设置customListAdapter时自动调用setXXListener()方法。
以下是每种监听器接口的具体描述。
【DragSortListView.DropListener 释放事件监听器】
DropListener接口只有一个回调函数:
public void drop(int from, int to);
该回调在拖动排序完成的时候被执行;也就是说,当floatingView被释放拖动的时候。
from参数和to参数分别代表item拖动的起始和释放位置。
这是个重要的回调;没有DropListener,DSLV毫无实际用途。
在正确的DSLV操作中,该回调必须执行ListAdapter中数据的重排序。
比如,我们通常用一个读取自数据库的Cursor来填装一个CursorAdapter。
在Cursor中items的顺序是固定的;因此,在拖动排序中,你必须实现一个由Cursor位置到DSLV位置的映射。
这种映射工作通常就是在一个实现了DropListener接口的ListAdapter或CursorWrapper中完成的。
请查看Issue#20中对此问题的讨论。
或者干脆就直接用DragSortCursorAdapter类!
如果你的DSLV实例的android:choiceMode属性不为“none”,并且你的ListAdapter没有稳定的id,那么你必须在drop(from,to)方法中调用DragSortListView.moveCheckState(int from, int to)方法。
请查看DSLV API文档以获取更多信息。
【DragSortListView.RemoveListener 移除事件监听器】
就像TI(TouchIntercepter)一样,DSLV提供了移除floatingView及其关联item的手势。
当移除手势完成的时候,DSLV会调用RemoveListener中的相关方法:
public void remove(int which);
which位置将被从你的ListAdapter中移除,即,从数据到ListAdapter中先前指向which位置的映射将从此被忽略。
至于你是否要连数据项也一并移除则完全由你自便。
item的移除也可以脱离拖动事件而发生,因为DragSortListView.removeItem(int position)方法可以随时调用。
如果你的DSLV实例的android:choiceMode属性不为“none”,并且你的ListAdapter没有稳定的id,那么你必须在remove(which)方法中调用DragSortListView.removeCheckState(which)。
请查看DSLV API文档以获取更多信息。
【DragSortListView.DragListener 拖动事件监听器】
DragListener中的回调是
public void drag(int from, int to);
该方法在floatingView移动时被不断调用;to代表当前的潜在释放位置,from则代表上一次的潜在位置。
TI也提供了相同的回调;但我现在还举不出什么例子。
【DragSortListView.DragSortListener 拖动排序监听器】
这是一个综合了上述各种监听器接口于一身的牛逼便利接口。
【FloatViewManager】
这是一个管理floatingView的创建、更新及销毁的接口。
它通过DSLV.setFloatViewManager()方法被赋值给DSLV。
使用方法的例子在SimpleFloatViewManager中有,这是一个通过简单地给被拖动item拍快照来实现floatingView管理的现成实现类。
如果你想给你的floatingView增添一点情趣的话,那就自己实现一个FloatViewManager。
在你的onCreateFloatView()中,你必须保证你所return的View有特定的高度(别鸡巴使用MATCH_PARENT!这货只有指定宽度的时候才好使)。
DSLV将根据指定的ViewGroup.LayoutParams将floatingView呈现出来。
如果没指定LayoutParams的话,DSLV就会用MATCH_PARENT和WRAP_CONTENT作为默认的宽高。
【拖动开始/结束】
在DragSortListView 0.3.0中,拖动的开始和结束行为完全由你自己指定。
你可以随意对DSLV实例调用startDrag()和stopDrag()。
但如果在调用startDrag()的时候并无触屏事件发生的话,拖动并不会自动开始。
别浪费时间去想如何初始化你的拖动事件了,接下来要介绍的DragSortController会为你轻松实现。
【DragSortController】
DragSortController是一个初始化拖动和移除item的现成实现类。
它实现了View.OnTouchListener接口,当触屏事件被分发到DSLV时实现事件监听。
它还通过继承SimpleFloatViewManager类实现了FloatViewManager接口,来简单处理floatingView的创建。
如果你没有通过指定XML属性创建默认的DragSortController的话,你就必须调setFloatViewManager()和setOnTouchListener()方法为DSLV传递你自己的DragSortController实例。
DragSortController默认认为所有可拖动的item都有一个叫做“drag handle”的childView。
该“drag handle”childView必须有关联的资源id,并且要传给DragSortController(当然,如果你在XML中指定了use_default_controller=true的话,就可以直接在XML设定)。
如果触屏事件发生在该“drag handle”childView上就能够被监听到,拖动就会开始。
【附件文档】
DSLV文档不多。你可以用Javadoc定位到/path/to/drag-sort-listview/src/进行检出,然后输入
javadoc com.mobeta.android.dslv *
眼下处于焦头烂额烂屁眼状态,无暇他顾。
有时间我会好好重新整理下文档的。
【安装】
先下载安装AndroidSDK,要克隆/下载本项目的repo,请直接访问GitHub,或者用Git克隆之(该项目是只读的)
【Ant略,Maven略】
【在Eclipse(Indigo)中安装】
第一步选择 File > Import,或在ProjectExplorer中右键然后选择Import。
如果你没用E-Git将Git整合到Eclipse中的话,请跳过本段。
选择"Projects from Git"作为导入源。
在Git页,点击Clone,键入本仓库的URI——这是本页唯一需要输入之处。
在接下来的各页面中,选择克隆哪些分支(或者干脆全部)、本地仓库建在何处,点击Finish。
一旦克隆完成,从列表中选择你的新仓库,然后在接下来的页面中选择“Use the New Projects wizard”。
从这步开始,无论你是否有使用E-Git,所有步骤都是完全相同的。
选择 “Android Project from Existing Code”并浏览你检出DSLV的本地目录。
你会在列表中看到两个项目:一个以目录名命名,另一个叫做com.mobeta.android.demodslv.Launcher。
第一个是library工程,第二个是demo工程。
一开始你可能两个都需要,所以直接点Finish。
最后,将library添加到你自己的应用项目中,PackageExplorer中右键选Properties。
选Android,下方点Add,你会看到DSLV工程和空间中的其它工程。
【参与本项目】
首先,谢谢!诸位的pull请求使本项目蓬荜生辉。多谢抬爱感激不尽!
鉴于眼下本工程已臻成熟,在此我想为今后的pull请求说几条不算规则的规则。
目前我只有一条(当然你们还可以加)。如下:
请避免发送【对默认的DragSortController行为进行零敲碎打小规模修改的】pull请求。
因为该类仅仅是一个引导帮助类,用以帮助用户建立更复杂的拖动排序交互。
比如,你不想在自己的应用中使用甩动移除,你就创建一个pull请求试图“修复”该操作——
其实,你更应该重写或继承DragSortController类来实现自己的特定的需求。
话虽如此,但如果一种全新且“极其必要的”触屏操作方式诞生了,我想本条仍有商榷空间。
【调试略】
【许可证】
本控件为安卓原生ListView的子类控件,实现了对item的拖动排序功能。
版权所有 2012 Carl Bauer
根据本许可证,用户可以不使用此文件。
除非因适用法律需要或书面同意,否则,根据本许可证发布的软件均须"按原样"提供本文件,无任何明示的或暗示的保证或条件。
更多详情,请参阅本证特定语言版本下的【管辖权限和限制】条款。
--------------------------------------------------------------------------------------------------------------------------------------------------------------
* 日美术