效果: 1:子控件跟着手指移动  2:快速拨动一下,根据拨动的速度 滑动过去  3:拖过头,放手后弹回去 
   但是用listView或者GridView又不好实现项目要求的其他效果..于是继承viewGroup实现以上效果。 
   既然要获取拨动速度,并以此滑动。首先想到了OnGestureListener 这个接口,实现这个接口并实现其onFling方法. 
  还要控制拖动。重写onTouchEvent方法,并在其中控制内容控件的拖动,反弹等效果 
这时候基本已经完成了。。。。测试了一下了,发现了一个问题,当手指点在viewGroup上 
进行 拖动是没问题的,但是在子控件上就不行了,这是事件响应的问题 那么还要做如面的处

理:实现onInterceptTouchEvent方法,判断是拖动事件时 ,将事件传递下去。

[java] view plaincopyprint?
  1. import java.util.List;
  2. import android.content.Context;
  3. import android.graphics.Color;
  4. import android.util.Log;
  5. import android.view.GestureDetector;
  6. import android.view.MotionEvent;
  7. import android.view.View;
  8. import android.view.ViewConfiguration;
  9. import android.view.ViewGroup;
  10. import android.view.GestureDetector.OnGestureListener;
  11. import android.widget.Button;
  12. import android.widget.ImageView;
  13. import android.widget.Scroller;
  14. import android.widget.Toast;
  15. import android.widget.ImageView.ScaleType;
  16. public class MyViewGroup extends ViewGroup implements OnGestureListener {
  17. private float mLastMotionY;// 最后点击的点
  18. private GestureDetector detector;
  19. int move = 0;// 移动距离
  20. int MAXMOVE = 850;// 最大允许的移动距离
  21. private Scroller mScroller;
  22. int up_excess_move = 0;// 往上多移的距离
  23. int down_excess_move = 0;// 往下多移的距离
  24. private final static int TOUCH_STATE_REST = 0;
  25. private final static int TOUCH_STATE_SCROLLING = 1;
  26. private int mTouchSlop;
  27. private int mTouchState = TOUCH_STATE_REST;
  28. Context mContext;
  29. public MyViewGroup(Context context) {
  30. super(context);
  31. mContext = context;
  32. // TODO Auto-generated constructor stub
  33. setBackgroundResource(R.drawable.pic);
  34. mScroller = new Scroller(context);
  35. detector = new GestureDetector(this);
  36. final ViewConfiguration configuration = ViewConfiguration.get(context);
  37. // 获得可以认为是滚动的距离
  38. mTouchSlop = configuration.getScaledTouchSlop();
  39. // 添加子View
  40. for (int i = 0; i < 48; i++) {
  41. final Button    MButton = new Button(context);
  42. MButton.setText("" + (i + 1));
  43. MButton.setOnClickListener(new OnClickListener() {
  44. public void onClick(View v) {
  45. // TODO Auto-generated method stub
  46. Toast.makeText(mContext, MButton.getText(), Toast.LENGTH_SHORT).show();
  47. }
  48. });
  49. addView(MButton);
  50. }
  51. }
  52. @Override
  53. public void computeScroll() {
  54. if (mScroller.computeScrollOffset()) {
  55. // 返回当前滚动X方向的偏移
  56. scrollTo(0, mScroller.getCurrY());
  57. postInvalidate();
  58. }
  59. }
  60. @Override
  61. public boolean onInterceptTouchEvent(MotionEvent ev) {
  62. final int action = ev.getAction();
  63. final float y = ev.getY();
  64. switch (ev.getAction())
  65. {
  66. case MotionEvent.ACTION_DOWN:
  67. mLastMotionY = y;
  68. mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST
  69. : TOUCH_STATE_SCROLLING;
  70. break;
  71. case MotionEvent.ACTION_MOVE:
  72. final int yDiff = (int) Math.abs(y - mLastMotionY);
  73. boolean yMoved = yDiff > mTouchSlop;
  74. // 判断是否是移动
  75. if (yMoved) {
  76. mTouchState = TOUCH_STATE_SCROLLING;
  77. }
  78. break;
  79. case MotionEvent.ACTION_UP:
  80. mTouchState = TOUCH_STATE_REST;
  81. break;
  82. }
  83. return mTouchState != TOUCH_STATE_REST;
  84. }
  85. @Override
  86. public boolean onTouchEvent(MotionEvent ev) {
  87. // final int action = ev.getAction();
  88. final float y = ev.getY();
  89. switch (ev.getAction())
  90. {
  91. case MotionEvent.ACTION_DOWN:
  92. if (!mScroller.isFinished()) {
  93. mScroller.forceFinished(true);
  94. move = mScroller.getFinalY();
  95. }
  96. mLastMotionY = y;
  97. break;
  98. case MotionEvent.ACTION_MOVE:
  99. if (ev.getPointerCount() == 1) {
  100. // 随手指 拖动的代码
  101. int deltaY = 0;
  102. deltaY = (int) (mLastMotionY - y);
  103. mLastMotionY = y;
  104. Log.d("move", "" + move);
  105. if (deltaY < 0) {
  106. // 下移
  107. // 判断上移 是否滑过头
  108. if (up_excess_move == 0) {
  109. if (move > 0) {
  110. int move_this = Math.max(-move, deltaY);
  111. move = move + move_this;
  112. scrollBy(0, move_this);
  113. } else if (move == 0) {// 如果已经是最顶端 继续往下拉
  114. Log.d("down_excess_move", "" + down_excess_move);
  115. down_excess_move = down_excess_move - deltaY / 2;// 记录下多往下拉的值
  116. scrollBy(0, deltaY / 2);
  117. }
  118. } else if (up_excess_move > 0)// 之前有上移过头
  119. {
  120. if (up_excess_move >= (-deltaY)) {
  121. up_excess_move = up_excess_move + deltaY;
  122. scrollBy(0, deltaY);
  123. } else {
  124. up_excess_move = 0;
  125. scrollBy(0, -up_excess_move);
  126. }
  127. }
  128. } else if (deltaY > 0) {
  129. // 上移
  130. if (down_excess_move == 0) {
  131. if (MAXMOVE - move > 0) {
  132. int move_this = Math.min(MAXMOVE - move, deltaY);
  133. move = move + move_this;
  134. scrollBy(0, move_this);
  135. } else if (MAXMOVE - move == 0) {
  136. if (up_excess_move <= 100) {
  137. up_excess_move = up_excess_move + deltaY / 2;
  138. scrollBy(0, deltaY / 2);
  139. }
  140. }
  141. } else if (down_excess_move > 0) {
  142. if (down_excess_move >= deltaY) {
  143. down_excess_move = down_excess_move - deltaY;
  144. scrollBy(0, deltaY);
  145. } else {
  146. down_excess_move = 0;
  147. scrollBy(0, down_excess_move);
  148. }
  149. }
  150. }
  151. }
  152. break;
  153. case MotionEvent.ACTION_UP:
  154. // 多滚是负数 记录到move里
  155. if (up_excess_move > 0) {
  156. // 多滚了 要弹回去
  157. scrollBy(0, -up_excess_move);
  158. invalidate();
  159. up_excess_move = 0;
  160. }
  161. if (down_excess_move > 0) {
  162. // 多滚了 要弹回去
  163. scrollBy(0, down_excess_move);
  164. invalidate();
  165. down_excess_move = 0;
  166. }
  167. mTouchState = TOUCH_STATE_REST;
  168. break;
  169. }
  170. return this.detector.onTouchEvent(ev);
  171. }
  172. int Fling_move = 0;
  173. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  174. float velocityY) {
  175. //随手指 快速拨动的代码
  176. Log.d("onFling", "onFling");
  177. if (up_excess_move == 0 && down_excess_move == 0) {
  178. int slow = -(int) velocityY * 3 / 4;
  179. mScroller.fling(0, move, 0, slow, 0, 0, 0, MAXMOVE);
  180. move = mScroller.getFinalY();
  181. computeScroll();
  182. }
  183. return false;
  184. }
  185. public boolean onDown(MotionEvent e) {
  186. // TODO Auto-generated method stub
  187. return true;
  188. }
  189. public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
  190. float distanceY) {
  191. return false;
  192. }
  193. public void onShowPress(MotionEvent e) {
  194. // // TODO Auto-generated method stub
  195. }
  196. public boolean onSingleTapUp(MotionEvent e) {
  197. // TODO Auto-generated method stub
  198. return false;
  199. }
  200. public void onLongPress(MotionEvent e) {
  201. // TODO Auto-generated method stub
  202. }
  203. @Override
  204. protected void onLayout(boolean changed, int l, int t, int r, int b) {
  205. // TODO Auto-generated method stub
  206. int childTop = 0;
  207. int childLeft = 0;
  208. final int count = getChildCount();
  209. for (int i = 0; i < count; i++) {
  210. final View child = getChildAt(i);
  211. if (child.getVisibility() != View.GONE) {
  212. child.setVisibility(View.VISIBLE);
  213. child.measure(r - l, b - t);
  214. child
  215. .layout(childLeft, childTop, childLeft + 80,
  216. childTop + 80);
  217. if (childLeft < 160) {
  218. childLeft += 80;
  219. } else {
  220. childLeft = 0;
  221. childTop += 80;
  222. }
  223. }
  224. }
  225. }
  226. }
 
[java] view plaincopyprint?
  1. import android.content.Context;
  2. import android.view.View;
  3. import android.view.ViewGroup;
  4. public class Workspace extends ViewGroup {
  5. public Workspace(Context context) {
  6. super(context);
  7. // TODO Auto-generated constructor stub
  8. addView(new MyViewGroup(context));
  9. }
  10. @Override
  11. protected void onLayout(boolean changed, int l, int t, int r, int b) {
  12. // TODO Auto-generated method stub
  13. final int count = getChildCount();
  14. for (int i = 0; i < count; i++) {
  15. final View child = getChildAt(i);
  16. child.measure(r - l, b - t);
  17. child.layout(0, 0, 320, 480);
  18. }
  19. }
  20. }
 
[java] view plaincopyprint?
  1. import android.app.Activity;
  2. import android.os.Bundle;
  3. public class MoveViewGroup extends Activity {
  4. /** Called when the activity is first created. */
  5. @Override
  6. public void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(new Workspace(this));
  9. }
  10. }


http://blog.csdn.net/ztp800201/article/details/14057695

自定义ViewGroup 实现拖动跟快速滚动的效果相关推荐

  1. android 自定义图片容器,Android应用开发中自定义ViewGroup视图容器的教程

    一.概述在写代码之前,我必须得问几个问题: 1.ViewGroup的职责是啥?ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属性, ...

  2. qq模板图片asqq_重要更新 电脑编辑规则、快速滚动、富文本图片、规则模板等十多项更新!...

    新方圆小棉袄,传说中的贴心小棉袄,宇宙无敌超级厉害. 记住我们的付费群(大佬众多):978260150,免费群:1101359539 1.方圆和海阔的规则导入和支付宝口令类似,将口令全部复制打开最新版 ...

  3. android 半圆滚动菜单,自定义控件:实现半圆滚动菜单效果

    前言 本自定义控件参考自鸿洋大神的自定义控件,基于原来的控件效果进行修改,着重实现了以下效果:位置自动修正以及滑动结束的回调.我们先来看看效果图: 上面的图片是一个ImageView,与控件无关,是为 ...

  4. 自定义RecyclerView支持快速滚动

    问题描述: RecyclerView自带快速滚动无法控制滚动条的长度唯一,也就是说随着item的增多,滚动条的长度会越变越小. 解决问题: 通过自定义RecyclerView来实现滚动条的长度不会因为 ...

  5. QQ 5.0侧滑HorizontalScrollView以及自定义ViewGroup

      一般侧滑的实现: 自定义的ViewGroup(menu+content) ouTouchEvent事件改变ViewGroup的LeftMargin. 大于菜单的一半显示,小于则隐藏(使用Scrol ...

  6. Android自定义ViewGroup第十二式之年年有鱼

    前言 先来看两张效果图: 哈哈,就是这样了. 前段时间在鸿神的群里看到有群友截了一张QQ空间的图,问它那个是怎么实现的: 在好友动态的列表中多了个Header,这个Header有一叠卡片的效果,上面的 ...

  7. android滚动条布局横向,Android自定义ViewGroup实现可滚动的横向布局(2)

    这里直接代码: package com.example.libingyuan.horizontallistview.ScrollViewGroup; import android.content.Co ...

  8. 自定义ViewGroup (2)支持滑动,并处理多指触摸可能产生的跳动问题

    2019独角兽企业重金招聘Python工程师标准>>> 昨天完成了一个支持设置margin,gravity,水平或者垂直排列的简单的自定义ViewGroup.但是它并不支持滑动,所以 ...

  9. android 自定义ViewGroup实现仿淘宝的商品详情页

    最近公司在新版本上有一个需要, 要在首页添加一个滑动效果, 具体就是仿照X宝的商品详情页, 拉到页面底部时有一个粘滞效果, 如下图 X东的商品详情页,如果用户继续向上拉的话就进入商品图文描述界面: 刚 ...

最新文章

  1. 使用Facade模式分析
  2. [原创]关于javax.servlet.ServletException: File [/loginController/getVerifCode.jsp] not found异常 解决方案
  3. tomcat出现5个using_当猫咪出现这5个迹象,主人就要给猫咪换猫粮了
  4. (翻译)Google Guava Cache
  5. [LUOGU]P1451 求细胞数量
  6. underscore源码剖析之整体架构
  7. java jsonfield_fastjson使用-- @JSONField使用(转)
  8. 20201023:力扣第37场双周赛(上)
  9. Eclipse用法和技巧九:自动添加try/catch块2
  10. 结对项目:黄金点游戏(何珠赵艳)
  11. ORA-06502: PL/SQL: numeric or value error: character to number conversion error 错误的解决方法...
  12. 力扣-692 前k个高频单词
  13. c#生成随机彩色验证码例子
  14. RS码编译matlab仿真2
  15. 关于身份证校验算法的一些想法
  16. btsync 文件同步工具 私有云盘
  17. 关于gopher协议的ssrf攻击
  18. 高等数学基础06:方向导数
  19. 数据库 SQL :数据库三大泛式简谈
  20. equestresponseservletContext

热门文章

  1. Java并发编程—为什么wait/notify操作要先获取到锁?
  2. 浅谈:数据结构之单链表,java代码演示单链表
  3. python网络爬虫之requests模块
  4. JS语言的基本构成、变量、数据类型
  5. openstack havana块存储Cinder磁盘加密方法研究
  6. 6月24日AppCan移动开发者大会礼品清单遭泄露
  7. spring入门:beans.xml不提示、别名、创建对象的三种方式
  8. JAAS:灵活的Java安全机制[转]
  9. zookeeper学习一
  10. 2018-2019 20165227《信息安全系统设计基础》第三周学习总结