編輯: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: 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.cn/OS/extra/
代碼說明:
1、取消了焦點和選中的判斷
2、將延遲1200改為0,立即執行跑馬燈效果。
3、核心代碼都是直接從TextView拷貝出來。
結束
這裡主要是提供一種解決問題的思路,實際使用還需要進行相應的修改。
作者:cnblogs 農民伯伯
盡管以前你也可以將一個網頁放到Android主屏直接啟動,但Chrome V31 beta for Android加到主屏的功能稍微有點改進,就是通過快捷方式進入的網頁是
經過上一篇的講解,相信大家對於LibGDX有了一個初步大概的認識和了解,那麼從今天開始,博主將會帶 領大家繼續的深入下去。首先我會以一個個實例的方式教大家學習最基礎的知識
1.背景即將結束在sony移動的實習了,在最後的日子有一些傷感有一些感觸,對於android這個傾注一年心血的技術有太多話要說。感謝sony移動的各位大牛們給我這個機會,
目前所介紹的方法只是用來存儲一些簡單的數據。如果想要存儲關系型數據,那麼使用數據庫將會更加的 效率。舉個例子,你要存儲學校裡面每一個學生的分數,這種情況下,最好使用數據庫