[转] android自定义布局中的平滑移动
无意中搜索到这篇文章,大概扫了一眼,知道是篇好文,先转载记录下来学习!
文章主要讲的是自定义view的写法心得。
转自:http://www.apkbus.com/android-48445-1-1.html
在android应用程序的开发过程中,相信我们很多人都想把应用的交互做的比较绚丽,比如让界面切换平滑的滚动,还有热度灰常高的伪3D等界面效果,通常情况下,系统提供的应用在特效这方面只能为我们提供简单的动画接口,所以要想实现比较酷炫的效果还是要自己去开发布局控件(即所谓的自定义View、ViewGroup)。小弟也经常做一些自定义的控件,最近工作比较清闲,所以便将自己对自定义布局控件的一些心得写出来,权当是自己的学习笔记了,各位高手看到了可以忽略。下面就我最近工作中遇到的一个自定义控件开发做一些简单的介绍,其实那个地方原本可以用ScrollView解决很大一部分问题的,但有一些效果确实需要对控件进行重新定义,在继承ScrollView开发中仍然会遇到一些ScrollView自身的限制,所以就仿照ScrollView自己做了一个控件。在其中遇到了一些问题自然就是像ScrollView中拖动的效果(比如快速拖动在手指离开屏幕时控件依旧会由于惯性继续滑动一段距离后才会停止运动),所以就对这个东东做了一下仔细的研究,虽然以前也做过类似的开发,这次由于时间比较充裕,所以将开发中遇到的一些问题都一一记录了下来。下面开始正题:
自定义布局控件自然是要继承某个View或ViewGroup
由于是根据项目的开发来写的这篇博客,所以我就以自定义布局控件(ViewGroup)来做介绍了。
开发一个自定义的ViewGroup自然是要继承ViewGroup类了,在继承这个类之后必须要重写的方法就是
onLayout(boolean changed, int l, int t, int r, int b)
另外至少要有一个构造方法,我个人习惯重写那个有两个参数的构造方法(XXX(Context context, AttributeSet attrs)),因为有了这个构造方法就可以在xml布局文件里使用这个类了。
如果想要对这个布局控件以及其子控件的尺寸进行精确的控制那就要重写下面这个方法了
onMeasure(int widthMeasureSpec, int heightMeasureSpec)
这个方法从字面理解就是估算控件的尺寸大小了,关于这个方法的详细说明引用一下另一位童鞋的文章http://www.eoeandroid.com/thread-102385-1-1.html,这里就不详细介绍了
下面开始介绍关于如何让自定义的控件进行平滑的移动,并能够根据手势的情况产生惯性滑动的效果
先介绍一下开发这种滑动效果需要用到的各种工具类:
android.view.VelocityTracker
android.view.Scroller
android.view.ViewConfiguration
VelocityTracker从字面意思理解那就是速度追踪器了,在滑动效果的开发中通常都是要使用该类计算出当前手势的初始速度(不知道我这么理解是否正确,对应的方法是velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity))并通过getXVelocity或getYVelocity方法得到对应的速度值initialVelocity,并将获得的速度值传递给Scroller类的fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY) 方法进行控件滚动时各种位置坐标数值的计算,API中对fling 方法的解释是基于一个fling手势开始滑动动作,滑动的距离将由所获得的初始速度initialVelocity来决定。关于ViewConfiguration 的使用主要使用了该类的下面三个方法:
configuration.getScaledTouchSlop() //获得能够进行手势滑动的距离
configuration.getScaledMinimumFlingVelocity()//获得允许执行一个fling手势动作的最小速度值
configuration.getScaledMaximumFlingVelocity()//获得允许执行一个fling手势动作的最大速度值
需要重写的方法至少要包含下面几个方法:
onTouchEvent(MotionEvent event)//有手势操作必然少不了这个方法了
computeScroll()//必要时由父控件调用请求或通知其一个子节点需要更新它的mScrollX和mScrollY的值。典型的例子就是在一个子节点正在使用Scroller进行滑动动画时将会被执行。所以,从该方法的注释来看,继承这个方法的话一般都会有Scroller对象出现。
在往下就是介绍比较具体的开发思路
首先我们要初始化一些变量,其中的多数代码已经在上面做出介绍了
void init(Context context) {mScroller = new Scroller(getContext());setFocusable(true);setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);setWillNotDraw(false);final ViewConfiguration configuration = ViewConfiguration.get(context);mTouchSlop = configuration.getScaledTouchSlop();mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();}
public void fling(int velocityY) {if (getChildCount() > 0) {mScroller.fling(getScrollX(), getScrollY(), 0, velocityY, 0, 0, 0,maxScrollEdge);final boolean movingDown = velocityY > 0;awakenScrollBars(mScroller.getDuration());invalidate();} }
private void obtainVelocityTracker(MotionEvent event) {if (mVelocityTracker == null) {mVelocityTracker = VelocityTracker.obtain();}mVelocityTracker.addMovement(event); }private void releaseVelocityTracker() {if (mVelocityTracker != null) {mVelocityTracker.recycle();mVelocityTracker = null;} }
public boolean onTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN&& event.getEdgeFlags() != 0) {return false;}obtainVelocityTracker(event);final int action = event.getAction();final float x = event.getX();final float y = event.getY();switch (action) {case MotionEvent.ACTION_DOWN:LogUtil.log(TAG, "ACTION_DOWN#currentScrollY:" + getScrollY()+ ", mLastMotionY:" + mLastMotionY,LogUtil.LOG_E);if (!mScroller.isFinished()) {mScroller.abortAnimation();}mLastMotionY = y;break;case MotionEvent.ACTION_MOVE:final int deltaY = (int) (mLastMotionY - y);mLastMotionY = y;if (deltaY < 0) {if (getScrollY() > 0) {scrollBy(0, deltaY);} } else if (deltaY > 0) {mIsInEdge = getScrollY() <= childTotalHeight - height;if (mIsInEdge) {scrollBy(0, deltaY);}}break;case MotionEvent.ACTION_UP:final VelocityTracker velocityTracker = mVelocityTracker;velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);int initialVelocity = (int) velocityTracker.getYVelocity();if ((Math.abs(initialVelocity) > mMinimumVelocity)&& getChildCount() > 0) {fling(-initialVelocity);}releaseVelocityTracker();break;}return true;}
public void computeScroll() {if (mScroller.computeScrollOffset()) {int scrollX = getScrollX();int scrollY = getScrollY();int oldX = scrollX;int oldY = scrollY;int x = mScroller.getCurrX();int y = mScroller.getCurrY();scrollX = x;scrollY = y;scrollY = scrollY + 10;scrollTo(scrollX, scrollY);postInvalidate();} }
public void scrollTo(int x, int y) {if (mScrollX != x || mScrollY != y) {int oldX = mScrollX;int oldY = mScrollY;mScrollX = x;mScrollY = y;onScrollChanged(mScrollX, mScrollY, oldX, oldY);if (!awakenScrollBars()) {invalidate();}}}
转载于:https://www.cnblogs.com/supersugar/archive/2012/08/08/2628602.html
[转] android自定义布局中的平滑移动相关推荐
- android 自定义布局 根据布局获取类,android自定义布局中的平滑移动之ViewGroup实现...
在android应用程序的开发过程中,相信我们很多人都想把应用的交互做的比较绚丽,比如让界面切换平滑的滚动,还有热度灰常高的伪3D等界面效果,通常情况下,系统提供的应用在特效这方面只能为我们提供简单的 ...
- android自定义布局实现优惠券效果
最近需要实现一个凹凸效果的拟物化优惠券效果,我一看,本来想用.9图片做背景实现的,虽说图片做背景实现省事儿方便,但是能用代码实现最好不过了,最终我还是选择了用代码来实现,于是有了下文. 最终效果图 d ...
- 名片夹android布局代码,Android自定义布局实现仿qq侧滑部分代码
自定义布局实现仿qq侧滑部分Android代码,供大家参考,具体内容如下 实现说明: 通过自定义布局实现: SlidingLayout继承于 HorizontalScrollView /** * Cr ...
- android 自定义布局 根据布局获取类,阿里高级Android面试题解析:Android自定义View—布局过程的自定义...
自定义分三部分绘制.布局和触摸反馈,本篇主要讲的布局过程的自定义 布局过程的含义 布局过程,就是程序在运行时利用布局文件的代码来计算出实际尺寸的过程. 布局过程的工作内容 两个阶段:测量阶段和布局阶段 ...
- android仿qq布局,Android自定义布局实现仿qq侧滑部分代码
自定义布局实现仿qq侧滑部分android代码,供大家参考,具体内容如下 实现说明: 通过自定义布局实现: slidinglayout继承于 horizontalscrollview /** * cr ...
- android 自定义布局 attribute·,android 自定义控件之xml---- attributeset attrs
主要是说明android 自定义控件的在布局代码中设置属性,如何自定义attributeset ,和在控件中如何获取到xml布局中设置的属性值,不是想了解这方面的请略过...不浪费大家时间 1.首先添 ...
- Android 自定义View中坐标点的理解学习(一)
本文主要是记录学习自定义view中看到的资料,为了方便记忆做了保存整理便于自己学习也方便其他Android开发爱好者学习,参考资料看底部链接. 一.getLocationInWindow和getLoc ...
- 从零开始学android开发-布局中 layout_gravity、gravity、orientation、layout_weight
线性布局中,有 4 个及其重要的参数,直接决定元素的布局和位置,这四个参数是 android:layout_gravity ( 是本元素相对于父元素的重力方向 ) android:gravity (是 ...
- android控件位置居中,Android 的布局中如何使控件居中
首先要分两种不同情况,在两种不同的布局方式下:LinearLayout 和RelativeLayout 1. LinearLayout a). android:layout_gravity=" ...
- android toast设置布局,Android 自定义布局的Toast
项目开发经常用到自定义布局的Toast,写一个Toast工具类需要用的地方直接调用showText public class KdToast extends Toast { private stati ...
最新文章
- TCP/IP详解--学习笔记(2)-数据链路层
- C#、.Net经典面试题目及答案
- 【小白学习C++ 教程】一、Vscode和 Visual stdudio配置C++环境
- vim 的寄存器/剪贴板
- immutable.js笔记
- C语言整数与字符串相互转换
- 简化java_Java泛型太复杂了?如何简化?
- java ftl crud_使用JDBC完成CRUD(增删改查)
- Java1.8安装win10_java1.8环境配置+win10系统
- Unicode字符集和多字节字符集
- 2021年高压电工考试题及高压电工模拟考试
- 微信小程序使用赞赏码功能
- Thread线程中的stop方法过时问题
- 【ABAP】 Smartforms 字符串中上标/下标打印实现
- Metric Learning详解(附带NCA算法)
- 情感分析textblob--英文分析
- Chrome 开发者工具新功能-网络面板新增载荷(Payload)边栏
- js ,DOM节点,制作点名器
- Haproxy基础知识 -运维小结
- linux lsof命令和ps的,Linux 中lsof 命令的使用