自定义ViewGroup 实现拖动跟快速滚动的效果
效果: 1:子控件跟着手指移动 2:快速拨动一下,根据拨动的速度 滑动过去 3:拖过头,放手后弹回去
但是用listView或者GridView又不好实现项目要求的其他效果..于是继承viewGroup实现以上效果。
既然要获取拨动速度,并以此滑动。首先想到了OnGestureListener 这个接口,实现这个接口并实现其onFling方法.
还要控制拖动。重写onTouchEvent方法,并在其中控制内容控件的拖动,反弹等效果
这时候基本已经完成了。。。。测试了一下了,发现了一个问题,当手指点在viewGroup上
进行 拖动是没问题的,但是在子控件上就不行了,这是事件响应的问题 那么还要做如面的处
理:实现onInterceptTouchEvent方法,判断是拖动事件时 ,将事件传递下去。
- import java.util.List;
- import android.content.Context;
- import android.graphics.Color;
- import android.util.Log;
- import android.view.GestureDetector;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.ViewConfiguration;
- import android.view.ViewGroup;
- import android.view.GestureDetector.OnGestureListener;
- import android.widget.Button;
- import android.widget.ImageView;
- import android.widget.Scroller;
- import android.widget.Toast;
- import android.widget.ImageView.ScaleType;
- public class MyViewGroup extends ViewGroup implements OnGestureListener {
- private float mLastMotionY;// 最后点击的点
- private GestureDetector detector;
- int move = 0;// 移动距离
- int MAXMOVE = 850;// 最大允许的移动距离
- private Scroller mScroller;
- int up_excess_move = 0;// 往上多移的距离
- int down_excess_move = 0;// 往下多移的距离
- private final static int TOUCH_STATE_REST = 0;
- private final static int TOUCH_STATE_SCROLLING = 1;
- private int mTouchSlop;
- private int mTouchState = TOUCH_STATE_REST;
- Context mContext;
- public MyViewGroup(Context context) {
- super(context);
- mContext = context;
- // TODO Auto-generated constructor stub
- setBackgroundResource(R.drawable.pic);
- mScroller = new Scroller(context);
- detector = new GestureDetector(this);
- final ViewConfiguration configuration = ViewConfiguration.get(context);
- // 获得可以认为是滚动的距离
- mTouchSlop = configuration.getScaledTouchSlop();
- // 添加子View
- for (int i = 0; i < 48; i++) {
- final Button MButton = new Button(context);
- MButton.setText("" + (i + 1));
- MButton.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Toast.makeText(mContext, MButton.getText(), Toast.LENGTH_SHORT).show();
- }
- });
- addView(MButton);
- }
- }
- @Override
- public void computeScroll() {
- if (mScroller.computeScrollOffset()) {
- // 返回当前滚动X方向的偏移
- scrollTo(0, mScroller.getCurrY());
- postInvalidate();
- }
- }
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- final int action = ev.getAction();
- final float y = ev.getY();
- switch (ev.getAction())
- {
- case MotionEvent.ACTION_DOWN:
- mLastMotionY = y;
- mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST
- : TOUCH_STATE_SCROLLING;
- break;
- case MotionEvent.ACTION_MOVE:
- final int yDiff = (int) Math.abs(y - mLastMotionY);
- boolean yMoved = yDiff > mTouchSlop;
- // 判断是否是移动
- if (yMoved) {
- mTouchState = TOUCH_STATE_SCROLLING;
- }
- break;
- case MotionEvent.ACTION_UP:
- mTouchState = TOUCH_STATE_REST;
- break;
- }
- return mTouchState != TOUCH_STATE_REST;
- }
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- // final int action = ev.getAction();
- final float y = ev.getY();
- switch (ev.getAction())
- {
- case MotionEvent.ACTION_DOWN:
- if (!mScroller.isFinished()) {
- mScroller.forceFinished(true);
- move = mScroller.getFinalY();
- }
- mLastMotionY = y;
- break;
- case MotionEvent.ACTION_MOVE:
- if (ev.getPointerCount() == 1) {
- // 随手指 拖动的代码
- int deltaY = 0;
- deltaY = (int) (mLastMotionY - y);
- mLastMotionY = y;
- Log.d("move", "" + move);
- if (deltaY < 0) {
- // 下移
- // 判断上移 是否滑过头
- if (up_excess_move == 0) {
- if (move > 0) {
- int move_this = Math.max(-move, deltaY);
- move = move + move_this;
- scrollBy(0, move_this);
- } else if (move == 0) {// 如果已经是最顶端 继续往下拉
- Log.d("down_excess_move", "" + down_excess_move);
- down_excess_move = down_excess_move - deltaY / 2;// 记录下多往下拉的值
- scrollBy(0, deltaY / 2);
- }
- } else if (up_excess_move > 0)// 之前有上移过头
- {
- if (up_excess_move >= (-deltaY)) {
- up_excess_move = up_excess_move + deltaY;
- scrollBy(0, deltaY);
- } else {
- up_excess_move = 0;
- scrollBy(0, -up_excess_move);
- }
- }
- } else if (deltaY > 0) {
- // 上移
- if (down_excess_move == 0) {
- if (MAXMOVE - move > 0) {
- int move_this = Math.min(MAXMOVE - move, deltaY);
- move = move + move_this;
- scrollBy(0, move_this);
- } else if (MAXMOVE - move == 0) {
- if (up_excess_move <= 100) {
- up_excess_move = up_excess_move + deltaY / 2;
- scrollBy(0, deltaY / 2);
- }
- }
- } else if (down_excess_move > 0) {
- if (down_excess_move >= deltaY) {
- down_excess_move = down_excess_move - deltaY;
- scrollBy(0, deltaY);
- } else {
- down_excess_move = 0;
- scrollBy(0, down_excess_move);
- }
- }
- }
- }
- break;
- case MotionEvent.ACTION_UP:
- // 多滚是负数 记录到move里
- if (up_excess_move > 0) {
- // 多滚了 要弹回去
- scrollBy(0, -up_excess_move);
- invalidate();
- up_excess_move = 0;
- }
- if (down_excess_move > 0) {
- // 多滚了 要弹回去
- scrollBy(0, down_excess_move);
- invalidate();
- down_excess_move = 0;
- }
- mTouchState = TOUCH_STATE_REST;
- break;
- }
- return this.detector.onTouchEvent(ev);
- }
- int Fling_move = 0;
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {
- //随手指 快速拨动的代码
- Log.d("onFling", "onFling");
- if (up_excess_move == 0 && down_excess_move == 0) {
- int slow = -(int) velocityY * 3 / 4;
- mScroller.fling(0, move, 0, slow, 0, 0, 0, MAXMOVE);
- move = mScroller.getFinalY();
- computeScroll();
- }
- return false;
- }
- public boolean onDown(MotionEvent e) {
- // TODO Auto-generated method stub
- return true;
- }
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
- float distanceY) {
- return false;
- }
- public void onShowPress(MotionEvent e) {
- // // TODO Auto-generated method stub
- }
- public boolean onSingleTapUp(MotionEvent e) {
- // TODO Auto-generated method stub
- return false;
- }
- public void onLongPress(MotionEvent e) {
- // TODO Auto-generated method stub
- }
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- // TODO Auto-generated method stub
- int childTop = 0;
- int childLeft = 0;
- final int count = getChildCount();
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
- if (child.getVisibility() != View.GONE) {
- child.setVisibility(View.VISIBLE);
- child.measure(r - l, b - t);
- child
- .layout(childLeft, childTop, childLeft + 80,
- childTop + 80);
- if (childLeft < 160) {
- childLeft += 80;
- } else {
- childLeft = 0;
- childTop += 80;
- }
- }
- }
- }
- }
- import android.content.Context;
- import android.view.View;
- import android.view.ViewGroup;
- public class Workspace extends ViewGroup {
- public Workspace(Context context) {
- super(context);
- // TODO Auto-generated constructor stub
- addView(new MyViewGroup(context));
- }
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- // TODO Auto-generated method stub
- final int count = getChildCount();
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
- child.measure(r - l, b - t);
- child.layout(0, 0, 320, 480);
- }
- }
- }
- import android.app.Activity;
- import android.os.Bundle;
- public class MoveViewGroup extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(new Workspace(this));
- }
- }
http://blog.csdn.net/ztp800201/article/details/14057695
自定义ViewGroup 实现拖动跟快速滚动的效果相关推荐
- android 自定义图片容器,Android应用开发中自定义ViewGroup视图容器的教程
一.概述在写代码之前,我必须得问几个问题: 1.ViewGroup的职责是啥?ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属性, ...
- qq模板图片asqq_重要更新 电脑编辑规则、快速滚动、富文本图片、规则模板等十多项更新!...
新方圆小棉袄,传说中的贴心小棉袄,宇宙无敌超级厉害. 记住我们的付费群(大佬众多):978260150,免费群:1101359539 1.方圆和海阔的规则导入和支付宝口令类似,将口令全部复制打开最新版 ...
- android 半圆滚动菜单,自定义控件:实现半圆滚动菜单效果
前言 本自定义控件参考自鸿洋大神的自定义控件,基于原来的控件效果进行修改,着重实现了以下效果:位置自动修正以及滑动结束的回调.我们先来看看效果图: 上面的图片是一个ImageView,与控件无关,是为 ...
- 自定义RecyclerView支持快速滚动
问题描述: RecyclerView自带快速滚动无法控制滚动条的长度唯一,也就是说随着item的增多,滚动条的长度会越变越小. 解决问题: 通过自定义RecyclerView来实现滚动条的长度不会因为 ...
- QQ 5.0侧滑HorizontalScrollView以及自定义ViewGroup
一般侧滑的实现: 自定义的ViewGroup(menu+content) ouTouchEvent事件改变ViewGroup的LeftMargin. 大于菜单的一半显示,小于则隐藏(使用Scrol ...
- Android自定义ViewGroup第十二式之年年有鱼
前言 先来看两张效果图: 哈哈,就是这样了. 前段时间在鸿神的群里看到有群友截了一张QQ空间的图,问它那个是怎么实现的: 在好友动态的列表中多了个Header,这个Header有一叠卡片的效果,上面的 ...
- android滚动条布局横向,Android自定义ViewGroup实现可滚动的横向布局(2)
这里直接代码: package com.example.libingyuan.horizontallistview.ScrollViewGroup; import android.content.Co ...
- 自定义ViewGroup (2)支持滑动,并处理多指触摸可能产生的跳动问题
2019独角兽企业重金招聘Python工程师标准>>> 昨天完成了一个支持设置margin,gravity,水平或者垂直排列的简单的自定义ViewGroup.但是它并不支持滑动,所以 ...
- android 自定义ViewGroup实现仿淘宝的商品详情页
最近公司在新版本上有一个需要, 要在首页添加一个滑动效果, 具体就是仿照X宝的商品详情页, 拉到页面底部时有一个粘滞效果, 如下图 X东的商品详情页,如果用户继续向上拉的话就进入商品图文描述界面: 刚 ...
最新文章
- 使用Facade模式分析
- [原创]关于javax.servlet.ServletException: File [/loginController/getVerifCode.jsp] not found异常 解决方案
- tomcat出现5个using_当猫咪出现这5个迹象,主人就要给猫咪换猫粮了
- (翻译)Google Guava Cache
- [LUOGU]P1451 求细胞数量
- underscore源码剖析之整体架构
- java jsonfield_fastjson使用-- @JSONField使用(转)
- 20201023:力扣第37场双周赛(上)
- Eclipse用法和技巧九:自动添加try/catch块2
- 结对项目:黄金点游戏(何珠赵艳)
- ORA-06502: PL/SQL: numeric or value error: character to number conversion error 错误的解决方法...
- 力扣-692 前k个高频单词
- c#生成随机彩色验证码例子
- RS码编译matlab仿真2
- 关于身份证校验算法的一些想法
- btsync 文件同步工具 私有云盘
- 关于gopher协议的ssrf攻击
- 高等数学基础06:方向导数
- 数据库 SQL :数据库三大泛式简谈
- equestresponseservletContext
热门文章
- Java并发编程—为什么wait/notify操作要先获取到锁?
- 浅谈:数据结构之单链表,java代码演示单链表
- python网络爬虫之requests模块
- JS语言的基本构成、变量、数据类型
- openstack havana块存储Cinder磁盘加密方法研究
- 6月24日AppCan移动开发者大会礼品清单遭泄露
- spring入门:beans.xml不提示、别名、创建对象的三种方式
- JAAS:灵活的Java安全机制[转]
- zookeeper学习一
- 2018-2019 20165227《信息安全系统设计基础》第三周学习总结