android自定义View-垂直滚动的TextView
其实要让TextView能够滚动,可以使用ScrollView/HorizontalScrollView或者设置ScrollingMovementMethod来实现。
点击查看:android实现TextView垂直或水平滚动
下面自定义垂直滚动的TextView,主要是用来学习Scroller的使用。关于ScrollTextView的实现,可以看下面的介绍和源码。
package com.orgcent.demo.view; import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.VelocityTracker;import android.view.ViewConfiguration;import android.view.animation.DecelerateInterpolator;import android.widget.Scroller;import android.widget.TextView;/** * 配置android:scrollbars="vertical",启用垂直滚动条 * * 实现水平滚动就是修改mScrollX,可参考HorizontalScrollView * * 滚动原理: 在绘制前对画布进行偏移操作 * * 下面是View的绘制机制: * |- view.computeScroll() --用来对mScrollX/Y进行修改。由于在绘制前调用,可调用invalite()来触发 * |- canvas.translate(-mScrollX,-mScrollY) --偏移画布 * |- view.draw() --绘制 * * 上述内容可以在View.buildDrawingCache()或ViewGroup.dispatchDraw()->drawChild()中找到.直接查看方法名即可 * * 滚动帮助类: * Scroller --用来计算滚动后的偏移值.具体请参考ScrollView和HorizontalScrollView * VelocityTracker --速度计算类。根据fling时的按下、抬起动作,计算滚动初速度 * * ScrollTextView--流程解析: * 1、onTouchEvent() --使用Scroller来计算滚动偏移值 * 2、重写computeScroll() --对View的mScrollY进行修改, 此处控制滚动范围 * * 滚动范围: * 最小值:0 * 最大值:所有文本高度+内边距-View高度。也就是超出屏幕的文本高度*/public class ScrollTextView extends TextView {private Scroller mScroller;private int mTouchSlop;private int mMinimumVelocity;private int mMaximumVelocity; private float mLastMotionY;private boolean mIsBeingDragged;private VelocityTracker mVelocityTracker;private int mActivePointerId = INVALID_POINTER; private static final int INVALID_POINTER = -1; public ScrollTextView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle); initView(); } public ScrollTextView(Context context, AttributeSet attrs) {super(context, attrs); initView(); } public ScrollTextView(Context context) {super(context); initView(); } private void initView() {final Context cx = getContext(); //设置滚动减速器,在fling中会用到 mScroller = new Scroller(cx,new DecelerateInterpolator(0.5f));final ViewConfiguration configuration = ViewConfiguration.get(cx); mTouchSlop = configuration.getScaledTouchSlop(); mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); } /** * 此方法为最后机会来修改mScrollX,mScrollY. * 这方法后将根据mScrollX,mScrollY来偏移Canvas已实现内容滚动*/ @Overridepublic void computeScroll() { super.computeScroll(); final Scroller scroller = mScroller;if(scroller.computeScrollOffset()) { //正在滚动,让view滚动到当前位置 int scrollY = scroller.getCurrY();final int maxY = (getLineCount() * getLineHeight() + getPaddingTop() + getPaddingBottom()) - getHeight();boolean toEdge = scrollY < 0 || scrollY > maxY;if(scrollY < 0) scrollY = 0;else if(scrollY > maxY) scrollY = maxY; /* *下面等同于: * mScrollY = scrollY; * awakenScrollBars(); //显示滚动条,必须在xml中配置。 * postInvalidate(); */ scrollTo(0, scrollY);if(toEdge) //移到两端,由于位置没有发生变化,导致滚动条不显示 awakenScrollBars(); } } public void fling(int velocityY) {final int maxY = (getLineCount() * getLineHeight() + getPaddingTop() + getPaddingBottom()) - getHeight(); mScroller.fling(getScrollX(), getScrollY(), 0, velocityY, 0, 0, 0, Math.max(0, maxY)); //刷新,让父控件调用computeScroll() invalidate(); } @Overridepublic boolean onTouchEvent(MotionEvent ev) {/* * 事件处理方式:先自己处理后交给父类处理。 * PS:方式不同,可能导致效果不同。请根据需求自行修改。*/boolean handled = false;final int contentHeight = getLineCount() * getLineHeight();if(contentHeight > getHeight()) { handled = processScroll(ev); } return handled | super.onTouchEvent(ev); } private boolean processScroll(MotionEvent ev) {boolean handled = false;if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); //帮助类,用来在fling时计算移动初速度 final int action = ev.getAction(); switch (action) {case MotionEvent.ACTION_DOWN: {if(!mScroller.isFinished()) { mScroller.forceFinished(true); } mLastMotionY = ev.getY(); mActivePointerId = ev.getPointerId(0); mIsBeingDragged = true; handled = true;break; }case MotionEvent.ACTION_MOVE: {final int pointerId = mActivePointerId;if(mIsBeingDragged && INVALID_POINTER != pointerId) {final int pointerIndex = ev.findPointerIndex(pointerId);final float y = ev.getY(pointerIndex);int deltaY = (int) (mLastMotionY - y); if(Math.abs(deltaY) > mTouchSlop) { //移动距离(正负代表方向)必须大于ViewConfiguration设置的默认值 mLastMotionY = y; /* * 默认滚动时间为250ms,建议立即滚动,否则滚动效果不明显 * 或者直接使用scrollBy(0, deltaY);*/ mScroller.startScroll(getScrollX(), getScrollY(), 0, deltaY, 0); invalidate(); handled = true; } }break; }case MotionEvent.ACTION_UP: {final int pointerId = mActivePointerId;if(mIsBeingDragged && INVALID_POINTER != pointerId) {final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);int initialVelocity = (int) velocityTracker.getYVelocity(pointerId); if(Math.abs(initialVelocity) > mMinimumVelocity) { fling(-initialVelocity); } mActivePointerId = INVALID_POINTER; mIsBeingDragged = false; if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } handled = true; }break; } }return handled; } }
测试DEMO: 点击查看
转: http://orgcent.com/android-custom-vertical-scroll-textview/
转载于:https://www.cnblogs.com/shanzei/archive/2012/03/28/2421179.html
android自定义View-垂直滚动的TextView相关推荐
- Android自定义view,圆形的TextView,并通过xml设置属性,AttributeSet中取值
Android自定义view设置xml属性 一个圆形的自定义TextView,通过xml来设置背景颜色的属性 values/attrs <declare-styleable name=" ...
- Android自定义View精品(LimitScrollerView-仿天猫广告栏上下滚动效果)
版权声明:本文为openXu原创文章[openXu的博客],未经博主允许不得以任何形式转载 文章目录 1.分析 2.定义组合控件布局 3.继承最外层控件 4.自定义属性 5.重写onMeasure 6 ...
- [Android]自定义View带效果的滚动数字
[Android]自定义View带效果的滚动数字 @Author GQ 2016年07月29日 一个可以让数字滚动的View,可以自定义参数,是想要的那种效果! 原文github地址 效果图 Andr ...
- Android 自定义View(四)实现股票自选列表滑动效果
一.前言 Android 开发过程中自定义 View 真的是无处不在,随随便便一个 UI 效果,都会用到自定义 View.前面三篇文章已经讲过自定义 View 的一些案例效果,相关类和 API,还有事 ...
- 【朝花夕拾】Android自定义View之(一)手把手教你看懂View绘制流程——向源码要答案
前言 原文:Android自定义View之(一)手把手教你看懂View绘制流程--向源码要答案 View作为整个app的颜值担当,在Android体系中占有重要的地位.深入理解Android View ...
- Android 自定义View合集
http://blog.csdn.net/u011507982/article/details/51199644 自定义控件学习 https://github.com/GcsSloop/Androi ...
- Android自定义View绘制流程
Android视图层次结构简介 在介绍View绘制流程之前,咱们先简单介绍一下Android视图层次结构以及DecorView,因为View的绘制流程的入口和DecorView有着密切的联系. 我们平 ...
- Android自定义view之基础知识
Android自定义view之基础知识 虽然Android已经自带了很多实用的view和layout,加以调教能实现很美观的界面,但是有一些情况下,需要实现特殊的界面效果,比如我们比较熟悉的各种播放器 ...
- Android 自定义View
[Android 自定义View] Android 自定义View 自定义View基础 自定义TextView 继承View重写onDraw方法 View的构造方法 自定义属性 创建attrsxml文 ...
最新文章
- hdu1042 java_N! hdu1042 | 学步园
- oracle loder nextval,ORA-07445: 出现异常错误: 核心转储
- Missing artifact log4j:log4j:bundle:1.2.17
- 【渝粤题库】陕西师范大学201981教育统计与测量 作业 (专升本、高起本)
- “约见”面试官系列之常见面试题第七篇说说Vue的生命周期(建议收藏)
- [C++] 哈希计数
- java 多线程同步 通过实现Runnable的示例
- 11-6渐变的用途和设定技巧
- zipkin使用_我的Spring Cloud(十):Zipkin 服务跟踪
- MyBatis3源码解析(3)查询语句执行
- python怎么使用-Python中__all__作用何在以及如何使用?
- MP算法和OMP算法及其思想与实现
- 科睿唯安官网更新SCI期刊列表,慎投2月已被剔除期刊
- 【墙裂推荐】二维码生成器哪个好?
- 微信小游戏保存自定义分享图到相册实例
- 使用旋转动画实现刻度表
- MySQL数据库灵魂拷问
- linux电脑访问android手机存储
- 基于STM32设计的智能家居控制系统设计_语音+环境检测(OneNet)_2022
- 【十万个BUG】npx mrm lint-staged报错