可控制的启动关闭跑马灯效果


前言

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:singleLine="true"
    android:ellipsize="marquee"/>

Android中当文本显示不全时可以通过设置跑马灯方式轮播显示所以文字
但是我们有时希望在指定情况下才启用跑马灯轮播,这就需要重写TextView来实现

自定义跑马灯

public class MarqueeText extends AppCompatTextView {
    private static final String TAG = "MarqueeText";
    public MarqueeText(Context context) {
        super(context);
    }
    public MarqueeText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    public MarqueeText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean isFocused() {
        return true;
    }}

如上代码所示,我们通过重写isFocused()方法,使它总是返回true就可以让文字开始轮播显示了

启动关闭轮播

如果一个界面有好多文本需要轮播,如果按照上面的方式实现,则会出现很多文本同时轮播的情况,这样就显得很乱,因此我们需要添加开关来进行控制

public class MarqueeText extends AppCompatTextView {
    private static final String TAG = "MarqueeText";
    private boolean enableFocus = false;
    private CustomRunnable mCustomRunnable;

    public MarqueeText(Context context) {
        super(context);
        init();
    }

    public MarqueeText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public MarqueeText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mCustomRunnable = new CustomRunnable(this);
    }

    public void setEnableFocus(boolean b) {
        //LogUtils.i(TAG, "setEnableFocus::b = " + b + "::txt = " + getText());
        setFocusable(b);
        enableFocus = b;
        if (b) {
            setEllipsize(TextUtils.TruncateAt.MARQUEE);
            postDelayed(mCustomRunnable, 500);
        } else {
            setEllipsize(TextUtils.TruncateAt.END);
            removeCallbacks(mCustomRunnable);//删除延时runnable
            post(mCustomRunnable);//触发焦点切换,设置跑马灯循环为0
        }
    }

    @Override//实现了都获取焦点
    public boolean isFocused() {
        //LogUtils.i(TAG, "isFocused::enableFocus = " + enableFocus + "::txt = " + getText());
        return enableFocus;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        removeCallbacks(mCustomRunnable);
    }

    static class CustomRunnable implements Runnable {
        private WeakReference<MarqueeText> mWeakReference = new WeakReference<>(null);

        public CustomRunnable(MarqueeText marqueeText) {
            mWeakReference = new WeakReference<>(marqueeText);
        }

        @Override
        public void run() {
            if (mWeakReference.get() == null) {
                return;
            }
            MarqueeText marqueeText = mWeakReference.get();
            //跑马灯循环次数设置为0则关闭跑马灯,否则设置无穷大
            marqueeText.setMarqueeRepeatLimit(marqueeText.enableFocus ? Integer.MAX_VALUE : 0);
            marqueeText.onWindowFocusChanged(marqueeText.enableFocus);
        }
    }}

通过setEnableFocus(boolean b)方法来设置打开\关闭开关
通过setMarqueeRepeatLimit设置跑马灯循环次数打开\关闭跑马灯
通过onWindowFocusChanged刷新通知轮播效果

上一篇:v-on="$listeners"和v-bind="$attrs"


下一篇:vue组件通讯