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

來源:互聯網
上載者:User

承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:                tick();                break;            case MESSAGE_RESTART:                if (mStatus == MARQUEE_RUNNING) {                    if (mRepeatLimit >= 0) {                        mRepeatLimit--;                    }                    start(mRepeatLimit);                }                break;            }        }            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);            removeMessages(MESSAGE_TICK);            resetScroll();        }            private void resetScroll() {            mScroll = 0.0f;            final TextView textView = mView.get();            if (textView != null) {                textView.invalidate();            }        }            void start(int repeatLimit) {            if (repeatLimit == 0) {                stop();                return;            }            mRepeatLimit = repeatLimit;            final TextView textView = mView.get();            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;                    textView.invalidate();                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;        }    }}

查看本欄目更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/OS/extra/

代碼說明:

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

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

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

結束

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

作者:cnblogs 農民伯伯

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.