美文网首页Android
BlinkLayout 闪烁布局

BlinkLayout 闪烁布局

作者: 小马要加油 | 来源:发表于2019-05-31 20:09 被阅读0次

    引用

    想必大家都知道BrinkLayout了吧。一个Inflate的隐藏彩蛋,在xml里使用<blink>就可以让布局里的东西定时闪烁。

     <blink
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
     
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_blue_bright"
                android:text="闪烁内容" />
        </blink>
    

    如果还不清楚的可以参考这个博主的文章,https://blog.csdn.net/qq_22644219/article/details/69367150,写得非常的清楚详细。

    源码介绍

     /**
         * 采用定时绘制的效果达到布局闪烁,blingbling的
         */
        private static class BlinkLayout extends FrameLayout {
            private static final int MESSAGE_BLINK = 0x42;//发送闪烁消息
            private static final int BLINK_DELAY = 500;//闪烁时间间隔
    
            private boolean mBlink;//是否支持闪烁
            private boolean mBlinkState;//闪烁状态,true为可见,false为不可见
            private final Handler mHandler;
    
            public BlinkLayout(Context context, AttributeSet attrs) {
                super(context, attrs);
                mHandler = new Handler(new Handler.Callback() {
                    @Override
                    public boolean handleMessage(Message msg) {
                        if (msg.what == MESSAGE_BLINK) {
                            if (mBlink) {
                                //可以闪烁时,每隔500ms去动态的修改mBlinkState状态
                                mBlinkState = !mBlinkState;
                                makeBlink();
                            }
                            //去刷新图案
                            invalidate();
                            return true;
                        }
                        return false;
                    }
                });
            }
    
            /**
             * 发送消息开始闪烁
             */
            private void makeBlink() {
                Message message = mHandler.obtainMessage(MESSAGE_BLINK);
                mHandler.sendMessageDelayed(message, BLINK_DELAY);
            }
    
            /**
             * 当这个view被添加到window时,开始闪烁
             * 将状态设置为可闪烁
             */
            @Override
            protected void onAttachedToWindow() {
                super.onAttachedToWindow();
                mBlink = true;
                mBlinkState = true;
                makeBlink();
            }
    
            /**
             * 当view被移除的时候 停止闪烁
             * 状态设置为不可闪烁
             * 绘制状态设置为 可见
             * 将消息移除,避免内存泄漏
             */
            @Override
            protected void onDetachedFromWindow() {
                super.onDetachedFromWindow();
    
                mBlink = false;
                mBlinkState = true;
    
                mHandler.removeMessages(MESSAGE_BLINK);
            }
    
            /**
             * onDrow的时候会去调用这个方法,这里就是采用invalidate会去onDrow
             * 如果mBlinkState为false时,不去绘制图案,这样就是空白的,达到闪烁中暗的一面
             * @param canvas
             */
            @Override
            protected void dispatchDraw(Canvas canvas) {
                if (mBlinkState) {
                    super.dispatchDraw(canvas);
                }
            }
        }
    
    
    

    自定义闪烁控件

    其实这个控件使用很简单,看到的现象就是这个layout里的布局一直每隔500ms闪烁一下。那有时候需求并不是这么简单。想要动态停止闪烁,想要控制闪烁频率,想要可闪可不闪改怎么弄?
    其实也是很简单,我们基于这个改一改就好了。提供一个接口设置时间间隔,把开始闪烁的方法从onAttachedToWindow拿出来,作为接口抛出来就好了。对应的停止闪烁也需要抛出来

      /**
         * 开始闪烁
         * @param intervalTime 闪烁间隔时间
         */
        public void startBlinkDelay(int intervalTime) {
           mIntervalTime = intervalTime;
           startBlinkDelay();
        }
    
        public void startBlink(){
            mBlink= true;
            if (mHandler.hasMessages(MESSAGE_BLINK)){
                return;
            }
            Message message = mHandler.obtainMessage(MESSAGE_BLINK);
            mHandler.sendMessage(message);
        }
    

    自定义闪烁控件源码

    /**
     * 支持闪烁的layout
     */
    public class BlinkLayout extends FrameLayout {
        private static final String TAG = BlinkLayout.class.getSimpleName();
        private static final int MESSAGE_BLINK = 66;
        private int mIntervalTime = 800;
        private boolean mBlink;
        private boolean mIsAllowDraw;
        private final Handler mHandler = new Handler(new Handler.Callback() {
            public boolean handleMessage(Message msg) {
                if (msg.what == MESSAGE_BLINK) {
                    if (mBlink) {
                        mIsAllowDraw = !mIsAllowDraw;
                        startBlinkDelay();
                    }
    
                    invalidate();
                    return true;
                } else {
                    return false;
                }
            }
        });
    
        public BlinkLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        /**
         * 开始闪烁
         * @param intervalTime 闪烁间隔时间
         */
        public void startBlinkDelay(int intervalTime) {
           mIntervalTime = intervalTime;
           startBlinkDelay();
        }
    
        public void startBlink(){
            mBlink= true;
            if (mHandler.hasMessages(MESSAGE_BLINK)){
                return;
            }
            Message message = mHandler.obtainMessage(MESSAGE_BLINK);
            mHandler.sendMessage(message);
        }
    
        public void startBlinkDelay(){
            if (mHandler.hasMessages(MESSAGE_BLINK)){
                return;
            }
            Message message = mHandler.obtainMessage(MESSAGE_BLINK);
            mHandler.sendMessageDelayed(message, mIntervalTime);
        }
    
        //停止之后可能刚好没有显示 这时候需要重新绘制一遍
        public void stopBlink() {
            mBlink= false;
            mHandler.removeMessages(MESSAGE_BLINK);
            mIsAllowDraw = true;
            invalidate();
        }
    
        /**
         * 通过控制标志位 是否需要绘制图像 达到闪烁效果
         * @param canvas
         */
        protected void dispatchDraw(Canvas canvas) {
            if (mIsAllowDraw) {
                super.dispatchDraw(canvas);
            }
        }
    
        @Override
        protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
            super.onVisibilityChanged(changedView, visibility);
            Log.d(TAG, "onVisibilityChanged: visibility = "+(visibility== View.VISIBLE));
            if (visibility == VISIBLE) {
                mBlink = true;
                mIsAllowDraw = true;
            }else {
                mBlink = false;
                mIsAllowDraw = true;
                mHandler.removeMessages(MESSAGE_BLINK);
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:BlinkLayout 闪烁布局

        本文链接:https://www.haomeiwen.com/subject/wrzgtctx.html