当前位置: 代码迷 >> Android >> Android 使用NineOldAndroids实现绚烂的ListView左右滑动删除Item效果
  详细解决方案

Android 使用NineOldAndroids实现绚烂的ListView左右滑动删除Item效果

热度:110   发布时间:2016-04-28 04:24:40.0
Android 使用NineOldAndroids实现绚丽的ListView左右滑动删除Item效果

转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/18311877),请尊重他人的辛勤劳动成果,谢谢!

今天还是给大家带来自定义控件的编写,自定义一个ListView的左右滑动删除Item的效果,这个效果之前已经实现过了,有兴趣的可以看下Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果,之前使用的是滑动类Scroller来实现的,但是看了下通知栏的左右滑动删除效果,确实很棒,当我们滑动Item超过一半的时候,item的透明度就变成了0,我们就知道抬起手指的时候item就被删除了,当item的透明度不为0的时候,我们抬起手指Item会回到起始位置,这样我们就知道拖动到什么位置item会删除,什么位置Item不删除,用户体验更好了,还有一个效果,就是我们滑动删除了item的时候,ListView的其他item会出现向上或者向下滚动的效果,感觉效果很棒,所以在GitHub上面搜索了下,发现很多开源库都有这个效果,比如ListViewAnimations,?android-swipelistview等等,我看了下实现原理,使用的是Jake Wharton的动画开源库NineOldAndroids,这个库究竟是干嘛的呢?在API3.0(Honeycomb), SDK新增了一个android.animation包,里面的类是实现动画效果相关的类,通过Honeycomb API,能够实现非常复杂的动画效果,但是如果开发者想在3.0以下使用这一套API, 则需要使用开源框架Nine Old Androids,在这个库中会根据我们运行的机器判断其SDK版本,如果是API3.0以上则使用Android自带的动画类,否则就使用Nine Old Androids库中,这是一个兼容库,接下来我们就来看看这个效果的具体实现吧

实现该效果的主要思路

?

  1. 先根据手指触摸的点来获取点击的是ListView的哪一个Item
  2. 当手指在屏幕上面滑动的时候,我们要使得Item跟随手指的滑动而滑动
  3. 当我们抬起手指的时候,我们根据滑动的距离或者手指在屏幕上面的速度来判断Item是滑出屏幕还是滑动至其实位置
  4. Item滑出屏幕时,使ListView的其他item产生向上挤压或者向下挤压的效果

?

大致的思路这是这四步,其中的一些细节接下来我会一一为大家解答的,接下来我们就用代码来实现这种效果吧

首先我们新建一个工程,叫Swipedismisslistview,我们需要将Nine Old Androids这个库引入到工程,大家可以去https://github.com/JakeWharton/NineOldAndroids下载,可以使用Jar包,也可以使用工程库的形式引入到我们自己的工程,我们还需要自定义一个ListView,我们先看代码然后给大家讲解下具体的功能实现

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片
?
  1. package?com.example.swipedismisslistview;??
  2. ??
  3. import?static?com.nineoldandroids.view.ViewHelper.setAlpha;??
  4. import?static?com.nineoldandroids.view.ViewHelper.setTranslationX;??
  5. import?android.content.Context;??
  6. import?android.util.AttributeSet;??
  7. import?android.view.MotionEvent;??
  8. import?android.view.VelocityTracker;??
  9. import?android.view.View;??
  10. import?android.view.ViewConfiguration;??
  11. import?android.view.ViewGroup;??
  12. import?android.widget.AdapterView;??
  13. import?android.widget.ListView;??
  14. ??
  15. import?com.nineoldandroids.animation.Animator;??
  16. import?com.nineoldandroids.animation.AnimatorListenerAdapter;??
  17. import?com.nineoldandroids.animation.ValueAnimator;??
  18. import?com.nineoldandroids.view.ViewHelper;??
  19. import?com.nineoldandroids.view.ViewPropertyAnimator;??
  20. /**?
  21. [email protected]://blog.csdn.net/xiaanming?
  22. ?*??
  23. [email protected]?
  24. ?*?
  25. ?*/??
  26. public?class?SwipeDismissListView?extends?ListView?{??
  27. ????/**?
  28. ?????*?认为是用户滑动的最小距离?
  29. ?????*/??
  30. ????private?int?mSlop;??
  31. ????/**?
  32. ?????*?滑动的最小速度?
  33. ?????*/??
  34. ????private?int?mMinFlingVelocity;??
  35. ????/**?
  36. ?????*?滑动的最大速度?
  37. ?????*/??
  38. ????private?int?mMaxFlingVelocity;??
  39. ????/**?
  40. ?????*?执行动画的时间?
  41. ?????*/??
  42. ????protected?long?mAnimationTime?=?150;??
  43. ????/**?
  44. ?????*?用来标记用户是否正在滑动中?
  45. ?????*/??
  46. ????private?boolean?mSwiping;??
  47. ????/**?
  48. ?????*?滑动速度检测类?
  49. ?????*/??
  50. ????private?VelocityTracker?mVelocityTracker;??
  51. ????/**?
  52. ?????*?手指按下的position?
  53. ?????*/??
  54. ????private?int?mDownPosition;??
  55. ????/**?
  56. ?????*?按下的item对应的View?
  57. ?????*/??
  58. ????private?View?mDownView;??
  59. ????private?float?mDownX;??
  60. ????private?float?mDownY;??
  61. ????/**?
  62. ?????*?item的宽度?
  63. ?????*/??
  64. ????private?int?mViewWidth;??
  65. ????/**?
  66. ?????*?当ListView的Item滑出界面回调的接口?
  67. ?????*/??
  68. ????private?OnDismissCallback?onDismissCallback;??
  69. ??
  70. ????/**?
  71. ?????*?设置动画时间?
  72. ?????*??
  73. [email protected]?
  74. ?????*/??
  75. ????public?void?setmAnimationTime(long?mAnimationTime)?{??
  76. ????????this.mAnimationTime?=?mAnimationTime;??
  77. ????}??
  78. ??
  79. ????/**?
  80. ?????*?设置删除回调接口?
  81. ?????*??
  82. [email protected]?
  83. ?????*/??
  84. ????public?void?setOnDismissCallback(OnDismissCallback?onDismissCallback)?{??
  85. ????????this.onDismissCallback?=?onDismissCallback;??
  86. ????}??
  87. ??
  88. ????public?SwipeDismissListView(Context?context)?{??
  89. ????????this(context,?null);??
  90. ????}??
  91. ??
  92. ????public?SwipeDismissListView(Context?context,?AttributeSet?attrs)?{??
  93. ????????this(context,?attrs,?0);??
  94. ????}??
  95. ??
  96. ????public?SwipeDismissListView(Context?context,?AttributeSet?attrs,??
  97. ????????????int?defStyle)?{??
  98. ????????super(context,?attrs,?defStyle);??
  99. ??
  100. ????????ViewConfiguration?vc?=?ViewConfiguration.get(context);??
  101. ????????mSlop?=?vc.getScaledTouchSlop();??
  102. ????????mMinFlingVelocity?=?vc.getScaledMinimumFlingVelocity()?*?8;?//获取滑动的最小速度??
  103. ????????mMaxFlingVelocity?=?vc.getScaledMaximumFlingVelocity();??//获取滑动的最大速度??
  104. ????}??
  105. ??
  106. ??????
  107. ????@Override??
  108. ????public?boolean?onTouchEvent(MotionEvent?ev)?{??
  109. ????????switch?(ev.getAction())?{??
  110. ????????case?MotionEvent.ACTION_DOWN:??
  111. ????????????handleActionDown(ev);??
  112. ????????????break;??
  113. ????????case?MotionEvent.ACTION_MOVE:??
  114. ????????????return?handleActionMove(ev);??
  115. ????????case?MotionEvent.ACTION_UP:??
  116. ????????????handleActionUp(ev);??
  117. ????????????break;??
  118. ????????}??
  119. ????????return?super.onTouchEvent(ev);??
  120. ????}??
  121. ??
  122. ????/**?
  123. ?????*?按下事件处理?
  124. ?????*??
  125. [email protected]?
  126. [email protected]?
  127. ?????*/??
  128. ????private?void?handleActionDown(MotionEvent?ev)?{??
  129. ????????mDownX?=?ev.getX();??
  130. ????????mDownY?=?ev.getY();??
  131. ??????????
  132. ????????mDownPosition?=?pointToPosition((int)?mDownX,?(int)?mDownY);??
  133. ??
  134. ????????if?(mDownPosition?==?AdapterView.INVALID_POSITION)?{??
  135. ????????????return;??
  136. ????????}??
  137. ??
  138. ????????mDownView?=?getChildAt(mDownPosition?-?getFirstVisiblePosition());??
  139. ??
  140. ????????if?(mDownView?!=?null)?{??
  141. ????????????mViewWidth?=?mDownView.getWidth();??
  142. ????????}??
  143. ??
  144. ????????//加入速度检测??
  145. ????????mVelocityTracker?=?VelocityTracker.obtain();??
  146. ????????mVelocityTracker.addMovement(ev);??
  147. ????}??
  148. ??????
  149. ??
  150. ????/**?
  151. ?????*?处理手指滑动的方法?
  152. ?????*??
  153. [email protected]?
  154. [email protected]?
  155. ?????*/??
  156. ????private?boolean?handleActionMove(MotionEvent?ev)?{??
  157. ????????if?(mVelocityTracker?==?null?||?mDownView?==?null)?{??
  158. ????????????return?super.onTouchEvent(ev);??
  159. ????????}??
  160. ??
  161. ????????//?获取X方向滑动的距离??
  162. ????????float?deltaX?=?ev.getX()?-?mDownX;??
  163. ????????float?deltaY?=?ev.getY()?-?mDownY;??
  164. ??
  165. ????????//?X方向滑动的距离大于mSlop并且Y方向滑动的距离小于mSlop,表示可以滑动??
  166. ????????if?(Math.abs(deltaX)?>?mSlop?&&?Math.abs(deltaY)?<?mSlop)?{??
  167. ????????????mSwiping?=?true;??
  168. ??????????????
  169. ????????????//当手指滑动item,取消item的点击事件,不然我们滑动Item也伴随着item点击事件的发生??
  170. ????????????MotionEvent?cancelEvent?=?MotionEvent.obtain(ev);??
  171. ????????????cancelEvent.setAction(MotionEvent.ACTION_CANCEL?|??
  172. ???????????????????????(ev.getActionIndex()<<?MotionEvent.ACTION_POINTER_INDEX_SHIFT));??
  173. ????????????onTouchEvent(cancelEvent);??
  174. ????????}??
  175. ??
  176. ????????if?(mSwiping)?{??
  177. ????????????//?跟谁手指移动item??
  178. ????????????ViewHelper.setTranslationX(mDownView,?deltaX);??
  179. ????????????//?透明度渐变??
  180. ????????????ViewHelper.setAlpha(mDownView,?Math.max(0f,?Math.min(1f,?1f?-?2f?*?Math.abs(deltaX)/?mViewWidth)));??
  181. ??
  182. ????????????//?手指滑动的时候,返回true,表示SwipeDismissListView自己处理onTouchEvent,其他的就交给父类来处理??
  183. ????????????return?true;??
  184. ????????}??
  185. ??
  186. ????????return?super.onTouchEvent(ev);??
  187. ??
  188. ????}??
  189. ??
  190. ????/**?
  191. ?????*?手指抬起的事件处理?
  192. [email protected]?
  193. ?????*/??
  194. ????private?void?handleActionUp(MotionEvent?ev)?{??
  195. ????????if?(mVelocityTracker?==?null?||?mDownView?==?null||?!mSwiping)?{??
  196. ????????????return;??
  197. ????????}??
  198. ??
  199. ????????float?deltaX?=?ev.getX()?-?mDownX;??
  200. ??????????
  201. ????????//通过滑动的距离计算出X,Y方向的速度??
  202. ????????mVelocityTracker.computeCurrentVelocity(1000);??
  203. ????????float?velocityX?=?Math.abs(mVelocityTracker.getXVelocity());??
  204. ????????float?velocityY?=?Math.abs(mVelocityTracker.getYVelocity());??
  205. ??????????
  206. ????????boolean?dismiss?=?false;?//item是否要滑出屏幕??
  207. ????????boolean?dismissRight?=?false;//是否往右边删除??
  208. ??????????
  209. ????????//当拖动item的距离大于item的一半,item滑出屏幕??
  210. ????????if?(Math.abs(deltaX)?>?mViewWidth?/?2)?{??
  211. ????????????dismiss?=?true;??
  212. ????????????dismissRight?=?deltaX?>?0;??
  213. ??????????????
  214. ????????????//手指在屏幕滑动的速度在某个范围内,也使得item滑出屏幕??
  215. ????????}?else?if?(mMinFlingVelocity?<=?velocityX??
  216. ????????????????&&?velocityX?<=?mMaxFlingVelocity?&&?velocityY?<?velocityX)?{??
  217. ????????????dismiss?=?true;??
  218. ????????????dismissRight?=?mVelocityTracker.getXVelocity()?>?0;??
  219. ????????}??
  220. ??
  221. ????????if?(dismiss)?{??
  222. ????????????ViewPropertyAnimator.animate(mDownView)??
  223. ????????????????????.translationX(dismissRight???mViewWidth?:?-mViewWidth)//X轴方向的移动距离??
  224. ????????????????????.alpha(0)??
  225. ????????????????????.setDuration(mAnimationTime)??
  226. ????????????????????.setListener(new?AnimatorListenerAdapter()?{??
  227. ????????????????????????@Override??
  228. ????????????????????????public?void?onAnimationEnd(Animator?animation)?{??
  229. ????????????????????????????//Item滑出界面之后执行删除??
  230. ????????????????????????????performDismiss(mDownView,?mDownPosition);??
  231. ????????????????????????}??
  232. ????????????????????});??
  233. ????????}?else?{??
  234. ????????????//将item滑动至开始位置??
  235. ????????????ViewPropertyAnimator.animate(mDownView)??
  236. ????????????.translationX(0)??
  237. ????????????.alpha(1)?????
  238. ????????????.setDuration(mAnimationTime).setListener(null);??
  239. ????????}??
  240. ??????????
  241. ????????//移除速度检测??
  242. ????????if(mVelocityTracker?!=?null){??
  243. ????????????mVelocityTracker.recycle();??
  244. ????????????mVelocityTracker?=?null;??
  245. ????????}??
  246. ??????????
  247. ????????mSwiping?=?false;??
  248. ????}??
  249. ??????
  250. ??
  251. ??????
  252. ????/**?
  253. ?????*?在此方法中执行item删除之后,其他的item向上或者向下滚动的动画,并且将position回调到方法onDismiss()中?
  254. [email protected]?
  255. [email protected]?
  256. ?????*/??
  257. ????private?void?performDismiss(final?View?dismissView,?final?int?dismissPosition)?{??
  258. ????????final?ViewGroup.LayoutParams?lp?=?dismissView.getLayoutParams();//获取item的布局参数??
  259. ????????final?int?originalHeight?=?dismissView.getHeight();//item的高度??
  260. ??
  261. ????????ValueAnimator?animator?=?ValueAnimator.ofInt(originalHeight,?0).setDuration(mAnimationTime);??
  262. ????????animator.start();??
  263. ??
  264. ????????animator.addListener(new?AnimatorListenerAdapter()?{??
  265. ????????????@Override??
  266. ????????????public?void?onAnimationEnd(Animator?animation)?{??
  267. ????????????????if?(onDismissCallback?!=?null)?{??
  268. ????????????????????onDismissCallback.onDismiss(dismissPosition);??
  269. ????????????????}??
  270. ??
  271. ????????????????//这段代码很重要,因为我们并没有将item从ListView中移除,而是将item的高度设置为0??
  272. ????????????????//所以我们在动画执行完毕之后将item设置回来??
  273. ????????????????ViewHelper.setAlpha(dismissView,?1f);??
  274. ????????????????ViewHelper.setTranslationX(dismissView,?0);??
  275. ????????????????ViewGroup.LayoutParams?lp?=?dismissView.getLayoutParams();??
  276. ????????????????lp.height?=?originalHeight;??
  277. ????????????????dismissView.setLayoutParams(lp);??
  278. ??
  279. ????????????}??
  280. ????????});??
  281. ??
  282. ????????animator.addUpdateListener(new?ValueAnimator.AnimatorUpdateListener()?{??
  283. ????????????@Override??
  284. ????????????public?void?onAnimationUpdate(ValueAnimator?valueAnimator)?{??
  285. ????????????????//这段代码的效果是ListView删除某item之后,其他的item向上滑动的效果??
  286. ????????????????lp.height?=?(Integer)?valueAnimator.getAnimatedValue();??
  287. ????????????????dismissView.setLayoutParams(lp);??
  288. ????????????}??
  289. ????????});??
  290. ??
  291. ????}??
  292. ??
  293. ????/**?
  294. ?????*?删除的回调接口?
  295. ?????*??
  296. [email protected]?
  297. ?????*??
  298. ?????*/??
  299. ????public?interface?OnDismissCallback?{??
  300. ????????public?void?onDismiss(int?dismissPosition);??
  301. ????}??
  302. ??
  303. }??

看过Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果你会发现,这个自定义的SwipeDismissListView只重写了onTouchEvent()方法,其实我们重写这一个方法就能实现我们需要的效果

?

1. 我们先看手指按下屏幕的处理方法handleActionDown();该方法里面根据我们手指按下的点根据pointToPosition()方法来获取我们点击的position,然后利用getChildAt()来获取我们按下的item的View对象,并且加入手指在屏幕滑动的速度检查,这一步相对来说还是比较简单


2. 接下来就是手指在屏幕上面滑动的处理方法handleActionMove(),这个方法就稍微的复杂些,我们需要根据手指在X轴的滑动距离和Y轴的滑动距离来判断是ListView?item的水平滑动还是ListView的上下滑动,当满足Math.abs(deltaX) > mSlop && Math.abs(deltaY) < mSlop这个条件时候,我们用一个布尔值mSwiping来标记Item现在处于水平滑动的状态,这时候我们需要处理Item跟随手指的滑动而滑动的逻辑,我们使用ViewHelper来处理Item的滑动逻辑,这个类会根据机器的SDK版本来判断使用Android系统的API还是NineOldandroids中自己实现的API使得View滑动的效果,NineOldandroids中主要使用Camera(可以实现各种复杂动画效果的类),我们直接使用ViewHelper的setTranslationX()和setAlpha()就实现了item滑动和透明度渐变的效果,为了使得我们在滑动item的时候,ListView不上下滚动,我们必须返回true来屏蔽ListView的上下滚动,这里需要我们要非常熟悉Android的事件分发机制,这里我就不说明了,大家不了解的去网上找找相关的文章看看
还有一个问题,就是当我们滑动ListView的item的时候,会伴随着item的点击事件,这不是我们想要的效果,所以当Item滑动的时候我们需要取消ListView Item的点击事件

?

3. 在看手指抬起的时候的处理方法handleActionUp(),这里面需要根据手指的滑动速度或者Item移动的距离来判断Item是滑出屏幕还是滑动至起始位置,并且要判断item向左还是向右滑出屏幕等等逻辑,具体的逻辑可以看代码,相信大家都看得懂.

我这里要说说ViewPropertyAnimator类,这个类能更好的实现一个View同时进行多个动画的功能,当然我们也可以使用ObjectAnimator利用AnimatorSet来实现一个View上的多个同时进行的动画效果,例如我们可以将

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片
?
  1. ViewPropertyAnimator.animate(mDownView)??
  2. ????????.translationX(dismissRight???mViewWidth?:?-mViewWidth)//X轴方向的移动距离??
  3. ????????.alpha(0)??
  4. ????????.setDuration(mAnimationTime)??
  5. ????????.setListener(new?AnimatorListenerAdapter()?{??
  6. ????????????@Override??
  7. ????????????public?void?onAnimationEnd(Animator?animation)?{??
  8. ????????????????//Item滑出界面之后执行删除??
  9. ????????????????performDismiss(mDownView,?mDownPosition);??
  10. ????????????}??
  11. ????????});??

替换成

[java]?view plaincopy在CODE上查看代码片派生到我的代码片
?
  1. AnimatorSet?set?=?new?AnimatorSet();??
  2. ????????????set.playTogether(ObjectAnimator.ofFloat(mDownView,?"translationX",?dismissRight???mViewWidth?:?-mViewWidth),???
  3. ????????????????????????????ObjectAnimator.ofFloat(mDownView,?"alpha",?0));??
  4. ????????????set.setDuration(mAnimationTime).start();??
  5. ????????????set.addListener(new?AnimatorListenerAdapter()?{??
  6. ????????????????????????@Override??
  7. ????????????????????????public?void?onAnimationEnd(Animator?animation)?{??
  8. ????????????????????????????//Item滑出界面之后执行删除??
  9. ????????????????????????????performDismiss(mDownView,?mDownPosition);??
  10. ????????????????????????}??
  11. ????????????????????});??

在效果上面是一样的,但是ViewPropertyAnimator在性能上要比使用ObjectAnimator来实现多个同时进行的动画要高的多,举个例子,假如要对View使用移动和透明度的动画,使用ViewPropertyAnimator的话,某个时间点上我们只需要调用一次invalidate()方法刷新界面就行了,而使用ObjectAnimator的话,移动的动画需要调用invalidate(),透明度的动画也需要调用invalidate()方法,在性能上使用AnimationSet比ViewPropertyAnimator要低,但是有的时候我们还是需要使用ObjectAnimator,比如,在某个时间内,我们需要将View先变大在变小在变大等复杂情况,这时候ObjectAnimator就派上用场了,例如

[java]?view plaincopy在CODE上查看代码片派生到我的代码片
?
  1. ObjectAnimator.ofInt(mDownView,?"scaleX",?0?,100?,0,?100).setDuration(100).start()??

通过上面的几步我们就实现了ListView的左右滑动删除item的效果啦,但是还有一个效果,item删除之后,ListView的其他item向上或者向下缓缓滑动的效果,实现这个也很容易,就是动态设置item的高度,item高度逐渐变小,这样其他的item就会出现向上或者向下挤压的效果啦!

?

4. 这里我们使用的是ValueAnimator这个类,这个类并不是针对View作用的动画,而是对某个值作用的动画,他默认使用的Interpolator(插补器)是AccelerateDecelerateInterpolator(开始和结束的时候慢,中间快) ,?举个很简单的例子,我们在10秒内使用ValueAnimator将某个值从0变化到100,如果使用LinearInterpolator(线性插补器,匀速变化)在第2秒的时候,这个值变成了20,而是用AccelerateDecelerateInterpolator,可能在第二秒的时候这个值为15或者13,所以我们在ValueAnimator变化的时候设置值动画变化的监听器AnimatorUpdateListener就知道某个时间这个值变成了多少,从而对View的某个属性进行设置(例如大小),所以ValueAnimator是间接的对View设置动画的

了解了ValueAnimator的使用原理,我们就可以现实上面的动画效果了,我们使用ValueAnimator将item的高度变成0,设置ValueAnimator变化的监听,我们在回调函数onAnimationUpdate()中动态的设置item的高度, 然后添加AnimatorListener监听动画的状态(例如动画开始,结束,重复等)监听,在动画结束的回调函数onAnimationEnd()中删除该item的数据,调用notifyDataSetChanged刷新ListView,看看下面这段代码

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片
?
  1. ViewHelper.setAlpha(dismissView,?1f);??
  2. ????????????????ViewHelper.setTranslationX(dismissView,?0);??
  3. ????????????????ViewGroup.LayoutParams?lp?=?dismissView.getLayoutParams();??
  4. ????????????????lp.height?=?originalHeight;??
  5. ????????????????dismissView.setLayoutParams(lp);??

我们使用动画只是将item移动出了屏幕,并且将item的高度设置为了0,并没有将item的View从ListView中Remove掉,况且ListView也不能直接Remove掉Item的,只能将数据源删除,在调用notifyDataSetChanged()刷新,所以我们需要将刚刚滑出屏幕高度设置为0的Item恢复回来

?

自定义控件的代码我们已经编写完了,接下来我们就要使用它了,先看界面的布局代码

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片
?
  1. <RelativeLayout?xmlns:android="http://schemas.android.com/apk/res/android"????
  2. ????xmlns:tools="http://schemas.android.com/tools"????
  3. ????android:layout_width="match_parent"????
  4. ????android:layout_height="match_parent">????
  5. ????
  6. ????<com.example.swipedismisslistview.SwipeDismissListView??
  7. ????????android:id="@+id/swipeDismissListView"????
  8. ????????android:layout_width="match_parent"????
  9. ????????android:layout_height="match_parent"???
  10. ????????android:listSelector="@android:color/transparent"??
  11. ????????android:cacheColorHint="@android:color/transparent">????
  12. ????</com.example.swipedismisslistview.SwipeDismissListView>??
  13. ????
  14. </RelativeLayout>????

?

很简单,一个RelativeLayout包裹我们自定义的ListView控件,接下来就是主界面的代码编写,跟平常的ListView使用一样,但是我们需要设置OnDismissCallback()监听,在

onDismiss()中删除该位置对于的数据,刷新ListView

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片
?
  1. package?com.example.swipedismisslistview;??
  2. ??
  3. import?java.util.ArrayList;??
  4. import?java.util.List;??
  5. ??
  6. import?android.app.Activity;??
  7. import?android.os.Bundle;??
  8. import?android.view.View;??
  9. import?android.widget.AdapterView;??
  10. import?android.widget.AdapterView.OnItemClickListener;??
  11. import?android.widget.ArrayAdapter;??
  12. import?android.widget.Toast;??
  13. ??
  14. import?com.example.swipedismisslistview.SwipeDismissListView.OnDismissCallback;??
  15. ??
  16. public?class?SwipeActivity?extends?Activity?{??
  17. ????private?SwipeDismissListView?swipeDismissListView;??
  18. ????private?ArrayAdapter<String>?adapter;??
  19. ????private?List<String>?dataSourceList?=?new?ArrayList<String>();??
  20. ??
  21. ????@Override??
  22. ????protected?void?onCreate(Bundle?savedInstanceState)?{??
  23. ????????super.onCreate(savedInstanceState);??
  24. ????????setContentView(R.layout.activity_swipe);??
  25. ????????init();??
  26. ????}??
  27. ??
  28. ????private?void?init()?{??
  29. ????????swipeDismissListView?=?(SwipeDismissListView)?findViewById(R.id.swipeDismissListView);??
  30. ????????for?(int?i?=?0;?i?<?20;?i++)?{??
  31. ????????????dataSourceList.add("滑动删除"?+?i);??
  32. ????????}??
  33. ??
  34. ????????adapter?=?new?ArrayAdapter<String>(this,??
  35. ????????????????android.R.layout.simple_list_item_1,??
  36. ????????????????android.R.id.text1,?dataSourceList);??
  37. ??????????
  38. ????????swipeDismissListView.setAdapter(adapter);??
  39. ??????????
  40. ????????swipeDismissListView.setOnDismissCallback(new?OnDismissCallback()?{??
  41. ??????????????
  42. ????????????@Override??
  43. ????????????public?void?onDismiss(int?dismissPosition)?{??
  44. ?????????????????adapter.remove(adapter.getItem(dismissPosition));???
  45. ????????????}??
  46. ????????});??
  47. ??????????
  48. ??????????
  49. ????????swipeDismissListView.setOnItemClickListener(new?OnItemClickListener()?{??
  50. ??
  51. ????????????@Override??
  52. ????????????public?void?onItemClick(AdapterView<?>?parent,?View?view,??
  53. ????????????????????int?position,?long?id)?{??
  54. ????????????????Toast.makeText(SwipeActivity.this,?adapter.getItem(position),?Toast.LENGTH_SHORT).show();??
  55. ????????????}??
  56. ????????});??
  57. ??
  58. ????}??
  59. ??
  60. }??

所有的代码都已经编写完毕了,接下来就是运行工程,看看具体的效果是不是我们想要的

好了,今天的讲解到这里结束了,有了NineOldAndroids我们可以在2.x的手机上面实现许多复杂的动画效果,文章也介绍了关于开源库NineOldAndroids使用的一些知识,文章有点长,希望读者还是先将文章看下,然后自己看看能不能自己实现出来,有什么不明白的地方请在下面留言,我会为大家解答的!

项目源码,点击下载

?

ps: 下载源码的时候运行出错,是因为我加入了NineOldAndroids的Jar包,然后又加入了NineOldAndroids工程库,主要是我写DEMO的时候为了方便看源码就导入了NineOldAndroids工程库,大家删除一个JAR包或者NineOldAndroids工程库?就能解决了

  相关解决方案