`
梦想家dream
  • 浏览: 61821 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

Android自定义控件--1(TextView跑马灯效果)

阅读更多
  N久没有跟新了,最近做的银行项目中的一个自定义控件(用于状态栏欢迎语句+柜员信息的滚动,简单点说就是TextView跑马灯效果)
package com.hacheng.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;

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已实现内容滚动
	 */
	@Override
	public 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();
	}

	@Override
	public 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;
	}
}


layout中引用:
 <com.hacheng.view.ScrollTextView
            android:id="@+id/scrollview"
            android:layout_width="750px"
            android:layout_height="48px"
            android:ellipsize="marquee"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:lines="1"
            android:marqueeRepeatLimit="marquee_forever"
            android:scrollHorizontally="true"
            android:singleLine="true"
            android:text="欢迎光临中国某某银行!柜员号:25645 地区号:658978"
            android:textSize="38dp" >
        </com.hacheng.view.ScrollTextView>


源码下载请戳这里:
分享到:
评论

相关推荐

    Android中继承TextView实现文字的跑马灯效果

    Android中继承TextView实现文字的跑马灯效果,详细了解请移步http://blog.csdn.net/zxc514257857/article/details/70184606

    TextView实现跑马灯效果

    好像跑马灯这种效果已经不用咱们来实现了 呵呵 不过有一点 如果文字不过长 在组件的范围内 还想要跑马灯的效果怎么办呢 当然的自己自定义啦 那还能怎么做 哈哈 "&gt;android:ellipsize设置当文字过长时 该控件该如何...

    Android——自定义控件(跑马灯实例)

    人生中第一篇博客便是关于TextView跑马灯的实现,但是随着知识的增多,实现一些功能的方式方法也增多了起来,这里只是自定义控件一个例子,可以同理到很多控件上! 首先写一个类继承你需要重写的控件 比如我这里是...

    Android TextView实现跑马灯效果的方法

    本文为大家分享一个非常简单但又很常用的控件,跑马灯状态的TextView。当要显示的文本长度太长,又不想换行时用它来显示文本,一来可以完全的显示出文本,二来效果也挺酷,实现起来超级简单,所以,何乐不为。先看下...

    android自定义View实现跑马灯效果

    android自带的TextView可以实现跑马灯效果,但是有很多的局限性;比如需要设置ellipsize=”marquee”,获取 focusable=”true”,设置singleLine=”true”,控件里的内容需要超过控件本身的长度,无法控制滚动速度和...

    Android自定义View实现竖直跑马灯效果案例解析

    大家知道,横向的跑马灯android自带的TextView就可以实现,详情请百度【Android跑马灯效果】。但是竖直的跑马灯效果原生Android是不支持的。网上也有很多网友实现了自定义的效果,但是我一贯是不喜欢看别人的代码,...

    黑马程序员 安卓学院 万元哥项目经理 分享220个代码实例

    |--TextView单行跑马灯效果 |--TextView虚拟获得焦点 |--uploadServlet |--uri之表示资源resource |--ViewPage的使用 |--view中的tag用法之存储对象 |--view常用属性 |--xml常用属性 |--xml文件的pull解析与序列化...

    Android编程实现类似天气预报图文字幕垂直滚动效果的方法

    在很多天气或者新闻的应用中,我们都能看到一些字幕滚动的效果,最简单的实现为跑马灯效果,用系统提供的属性即可实现. 复杂一些的就需要自己去用自定义控件实现. 比如 让TextView 实现垂直滚动. 这里我要讲的是垂直...

    java版商城源码下载-AndroidNotes:安卓开发笔记

    跑马灯效果textview 来自酷安开源协议 带动画的textview 来自酷安开源协议 自定义省略号的textview 来自酷安开源协议 跑马灯 3.2k 来自awesome-android-ui github最强大的开源项目收集者 36k 文字拓展视图、类似...

Global site tag (gtag.js) - Google Analytics