Hand to show you a dynamic error prompt Android custom view
Let's not talk much about it. See:
First, the Construction Function Measurement.
public ErrorView(Context context) { this(context, null); } public ErrorView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ErrorView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (widthMode == MeasureSpec.EXACTLY) { mWidth = widthSize; } else { mWidth = 200; } if (heightMode == MeasureSpec.EXACTLY) { mHeight = heightSize; } else { mHeight = 200; } setMeasuredDimension(mWidth, mHeight); }
If you don't understand the above, you can refer to my blog and have some additional knowledge points.
Next, draw, if you want to draw a static one, you must close your eyes and draw it out .. So how can we achieve dynamic results ..
In fact, it is the process of imitating hand-drawn images. We drew them at 1.1 o'clock and gradually delayed a line. Then we will imitate this natural process.
First draw a circle.
Paint p = new Paint(); p.setStrokeWidth(10); p.setAntiAlias(true); p.setColor(Color.RED); p.setStyle(Paint.Style.STROKE); RectF rectF = new RectF(0 + 10, 0 + 10, mWidth - 10, mHeight - 10); canvas.drawArc(rectF, 180, 360 * mProgress / 100, false, p); mProgress+=5;
We can see that the third parameter of drawArc is changed. The initial value of mProgress is zero. Let him add itself here. That is to say, he will increase every time he calls the onDraw method. Therefore, each arc is a little longer than the original one until it is finished. So there must be postInvalidateDelayed (10); method at the end of the program.
Next we will draw two lines. I will take one of the four points of the radius for the coordinates here. The only note is that we will draw two lines only when the progress is greater than 100, the two line segments are also auto-incrementing based on a variable. The principle is the same as above. Here, mLineOneX and other parameters all represent the coordinates of the two points when the line is drawn. When mLineOneX = mWidth * 0.5, mWidth/4 + mLineOneX is the final point for us to draw a line segment.
If (mProgress> 100) {// draw the line on the left if (mLineOneX <mWidth * 0.5) {mLineOneX + = 20; mLineOneY + = 20;} canvas. drawLine (mWidth/4, mHeight/4, mWidth/4 + mLineOneX, mHeight/4 + mLineOneY, p); if (mLineOneX = mWidth * 0.5) {if (mLineTwoX <mWidth * 0.5) {mLineTwoX + = 20; mLineTwoY + = 20;} else {// determine whether all the painting is complete isLineDrawDone = true;} canvas. drawLine (mWidth/4, (float) (mHeight * 0.75), mWidth/4 + mLineTwoX, (float) (mHeight * 0.75)-mLineTwoY, p );}}
Then add a flag isLineDrawDone to determine if the image is not finished:
if(isLineDrawDone){ Log.e("wing","draw done"); }else{ postInvalidateDelayed(10); }
Now we have basically finished the drawing. Don't worry about the vibration. How is the vibration effect achieved? Do you remember?
Therefore, we need to write an interface to call onStop
public interface OnStopListener{ void onStop(View v); }
Complete the final painting and add a flag to indicate that all the painting is complete.
if(isLineDrawDone){ Log.e("wing","draw done"); if(!isDrawDone) { if (mOnStopListener != null) { mOnStopListener.onStop(this); } isDrawDone = true; } }else{ postInvalidateDelayed(10); }
Provides a reset () method for users to manually control repainting.
public void reset() { mProgress = 0; mLineOneX = 0; mLineOneY = 0; mLineTwoX = 0; mLineTwoY = 0; isLineDrawDone = false; isDrawDone = false; invalidate(); }
Add a listener
public void setOnStopListener(OnStopListener onStopListener){ mOnStopListener = onStopListener; }
Finally, add the vibration effect to the View in the Activity.
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mErrorView = (ErrorView) findViewById(R.id.errorView); mErrorView.setOnStopListener(new ErrorView.OnStopListener() { @Override public void onStop(View v) { ShakeAnimation sa = new ShakeAnimation(); sa.setDuration(1000); v.startAnimation(sa); } }); mErrorView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mErrorView.reset(); } });
Hey, hey... In this way, the Medal of perseverance is cheated.