类似百度手机助手的下载进度条。
虽然 gif 有些不平滑,但实际手机上是平滑的。。。
这种简单的自定义 View ,其实就是拼一个 background 。
public class ColorProgress extends TextView {
public ColorProgress(Context context) {
super(context);
}
public ColorProgress(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ColorProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// 三层 Drawable,重叠的实现
private Drawable floor0;
private Drawable floor1;
private Drawable floor2;
// 二层 ClipDrawable,进度条的实现
private ClipDrawable clipDrawable1;
private ClipDrawable clipDrawable2;
//
final int cornerRadius = 100;
final int strokeWidth = 4;
// 进度条的内边距
final int inset1 = 12;
final int inset2 = 4;
int progressColor;
private void initProgressColor() {
progressColor = getResources().getColor(android.R.color.holo_blue_light);
}
//
private void initFloor0() {
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setCornerRadius(cornerRadius);
gradientDrawable.setStroke(strokeWidth, progressColor);
floor0 = gradientDrawable;
}
private void initFloor1() {
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setCornerRadius(cornerRadius);
gradientDrawable.setColor(progressColor);
clipDrawable1 = new ClipDrawable(gradientDrawable, Gravity.START, ClipDrawable.HORIZONTAL);
floor1 = new InsetDrawable(clipDrawable1, inset1);
}
private void initFloor2() {
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setCornerRadius(cornerRadius);
gradientDrawable.setColor(progressColor);
// second 进度条设置透明度
gradientDrawable.setAlpha(100);
clipDrawable2 = new ClipDrawable(gradientDrawable, Gravity.START, ClipDrawable.HORIZONTAL);
floor2 = new InsetDrawable(clipDrawable2, inset2);
}
//
private void init() {
initProgressColor();
initFloor0();
initFloor1();
initFloor2();
Drawable[] d = new Drawable[]{floor0, floor1, floor2};
LayerDrawable layerDrawable = new LayerDrawable(d);
setBackground(layerDrawable);
setTextColor(Color.WHITE);
}
//
public void setProgress(float fraction) {
clipDrawable1.setLevel((int) (fraction * 10000));
}
public void setSecondProgress(float fraction) {
clipDrawable2.setLevel((int) (fraction * 10000));
}
public void clear() {
clipDrawable1.setLevel(0);
clipDrawable2.setLevel(0);
}
}
public class MainActivity extends AppCompatActivity {
ColorProgress progress;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress = (ColorProgress) findViewById(R.id.progress);
progress.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startAnim();
}
});
}
private void startAnim() {
progress.clear();
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0);
valueAnimator.setDuration(5000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float f = animation.getAnimatedFraction();
progress.setSecondProgress(f);
if (f > 0.2) {
progress.setProgress(f - 0.2f);
}
progress.setText((int) (f * 100) + " %");
if (f == 1) {
startAnim2();
}
}
});
valueAnimator.start();
}
private void startAnim2() {
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0);
valueAnimator.setDuration(1000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float f = animation.getAnimatedFraction();
progress.setProgress(0.8f + f * 0.2f);
if (f == 1) {
progress.setText("安装");
}
}
});
valueAnimator.start();
}
用了这么多 Drawable 会不会很消耗性能之类的问题?
我也不清楚。。。
InsetDrawable 和 ClipRrawable 都属于 DrawableWrapper ,并不参与绘制。
InsetDrawable 会压缩实际绘制 Drawable 的 bounds , ClipRrawable 则是只绘制 Drawable 的一部分。
实质是 ,根据 level 不断调整 clipRect(r) 中 r 的大小,然后重绘。