天天看點

【Android】不依賴焦點和選中的TextView跑馬燈

前言

繼承textview,并仿照源碼修改而來,主要是取消了焦點和選中了判斷,也不依賴文本的寬度。

聲明

歡迎轉載,但請保留文章原始出處:) 

部落格園:http://www.cnblogs.com

農民伯伯: http://over140.cnblogs.com 

正文

【Android】不依賴焦點和選中的TextView跑馬燈

import java.lang.ref.weakreference;

import android.content.context;

import android.graphics.canvas;

import android.os.handler;

import android.os.message;

import android.util.attributeset;

import android.widget.textview;

public class marqueetextview extends textview {

    private marquee mmarquee;

    public marqueetextview(context context, attributeset attrs) {

        super(context, attrs);

    }

    public marqueetextview(context context, attributeset attrs, int defstyle) {

        super(context, attrs, defstyle);

    public marqueetextview(context context) {

        super(context);

    public void startmarquee() {

        startmarquee(-1);

    public void startmarquee(int repeatlimit) {

        if (mmarquee == null)

            mmarquee = new marquee(this);

        mmarquee.start(repeatlimit);

    public void stopmarquee() {

        if (mmarquee != null && !mmarquee.isstopped()) {

            mmarquee.stop();

        }

    public void togglemarquee() {

        if (mmarquee == null || mmarquee.isstopped())

            startmarquee();

        else

            stopmarquee();

    @override

    protected void ondraw(canvas canvas) {

        if (mmarquee != null && mmarquee.isrunning()) {

            final float dx = -mmarquee.getscroll();

            canvas.translate(getlayoutdirection() == layout_direction_rtl ? -dx

                    : +dx, 0.0f);

        super.ondraw(canvas);

    @suppresswarnings("unused")

    private static final class marquee extends handler {

        // todo: add an option to configure this

        private static final float marquee_delta_max = 0.07f;

        private static final int marquee_delay = 0;// 1200;

        private static final int marquee_restart_delay = 1200;

        private static final int marquee_resolution = 1000 / 30;

        private static final int marquee_pixels_per_second = 30;

        private static final byte marquee_stopped = 0x0;

        private static final byte marquee_starting = 0x1;

        private static final byte marquee_running = 0x2;

        private static final int message_start = 0x1;

        private static final int message_tick = 0x2;

        private static final int message_restart = 0x3;

        private final weakreference<textview> mview;

        private byte mstatus = marquee_stopped;

        private final float mscrollunit;

        private float mmaxscroll;

        private float mmaxfadescroll;

        private float mghoststart;

        private float mghostoffset;

        private float mfadestop;

        private int mrepeatlimit;

        private float mscroll;

        marquee(textview v) {

            final float density = v.getcontext().getresources()

                    .getdisplaymetrics().density;

            mscrollunit = (marquee_pixels_per_second * density)

                    / marquee_resolution;

            mview = new weakreference<textview>(v);

        @override

        public void handlemessage(message msg) {

            switch (msg.what) {

            case message_start:

                mstatus = marquee_running;

                tick();

                break;

            case message_tick:

            case message_restart:

                if (mstatus == marquee_running) {

                    if (mrepeatlimit >= 0) {

                        mrepeatlimit--;

                    }

                    start(mrepeatlimit);

                }

            }

        void tick() {

            if (mstatus != marquee_running) {

                return;

            removemessages(message_tick);

            final textview textview = mview.get();

            // && (textview.isfocused() || textview.isselected())

            if (textview != null) {

                mscroll += mscrollunit;

                if (mscroll > mmaxscroll) {

                    mscroll = mmaxscroll;

                    sendemptymessagedelayed(message_restart,

                            marquee_restart_delay);

                } else {

                    sendemptymessagedelayed(message_tick, marquee_resolution);

                textview.invalidate();

        void stop() {

            mstatus = marquee_stopped;

            removemessages(message_start);

            removemessages(message_restart);

            resetscroll();

        private void resetscroll() {

            mscroll = 0.0f;

        void start(int repeatlimit) {

            if (repeatlimit == 0) {

                stop();

            mrepeatlimit = repeatlimit;

            if (textview != null && textview.getlayout() != null) {

                mstatus = marquee_starting;

                mscroll = 0.0f;

                final int textwidth = textview.getwidth()

                        - textview.getcompoundpaddingleft()

                        - textview.getcompoundpaddingright();

                final float linewidth = textview.getlayout().getlinewidth(0);

                final float gap = textwidth / 3.0f;

                mghoststart = linewidth - textwidth + gap;

                mmaxscroll = mghoststart + textwidth;

                mghostoffset = linewidth + gap;

                mfadestop = linewidth + textwidth / 6.0f;

                mmaxfadescroll = mghoststart + linewidth + linewidth;

                sendemptymessagedelayed(message_start, marquee_delay);

        float getghostoffset() {

            return mghostoffset;

        float getscroll() {

            return mscroll;

        float getmaxfadescroll() {

            return mmaxfadescroll;

        boolean shoulddrawleftfade() {

            return mscroll <= mfadestop;

        boolean shoulddrawghost() {

            return mstatus == marquee_running && mscroll > mghoststart;

        boolean isrunning() {

            return mstatus == marquee_running;

        boolean isstopped() {

            return mstatus == marquee_stopped;

}

【Android】不依賴焦點和選中的TextView跑馬燈

代碼說明: 

1、取消了焦點和選中的判斷

2、将延遲1200改為0,立即執行跑馬燈效果。

3、核心代碼都是直接從textview拷貝出來。

2014-04-25 更新

結束 

這裡主要是提供一種解決問題的思路,實際使用還需要進行相應的修改。

轉載:http://www.cnblogs.com/over140/p/3164712.html

繼續閱讀