引用
想必大家都知道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);
}
}
}
网友评论