类似百度手机助手的下载进度条。
虽然 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(); }
我也不清楚。。。
InsetDrawable 和 ClipRrawable 都属于 DrawableWrapper ,并不参与绘制。
InsetDrawable 会压缩实际绘制 Drawable 的 bounds , ClipRrawable 则是只绘制 Drawable 的一部分。
实质是 ,根据 level 不断调整 clipRect(r) 中 r 的大小,然后重绘。