1.
public class Sample01AfterOnDrawView extends AppCompatImageView {
public static final boolean DEBUG = true;
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
public Sample01AfterOnDrawView(Context context) {
super(context);
}
public Sample01AfterOnDrawView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public Sample01AfterOnDrawView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
{
paint.setColor(Color.parseColor("#FFC107"));
paint.setTextSize(28);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (DEBUG) {
// 在 debug 模式下绘制出 drawable 的尺寸信息
Drawable drawable = getDrawable();
if (drawable != null) {
canvas.save();
canvas.concat(getImageMatrix());
Rect bounds = drawable.getBounds();
canvas.drawText(getResources().getString(R.string.image_size, bounds.width(), bounds.height()), 20, 40, paint);
canvas.restore();
}
}
}
}
2.
public class Sample02BeforeOnDrawView extends AppCompatTextView {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
RectF bounds = new RectF();
public Sample02BeforeOnDrawView(Context context) {
super(context);
}
public Sample02BeforeOnDrawView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public Sample02BeforeOnDrawView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
{
paint.setColor(Color.parseColor("#FFC107"));
}
@Override
protected void onDraw(Canvas canvas) {
Layout layout = getLayout();
bounds.left = layout.getLineLeft(1);
bounds.right = layout.getLineRight(1);
bounds.top = layout.getLineTop(1);
bounds.bottom = layout.getLineBottom(1);
canvas.drawRect(bounds, paint);
bounds.left = layout.getLineLeft(layout.getLineCount() - 4);
bounds.right = layout.getLineRight(layout.getLineCount() - 4);
bounds.top = layout.getLineTop(layout.getLineCount() - 4);
bounds.bottom = layout.getLineBottom(layout.getLineCount() - 4);
canvas.drawRect(bounds, paint);
super.onDraw(canvas);
}
}
3.
public class Sample03OnDrawLayout extends LinearLayout {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Pattern pattern = new Pattern();
public Sample03OnDrawLayout(Context context) {
super(context);
}
public Sample03OnDrawLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public Sample03OnDrawLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
{
// ViewGroup 需要主动开启 dispatchDraw() 以外的绘制
setWillNotDraw(false);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
pattern.draw(canvas);
}
private class Pattern {
private static final float PATTERN_RATIO = 5f / 6;
Paint patternPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
Sample03OnDrawLayout.Pattern.Spot[] spots;
private Pattern() {
spots = new Sample03OnDrawLayout.Pattern.Spot[4];
spots[0] = new Sample03OnDrawLayout.Pattern.Spot(0.24f, 0.3f, 0.026f);
spots[1] = new Sample03OnDrawLayout.Pattern.Spot(0.69f, 0.25f, 0.067f);
spots[2] = new Sample03OnDrawLayout.Pattern.Spot(0.32f, 0.6f, 0.067f);
spots[3] = new Sample03OnDrawLayout.Pattern.Spot(0.62f, 0.78f, 0.083f);
}
private Pattern(Sample03OnDrawLayout.Pattern.Spot[] spots) {
this.spots = spots;
}
{
patternPaint.setColor(Color.parseColor("#A0E91E63"));
}
private void draw(Canvas canvas) {
int repitition = (int) Math.ceil((float) getWidth() / getHeight());
for (int i = 0; i < spots.length * repitition; i++) {
Sample03OnDrawLayout.Pattern.Spot spot = spots[i % spots.length];
canvas.drawCircle(i / spots.length * getHeight() * PATTERN_RATIO + spot.relativeX * getHeight(), spot.relativeY * getHeight(), spot.relativeSize * getHeight(), patternPaint);
}
}
private class Spot {
private float relativeX;
private float relativeY;
private float relativeSize;
private Spot(float relativeX, float relativeY, float relativeSize) {
this.relativeX = relativeX;
this.relativeY = relativeY;
this.relativeSize = relativeSize;
}
}
}
}
4.
public class Practice04DispatchDrawLayout extends LinearLayout {
Pattern pattern = new Pattern();
public Practice04DispatchDrawLayout(Context context) {
super(context);
}
public Practice04DispatchDrawLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public Practice04DispatchDrawLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
{
setWillNotDraw(false);
}
// 把 onDraw() 换成 dispatchDraw(),让绘制内容可以盖住子 View
// 另外,在改完之后,上面的 setWillNotDraw(false) 也可以删了
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
pattern.draw(canvas);
}
private class Pattern {
private static final float PATTERN_RATIO = 5f / 6;
Paint patternPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
Spot[] spots;
private Pattern() {
spots = new Spot[4];
spots[0] = new Spot(0.14f, 0.3f, 0.026f);
spots[1] = new Spot(0.59f, 0.25f, 0.067f);
spots[2] = new Spot(0.22f, 0.6f, 0.067f);
spots[3] = new Spot(0.52f, 0.78f, 0.083f);
}
private Pattern(Spot[] spots) {
this.spots = spots;
}
{
patternPaint.setColor(Color.parseColor("#A0E91E63"));
}
private void draw(Canvas canvas) {
int repitition = (int) Math.ceil((float) getWidth() / getHeight());
for (int i = 0; i < spots.length * repitition; i++) {
Spot spot = spots[i % spots.length];
canvas.drawCircle(i / spots.length * getHeight() * PATTERN_RATIO + spot.relativeX * getHeight(), spot.relativeY * getHeight(), spot.relativeSize * getHeight(), patternPaint);
}
}
private class Spot {
private float relativeX;
private float relativeY;
private float relativeSize;
private Spot(float relativeX, float relativeY, float relativeSize) {
this.relativeX = relativeX;
this.relativeY = relativeY;
this.relativeSize = relativeSize;
}
}
}
}