Github
Making address: https://github.com/Bigmercu/ACheckBox welcome star and issue.
The animation part
Do two kinds of animation can choose
hook
Use pathMeasure implementation
pathMeasure
setPath
Can I do forpathMeasure
Setting a pathgetLength()
You can getpathMeasure
The total length of the
A pathMeasure is very simple. It first adds a path to a pathMeasure and then retrieves a segment through getSegment.
mPath = new Path();
pathMeasure = new PathMeasure();
mPath.addRect(wStart,hStart,wSize + wStart,hSize + hStart, Path.Direction.CW);
pathMeasure.setPath(mPath,true);
pathLenth = pathMeasure.getLength();Copy the code
The power of animation
Send some number, it could be the Angle you want to change, it could be a length, it could be any number change you can think of. Given the interpolator setInterpolator and the duration setDuration, they will wait for the theme to be fired.
valueAnimator = ValueAnimator.ofInt(255, 0); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { AnimationValue = (int) animation.getAnimatedValue(); }); valueAnimator1 = ValueAnimator.ofInt(180, 225); valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { AnimationValue1 = (int) animation.getAnimatedValue(); }); valueAnimator2 = ValueAnimator.ofFloat(hSize + wSize, wSize * 2 / 5); valueAnimator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { AnimationValue2 = (float) animation.getAnimatedValue(); }); valueAnimator3 = ValueAnimator.ofFloat(hSize + wSize, hSize + wSize * 2); valueAnimator3.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { AnimationValue3 = (float) animation.getAnimatedValue(); });Copy the code
onDraw
First, I wanted to get the padding behind it, because it would be too crowded without the padding, so I added a 10px padding by default
int paddingLeft = getPaddingLeft() + 10;
int paddingRight = getPaddingRight() + 10;
int paddingTop = getPaddingTop() + 10;
int paddingBottom = getPaddingBottom() + 10;Copy the code
Then all we need to do is draw, because the pathMeasure itself has a bug, so the first step is required
mDst.reset(); MDst. LineTo (0, 0);Copy the code
- I saved the canvas for later
restore
Let’s draw a border - I’m going to move the canvas coordinates so that I have the padding,
drawText
Draw the text section. - For the CW rectangle:
pathMeasure.getSegment(0)
Is the bottom right corner of the rectangle, increase to the left and then up… - I get the parts I need to draw in several segments, using two brushes
mPaint
andmPaintAfter
ALPHA property change to make the entire animation color change. - The last
canvas.restore();
Restore the previously saved canvas state and draw the border if required
MDst. LineTo (0, 0); canvas.translate(wStart + paddingLeft, hStart + paddingTop); if(isShowBorder) { canvas.save(); canvas.drawText(boxText, wStart + wSize + 18, (hSize + textSize )/2, mPaintText); Canvas. Translate (-animationValue4 * wSize, (float) (-animationValue4 * hSize * 1.5)); * If startWithMoveTo is true, the truncated Path fragment remains unchanged. If startWithMoveTo is false, * moves the truncated Path fragment's starting point to the last point in the DST. To ensure DST continuity. * */ pathMeasure.getSegment(AnimationValue3, pathLenth, mDst, true); pathMeasure.getSegment(0, wSize * 2 / 5, mDst, true); pathMeasure.getSegment(wSize * 2 / 5, AnimationValue2, mDst, true); mPaint.setAlpha(AnimationValue); mPaintAfter.setAlpha(255 - AnimationValue); canvas.rotate(AnimationValue1, wStart + wSize / 2, hStart + hSize / 2); canvas.drawPath(mDst, mPaint); canvas.drawPath(mDst, mPaintAfter); if(isShowBorder) { canvas.restore(); canvas.drawRect(wStart, hStart, wStart + wSize, hSize + hStart, mPaintText);Copy the code
Finally, start all valueAnimators and postInvalidate(); Can.
fork
Use valueAnimator implementation This is simple, I use a valueAnimator to radiate the radius of a rectangle by calculating the positions of the four corners of the rectangle, connecting the top left corner of the rectangle, the top midpoint (Y axis adds valueAnimator), the top right corner, the right midpoint (X axis reduces valueAnimator), the bottom right corner… You end up with an animation where the rectangle changes to a cross. Also be careful with the padding, custom views don’t do the padding for you, you don’t do the padding for you.
MDst. LineTo (0, 0); canvas.translate(wStart+ paddingLeft , hStart + paddingTop ); if(isShowBorder) { canvas.save(); canvas.drawText(boxText, wStart + wSize + 18, (hSize + textSize )/2, mPaintText); Mdst.moveto ((float) (wStart + cAnimationValue * 0.3), (float) (hStart + cAnimationValue * 0.3)); Mdst. lineTo(wStart + wSize/2, (float) (hStart + cAnimationValue + cAnimationValue * 0.2)); Mdst. lineTo((float) (wStart+ wSize - cAnimationValue * 0.2), (float) (hStart + cAnimationValue * 0.2)); Mdst. lineTo((float) (wStart+ wSize -cAnimationValue -cAnimationValue * 0.2),hSize/2 + hStart); Mdst. lineTo((float) (wStart+ wsize-canimationValue * 0.2), (float) (hStart + hsize-canimationValue * 0.2)); Mdst. lineTo(wStart+ wSize/2, (float) (hStart + hSize - cAnimationValue - cAnimationValue * 0.2)); Mdst. lineTo((float) (wStart + cAnimationValue * 0.2), (float) (hStart + hSize - cAnimationValue * 0.2)); Mdst. lineTo((float) (wStart + cAnimationValue + cAnimationValue * 0.2),hStart + hSize/2); Mdst.lineto ((float) (wStart + cAnimationValue * 0.3), (float) (hStart + cAnimationValue * 0.3)); mPaint.setAlpha((int) cAnimationValue2); canvas.drawPath(mDst,mPaint); mPaintAfter.setAlpha((int) (255-cAnimationValue2)); canvas.drawPath(mDst,mPaintAfter); if(isShowBorder) { canvas.restore(); canvas.drawRect(wStart, hStart, wStart + wSize, hSize + hStart, mPaintText);Copy the code
Wrap_content processing
Rewrite onMeasure to calculate the width and height of the View, set different dimensions according to different SpecMode, and finally achieve the effect of WRAP_content. In this:
-
My View width is :2 ‘strokeWidth + wStart + wSize + 20 + paddingLeft + textSize boxText.length()’ 2 times border width + left margin + rectangle width + 20 is the distance between the word and the border + the padding + the string width
-
My View height is :hStart + hSize + paddingTop + paddingBottom + 2 * strokeWidth Top margin + top width + rectangle height + bottom padding + 2 times border width
Once you have the width and height of these two views, you can go into wrap_content.
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int paddingLeft = getPaddingLeft() + 10; int paddingRight = getPaddingRight() + 10; int paddingTop = getPaddingTop() + 10; int paddingBottom = getPaddingBottom() + 10; if(widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){ setMeasuredDimension(2* strokeWidth + wStart + wSize + 20 + paddingLeft + textSize * boxText.length(),hStart + hSize + paddingTop + paddingBottom + 2 * strokeWidth); Log.d(TAG, wStart+" "+ wSize +" "+ textSize * boxText.length() + " " +boxText.length()); }else if(widthSpecMode == MeasureSpec.AT_MOST){ setMeasuredDimension(2* strokeWidth +wStart + wSize + paddingLeft + 20 + textSize * boxText.length(),widthSpecSize); }else if(heightSpecMode == MeasureSpec.AT_MOST){ setMeasuredDimension(heightSpecSize,hStart + hSize + paddingTop + paddingBottom+ 2 * strokeWidth);Copy the code
The effect
Upload Jcenter
Classpath 'com. Jfrog. Bintray. Gradle: gradle bintray - plugin: 1.7.1' classpath 'com. Making. Dcendents: android - maven - gradle - plugin: 1.4.1'Copy the code
- Insert it under the original code in build.gradle of the module you want to upload
apply plugin: 'com.github.dcendents.android-maven' apply plugin: '. Com. Jfrog bintray version = "1.05" / / version number def siteUrl = "https://github.com/Bigmercu/ACheckBox" / / def gitUrl = to upload the project home page [email protected]: Bigmercu/ACheckBox. "git" / / git to upload the project address group = "com. Bigmercu. The checkbox" / / package name directly related to the last generation of gradle connect install { repositories.mavenInstaller { // This generates POM.xml with proper parameters pom { project { packaging 'aar' name 'This is a simple checkbox with cool animation for android by bigmercu.' url siteUrl licenses { license { name 'The Apache Software License, Version 2.0 'url' http://www.apache.org/licenses/LICENSE-2.0.txt 'developers {developer {id "bigmercu" / / bintray.com Id name "Wallace" // Your bintray.com name email "[email protected]" SCM {connection gitUrl developerConnection gitUrl url siteUrl task sourcesJar(type: Jar) { from android.sourceSets.main.java.srcDirs classifier = 'sources' task javadoc(type: Javadoc) { source = android.sourceSets.main.java.srcDirs classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' from javadoc.destinationDir artifacts { archives javadocJar archives sourcesJar Properties properties = new Properties() properties.load(project.rootProject.file('local.properties').newDataInputStream()) bintray { user = properties.getProperty("bintray.user") key = properties.getProperty("bintray.apikey") configurations = ['archives'] pkg {repo = "maven" name = "bCheckbox" // Project name websiteUrl = siteUrl vcsUrl = gitUrl licenses = [" apache-2.0 "] publish = trueCopy the code
- Insert your information in local.propreties in the project root directory
Bintray. user= your ID Bintray. apiKey = your keyCopy the code
Step 2 Run the task as instructed
Be sure to follow all the steps successfully
- javadocjar
- sourcesjar
- install
- bintrayUpload
The following figure
There is basically no problem if there is no error in operation. Bintray has been successfully uploaded. It is easy to add jCenter and so on.