当前位置: 代码迷 >> Android >> 可动态格局的Android抽屉之完整篇
  详细解决方案

可动态格局的Android抽屉之完整篇

热度:101   发布时间:2016-05-01 20:15:22.0
可动态布局的Android抽屉之完整篇

本文来自http://blog.csdn.net/hellogv/?,欢迎转摘,引用必须注明出处!??????

?????? 上次介绍了基础篇,讲解了自定义抽屉控件的基础实现,这次就在基础篇的基础上加入拖拉功能。拖拉功能基于GestureDetector,GestureDetector的基本使用方式不是本文介绍的重点,有兴趣的童鞋可以上网查询相关的教程。

?????? 本文的抽屉控件相对于基础篇的抽屉控件多了以下功能:

1.支持手势拖拉

2.拖拉到一半时,可以自动展开或者收缩。
具体如下图:

?

?

?

?

?

?

本文的源码可以到这里下载:http://download.csdn.net/detail/hellogv/3642418

只贴出抽屉组件的源码,其他源文件与基础篇的一样:

[java]?view plaincopyprint?
  1. <span?style="font-family:Comic?Sans?MS;font-size:18px;">public?class?Panel?extends?LinearLayout?implements?GestureDetector.OnGestureListener{??
  2. ??????
  3. ????public?interface?PanelClosedEvent?{??
  4. ????????void?onPanelClosed(View?panel);??
  5. ????}??
  6. ??????
  7. ????public?interface?PanelOpenedEvent?{??
  8. ????????void?onPanelOpened(View?panel);??
  9. ????}??
  10. ??????
  11. ????private?final?static?int?HANDLE_WIDTH=30;??
  12. ????private?final?static?int?MOVE_WIDTH=20;??
  13. ????private?Button?btnHandler;??
  14. ????private?LinearLayout?panelContainer;??
  15. ????private?int?mRightMargin=0;??
  16. ????private?Context?mContext;??
  17. ????private?GestureDetector?mGestureDetector;??
  18. ????private?boolean?mIsScrolling=false;??
  19. ????private?float?mScrollX;??
  20. ????private?PanelClosedEvent?panelClosedEvent=null;??
  21. ????private?PanelOpenedEvent?panelOpenedEvent=null;??
  22. ??????
  23. ????public?Panel(Context?context,View?otherView,int?width,int?height)?{??
  24. ????????super(context);??
  25. ????????this.mContext=context;??
  26. ??????????
  27. ????????//定义手势识别??
  28. ????????mGestureDetector?=?new?GestureDetector(mContext,this);??
  29. ????????mGestureDetector.setIsLongpressEnabled(false);??
  30. ??????????
  31. ????????//改变Panel附近组件的属性??
  32. ????????LayoutParams?otherLP=(LayoutParams)?otherView.getLayoutParams();??
  33. ????????otherLP.weight=1;??
  34. ????????otherView.setLayoutParams(otherLP);??
  35. ??????????
  36. ????????//设置Panel本身的属性??
  37. ????????LayoutParams?lp=new?LayoutParams(width,?height);??
  38. ????????lp.rightMargin=-lp.width+HANDLE_WIDTH;??
  39. ????????mRightMargin=Math.abs(lp.rightMargin);??
  40. ????????this.setLayoutParams(lp);??
  41. ????????this.setOrientation(LinearLayout.HORIZONTAL);??
  42. ??????????
  43. ????????//设置Handler的属性??
  44. ????????btnHandler=new?Button(context);??
  45. ????????btnHandler.setLayoutParams(new?LayoutParams(HANDLE_WIDTH,height));??
  46. ????????//btnHandler.setOnClickListener(handlerClickEvent);??
  47. ????????btnHandler.setOnTouchListener(handlerTouchEvent);??
  48. ????????this.addView(btnHandler);??
  49. ??????????
  50. ????????//设置Container的属性??
  51. ????????panelContainer=new?LinearLayout(context);??
  52. ????????panelContainer.setLayoutParams(new?LayoutParams(LayoutParams.FILL_PARENT,??
  53. ????????????????LayoutParams.FILL_PARENT));??
  54. ????????this.addView(panelContainer);??
  55. ??
  56. ????}??
  57. ??
  58. ????private?View.OnTouchListener?handlerTouchEvent=new?View.OnTouchListener()?{??
  59. ??????????
  60. ????????@Override??
  61. ????????public?boolean?onTouch(View?v,?MotionEvent?event)?{??
  62. ????????????if(event.getAction()==MotionEvent.ACTION_UP?&&?//onScroll时的ACTION_UP??
  63. ????????????????????mIsScrolling==true)??
  64. ????????????{??
  65. ????????????????LayoutParams?lp=(LayoutParams)?Panel.this.getLayoutParams();??
  66. ????????????????if?(lp.rightMargin?>=?(-mRightMargin/2))?{//往左超过一半??
  67. ????????????????????new?AsynMove().execute(new?Integer[]?{?MOVE_WIDTH?});//?正数展开??
  68. ????????????????}???
  69. ????????????????else?if?(lp.rightMargin?<?(-mRightMargin/2))?{//往右拖拉??
  70. ????????????????????new?AsynMove().execute(new?Integer[]?{?-MOVE_WIDTH?});//?负数收缩??
  71. ????????????????}??
  72. ????????????}??
  73. ????????????return?mGestureDetector.onTouchEvent(event);???
  74. ????????}??
  75. ????};??
  76. ??
  77. ????/**?
  78. ?????*?定义收缩时的回调函数?
  79. [email protected]?
  80. ?????*/??
  81. ????public?void?setPanelClosedEvent(PanelClosedEvent?event)??
  82. ????{??
  83. ????????this.panelClosedEvent=event;??
  84. ????}??
  85. ??????
  86. ????/**?
  87. ?????*?定义展开时的回调函数?
  88. [email protected]?
  89. ?????*/??
  90. ????public?void?setPanelOpenedEvent(PanelOpenedEvent?event)??
  91. ????{??
  92. ????????this.panelOpenedEvent=event;??
  93. ????}??
  94. ??????
  95. ????/**?
  96. ?????*?把View放在Panel的Container?
  97. [email protected]?
  98. ?????*/??
  99. ????public?void?fillPanelContainer(View?v)??
  100. ????{??
  101. ????????panelContainer.addView(v);??
  102. ????}??
  103. ??????
  104. ????/**?
  105. ?????*?异步移动Panel?
  106. [email protected]?
  107. ?????*/??
  108. ????class?AsynMove?extends?AsyncTask<Integer,?Integer,?Void>?{??
  109. ??
  110. ????????@Override??
  111. ????????protected?Void?doInBackground(Integer...?params)?{??
  112. ????????????int?times;??
  113. ????????????if?(mRightMargin?%?Math.abs(params[0])?==?0)//?整除??
  114. ????????????????times?=?mRightMargin?/?Math.abs(params[0]);??
  115. ????????????else??
  116. ????????????????//?有余数??
  117. ????????????????times?=?mRightMargin?/?Math.abs(params[0])?+?1;??
  118. ??
  119. ????????????for?(int?i?=?0;?i?<?times;?i++)?{??
  120. ????????????????publishProgress(params);??
  121. ????????????????try?{??
  122. ????????????????????Thread.sleep(Math.abs(params[0]));??
  123. ????????????????}?catch?(InterruptedException?e)?{??
  124. ????????????????????//?TODO?Auto-generated?catch?block??
  125. ????????????????????e.printStackTrace();??
  126. ????????????????}??
  127. ????????????}??
  128. ????????????return?null;??
  129. ????????}??
  130. ??
  131. ????????@Override??
  132. ????????protected?void?onProgressUpdate(Integer...?params)?{??
  133. ????????????LayoutParams?lp?=?(LayoutParams)?Panel.this.getLayoutParams();??
  134. ????????????if?(params[0]?<?0)??
  135. ????????????????lp.rightMargin?=?Math.max(lp.rightMargin?+?params[0],??
  136. ????????????????????????(-mRightMargin));??
  137. ????????????else??
  138. ????????????????lp.rightMargin?=?Math.min(lp.rightMargin?+?params[0],?0);??
  139. ??
  140. ????????????if(lp.rightMargin==0?&&?panelOpenedEvent!=null){//展开之后??
  141. ????????????????panelOpenedEvent.onPanelOpened(Panel.this);//调用OPEN回调函数??
  142. ????????????}??
  143. ????????????else?if(lp.rightMargin==-(mRightMargin)?&&?panelClosedEvent!=null){//收缩之后??
  144. ????????????????panelClosedEvent.onPanelClosed(Panel.this);//调用CLOSE回调函数??
  145. ????????????}??
  146. ????????????Panel.this.setLayoutParams(lp);??
  147. ????????}??
  148. ????}??
  149. ??
  150. ????@Override??
  151. ????public?boolean?onDown(MotionEvent?e)?{??
  152. ????????mScrollX=0;??
  153. ????????mIsScrolling=false;??
  154. ????????return?false;??
  155. ????}??
  156. ??
  157. ????@Override??
  158. ????public?boolean?onSingleTapUp(MotionEvent?e)?{??
  159. ????????LayoutParams?lp?=?(LayoutParams)?Panel.this.getLayoutParams();??
  160. ????????if?(lp.rightMargin?<?0)//?CLOSE的状态??
  161. ????????????new?AsynMove().execute(new?Integer[]?{?MOVE_WIDTH?});//?正数展开??
  162. ????????else?if?(lp.rightMargin?>=?0)//?OPEN的状态??
  163. ????????????new?AsynMove().execute(new?Integer[]?{?-MOVE_WIDTH?});//?负数收缩??
  164. ????????return?false;??
  165. ????}??
  166. ??????
  167. ????@Override??
  168. ????public?boolean?onScroll(MotionEvent?e1,?MotionEvent?e2,?float?distanceX,??
  169. ????????????float?distanceY)?{??
  170. ????????mIsScrolling=true;??
  171. ????????mScrollX+=distanceX;??
  172. ??????????
  173. ????????LayoutParams?lp=(LayoutParams)?Panel.this.getLayoutParams();??
  174. ????????if?(lp.rightMargin?<?-1?&&?mScrollX?>?0)?{//往左拖拉??
  175. ????????????lp.rightMargin?=?Math.min((lp.rightMargin?+?(int)?mScrollX),0);??
  176. ????????????Panel.this.setLayoutParams(lp);??
  177. ????????????Log.e("onScroll",lp.rightMargin+"");??
  178. ????????}???
  179. ????????else?if?(lp.rightMargin?>?-(mRightMargin)?&&?mScrollX?<?0)?{//往右拖拉??
  180. ????????????lp.rightMargin?=?Math.max((lp.rightMargin?+?(int)?mScrollX),-mRightMargin);??
  181. ????????????Panel.this.setLayoutParams(lp);??
  182. ????????}??
  183. ??????????
  184. ????????if(lp.rightMargin==0?&&?panelOpenedEvent!=null){//展开之后??
  185. ????????????panelOpenedEvent.onPanelOpened(Panel.this);//调用OPEN回调函数??
  186. ????????}??
  187. ????????else?if(lp.rightMargin==-(mRightMargin)?&&?panelClosedEvent!=null){//收缩之后??
  188. ????????????panelClosedEvent.onPanelClosed(Panel.this);//调用CLOSE回调函数??
  189. ????????}??
  190. ????????Log.e("onScroll",lp.rightMargin+"");??
  191. ??????????
  192. ????????return?false;??
  193. ????}??
  194. ??????
  195. ????@Override??
  196. ????public?boolean?onFling(MotionEvent?e1,?MotionEvent?e2,?float?velocityX,??
  197. ????????????float?velocityY)?{return?false;}??
  198. ????@Override??
  199. ????public?void?onLongPress(MotionEvent?e)?{}??
  200. ????@Override??
  201. ????public?void?onShowPress(MotionEvent?e)?{}??
  202. ??
  203. }??
  204. </span>??


?

  相关解决方案