SelectedDrawable是具有选中状态的自定义Drawable。这个工具类仍然有很大的改进空间,具体怎么改进,还需要看需求。
代码如下:
public class SelectedDrawable extends Drawable {
//未被选中
private Drawable mUnselectedDrawable;
//已被选中
private Drawable mSelectedDrawable;
//属性动画
private ValueAnimator anim;
public SelectedDrawable(Drawable unselected, Drawable selected) {
mUnselectedDrawable = unselected;
mSelectedDrawable = selected;
}
/**
* 开始揭露动画
*/
public void startRevealAnimator(){
//创建ValueAnimator对象,并设置属性动画的值(初始值、过程值、结束值)
anim = ValueAnimator.ofInt(0, 10000);
//动画执行时间
anim.setDuration(4000);
//动画播放延迟时间
anim.setStartDelay(0);
//设置动画重复次数
//假如设置重复次数为n,那么动画总共执行的次数为n+1次
//如果设置次数为ValueAnimator.INFINITE,那么动画则无限循环
anim.setRepeatCount(0);
//设置重复模式
//RESTART:正序播放
//REVERSE:倒序播放
anim.setRepeatMode(ValueAnimator.RESTART);
//监听动画更新
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int currentValue = (int) animation.getAnimatedValue();
setLevel(currentValue);
}
});
anim.start();
}
/**
* 暂停动画
*/
private void pauseRevealAnimator(){
if(anim != null && anim.isStarted()){
anim.pause();
}
}
/**
* 重新播放动画
*/
private void reStartRevealAnimator(){
if(anim != null && anim.isStarted()){
anim.start();
}
}
/**
* 停止动画
*/
private void endRevealAnimator(){
if(anim != null && anim.isStarted()){
anim.end();
}
}
@Override
public void draw(Canvas canvas) {
Rect r = getBounds();
Rect temp = new Rect();
//从一个已有的bound矩形边界范围当中抠出一个我们想要的矩形
Gravity.apply(
//左边
Gravity.LEFT,
//目标矩形宽
r.width() / 2 - r.width() * getLevel() / 10000,
//目标矩形高
r.height(),
//被扣的地方
r,
//抠出来,扔这里面
temp
);
canvas.save();
canvas.clipRect(temp);
mUnselectedDrawable.draw(canvas);
canvas.restore();
Gravity.apply(
//中间
Gravity.CENTER_HORIZONTAL,
//目标矩形宽
r.width() * 2 * getLevel() / 10000,
//目标矩形高
r.height(),
//被扣的地方
r,
temp
);
canvas.save();
canvas.clipRect(temp);
mSelectedDrawable.draw(canvas);
canvas.restore();
Gravity.apply(
//左边
Gravity.RIGHT,
//目标矩形宽
r.width() / 2 - r.width() * getLevel() / 10000,
//目标矩形高
r.height(),
//被扣的地方
r,
//抠出来,扔这里面
temp
);
canvas.clipRect(temp);
mUnselectedDrawable.draw(canvas);
}
@Override
protected void onBoundsChange(Rect bounds) {
// 定好两个Drawable图片的宽高---边界bounds
mUnselectedDrawable.setBounds(bounds);
mSelectedDrawable.setBounds(bounds);
}
@Override
public int getIntrinsicWidth() {
//得到Drawable的实际宽度
return Math.max(mSelectedDrawable.getIntrinsicWidth(), mUnselectedDrawable.getIntrinsicWidth());
}
@Override
public int getIntrinsicHeight() {
//得到Drawable的实际高度
return Math.max(mSelectedDrawable.getIntrinsicHeight(), mUnselectedDrawable.getIntrinsicHeight());
}
@Override
protected boolean onLevelChange(int level) {
// 当设置level的时候回调---提醒自己重新绘制
invalidateSelf();
return true;
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter cf) {
}
@Override
public int getOpacity() {
return 0;
}
}
如何使用?
//未被选中
Drawable mUnselectedDrawable = getResources().getDrawable(R.drawable.glass_unselected);
//已被选中
Drawable mSelectedDrawable = getResources().getDrawable(R.drawable.glass_selected);
SelectedDrawable rd = new SelectedDrawable(
mUnselectedDrawable,
mSelectedDrawable
);
iv = findViewById(R.id.iv);
iv.setBackground(rd);
iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((SelectedDrawable)iv.getBackground()).startRevealAnimator();
}
});
效果是怎样的?
340.gif[本章完...]
网友评论