Android profile with client focus and cancel attention button click on the effect of the implementation of the detailed _android

Source: Internet
Author: User
Tags hypot

First of all, the project code has been uploaded to GitHub, do not want to see a long speech can also go down the code, control code, where do not know where.
Code in this Https://github.com/zgzczzw/ZHFollowButton

A few days ago found that the attention of the Click Effect is really praise, check the implementation of the way, just see this problem, took a day to finally realize the effect, now to answer, unfortunately, upstairs, you are not all the answers, and listen to me one by one.

First of all, I looked at some of the known effects in detail, and there was a magical place like this:






Note that the second picture, the circle in the diffusion, the circle under the word is still, and the new word is also on the circle, the effect of the most difficult to achieve.

First look at the answers upstairs, summed up, a total of 2 ways to achieve ripple effect and use paint on the canvas hand-painted round

Ripple:

Ripple is the ripple effect, is the Android API 21 introduced after the introduction of a material design elements, is a touch feedback, that is, when the click will appear the pattern of Wave diffusion, demo (see last) in the first button is the use of the ripple effect.

The implementation is simple, to achieve one such drawable

The first color is the ripple color, the item inside specifies background normal color, can be a shape, also can be a drawable, can also be a selector.

Set to the background of the button

If the theme of the entire program uses meterial, then basically all the controls with the click Effect, such as button, bring the ripple effect. However, it should be noted that this set of APIs is only available after 21, so a compatibility process is required.

The effect is as follows:




I can see from the diagram that even if I set the ripple to Red (#FF0000), the effect is also light red, I guess because it is water ripple effect, in order not to affect the content of the button itself, the Android system automatically do the processing of transparency, in addition to the diagram can be clearly seen, Water Ripple and display content is up and down two layers, not affect each other, water ripple is at background level. This effect to do normal Click feedback is not bad, but absolutely do not know the effect of this with the ripple refresh content. So it's easy to see that the click Effect is not made with ripple.

Paint a circle on canvas.

@chaossss said to use paint in the click of the place to draw a circle, and then let the circle radius of the painting slowly become larger, to achieve the spread out of the style, I realized a bit, the code is as follows:

@Override
protected void OnDraw (Canvas Canvas) {
super.ondraw (Canvas);
if (mshoulddoanimation) {
Mmaxradius = getmeasuredwidth () +;
if (Mrevealradius > Mminbetweenwidthandheight/2)
Mrevealradius + = Mrevealradiusgap * 4;
else
Mrevealradius + = mrevealradiusgap;//radius
Paint mpaint = new Paint ();
if (!mispressed) {
mpaint.setcolor (color.white);
} else {
mpaint.setcolor (color.red);
} Sets the brush color
mpaint.setstyle (Paint.Style.FILL);
Canvas.drawcircle (Mcenterx, Mcentery, Mrevealradius, mpaint);

if (Mrevealradius <= mmaxradius) {
//Refresh
postinvalidatedelayed (invalidate_duration) after a certain time;
} else {
if (mispressed) {
settextcolor (color.white);
This.setbackgroundcolor (color.red);
} else {
settextcolor (color.black);
This.setbackgroundcolor (Color.White);
}
Mshoulddoanimation = false;
Invalidate ();}}

Effect as shown:







I thought it was almost like this, but compared with the effect of knowing, I can find the difference. What you can do with paint is to draw a circle where you click, then the radius slowly becomes larger and slowly spreads. The problem, however, is that this circle will cover the contents of the display, and the circle on the drawing cannot display the content. I tried to use DrawText, also can not achieve the word and circle together effect, the solution only, the process of painting the background color and the above text.

Then, after the circle is finished, erase the circle and show the background color and text below.

This will cause a text flicker problem, the first text will disappear, and then draw the circle after the show. Because the circle in the diffusion of time is not to see the text, only the circle disappears, the text can be displayed. And know the effect is the text and circle together brush out, and the text is still in the middle, there is no text flashing problem, the whole process flowing, it looks very smooth, as if with a circle opened the curtain.

To sum up, upstairs, all the answers are the answer to the owners see this effect after the first reaction to achieve, in fact, if not my own implementation, really think the second method is known to use, but at present, it is regrettable that the use of a better way to achieve this effect.

Then how to do it, I have no idea, how to draw a circle when the word is also painted on the circle, and then the background of the circle below also have it. No idea, look at the code, decompile.

The process of decompile I simply say:

Download the latest from the website to know APK

Using Apktool to decompile apk and get resource files

In the resource file search follow, here at the beginning of my search is ripple, because I think this effect should always be related to ripple, no results, so search follow, did not expect to really search out.

Revealfollowbutton This is obviously the ripple expansion control we want, and that's the next step is to find the control in the code. Here to remember, the position of this control is Com.zhihu.android.app.ui.widget.RevealFollowButton.

Decompile Code

Rename apk to RAR, open, you can find the inside of the class file

Knowing that Multidex is used, there will be two class files, are dragged out in the Dex2jar to compile, you can generate two jar package, the jar package in the GUI to look at, you can see the code, although the code has been confused, but the basic logic can still be seen.

Then according to the path in the previous XML to find the location of Revelfollowbutton, open the code to see it.

This is the inheritance of the class, Revealfollowbutton inherits from Revealframelayout, then inherits from Zhframelayout, this zhframelayout's parent class is framelayout, from the name we can see, Revelfollowbutton and Revealframelayout are the two classes that this effect implements.



See the implementation of this effect is based on framelayout, I know that we discussed before the method is actually going in the wrong direction, if told you to use Framelayout to achieve this effect, what would you do?

My idea is to add two TextView to this layout, and then a visible a gone, so switch, and then read the code, also proved that my idea is right.

Look, here are two textview. So, in fact, switching TextView is very easy to achieve, the problem is how to achieve the effect of ripple switching, the first thing is to look at the OnDraw function, for Groupview is Drawchild method.

Revealfollowbutton Drawchild method is not content, basically call the parent class, then we look at the Revealframelayout Drawchild method.

Here are two parts of the logic, if you meet a condition, do the first part, at first I do not know what this condition is, confused code can see the big logic, like this small logic can only take a step forward. So let's say this condition is forever false, look at the second part, see here instantaneous understand, the original is to use the way of cutting the canvas, cut the canvas into a circle, you can do the contents of the display is also on the circle, rather than the content is covered under the circle. Then the same way, the circular area is constantly expanding, and then constantly refresh, is to achieve the effect of the waveform brush out the content. The code is as follows.

Protected Boolean drawchild (Canvas Canvas, View Paramview, long paramlong) {
int i = Canvas.save ();
Mpath.reset ();
Mcenterx Mcentery is the location of the click, in the Ontouchevent set
//mrevealradius is the radius of the circle, will gradually become larger
mpath.addcircle (Mcenterx, Mcentery , Mrevealradius, Path.Direction.CW);
Canvas.clippath (This.mpath);
Boolean bool2 = Super.drawchild (Canvas, Paramview, paramlong);
Canvas.restoretocount (i);
return bool2;
}

According to the above, there must be something similar to the timer, can constantly change the radius of the circle, and then refresh, in fact, this is found in the code is easy to find. There is no other code in the revealframelayout except this drawchild. So let's look at Revealfollowbutton.

Revealfollowbutton, it's all about the timer.

A animator object, in fact this code I do not understand, but the logic is very simple, set a animator, timed 500ms, in this process to modify the circle radius, and then refresh.

Math.hypot (GetWidth (), GetHeight ()))

This method is based on the Pythagorean theorem to get the length of the hypotenuse of the triangle, think we want to draw the circle of the longest radius is how much, yes, is the diagonal length of the textview. So the whole logic is simple.

I got the code, that's it.

The code for the entire method is as follows, including controlling FOLLOWTV and UNFOLLOWTV which display

protected void Setfollowed (Boolean isfollowed, Boolean needanimate) {
misfollowed = isfollowed;
if (isfollowed) {
Munfollowtv.setvisibility (view.visible);
Mfollowtv.setvisibility (view.visible);
Mfollowtv.bringtofront ();
} else {
Munfollowtv.setvisibility (view.visible);
Mfollowtv.setvisibility (view.visible);
Munfollowtv.bringtofront ();
}
if (needanimate) {
Valueanimator animator = Objectanimator.offloat (mfollowtv, "empty", 0.0F, (float) math.hypot (Getmeasuredwidth (), Getmeasuredheight ()));
Animator.setduration (500L);
Animator.addupdatelistener (New Valueanimator.animatorupdatelistener () {
@Override
public void Onanimationupdate (Valueanimator animation) {
Mrevealradius = (Float) animation.getanimatedvalue ();
Invalidate ();
}
});
Animator.start ();
}
}

Display the follow TextView or unfollow TextView according to the current state, and then set a timer to expand the radius of the circle to draw, according to this radius crop the canvas into a gradually larger circle, and then gradually show the content.

After this effect is realized, try to run it, it's not bad, but there's always something wrong with it. So careful observation, finally found that the effect of knowing that in the refresh, the background is not white, or before the state, such as to become attention, the background of the attention or in, and we achieve this , the background is white when refreshed.

It's a knowing.

It's mine

So still do not know that the flowing, so we are missing something. At this time to think of it, before the revealframelayout in the drawchild of a judge conditions, we do not know what its logic is doing, now it seems. That part of the logic is to deal with this, when drawing a child control, to draw two, Followtextview and Unfollowtextview, to the control with the circle brush out of the way we cut the canvas to draw slowly. Another control that serves as a background does not need to be drawn slowly, as long as it is fully drawn. So, guess here this judgment condition is to determine whether the current control is to be brushed with the circle of the control, if not, you can directly draw the line. So modify the code as follows:

Protected Boolean drawchild (Canvas Canvas, View Paramview, long Paramlong) {
if (Drawbackground (Paramview)) {
Return Super.drawchild (canvas, Paramview, Paramlong);
}
int i = Canvas.save ();
Mpath.reset ();
Mpath.addcircle (Mcenterx, Mcentery, Mrevealradius, Path.Direction.CW);
Canvas.clippath (This.mpath);
Boolean bool2 = Super.drawchild (Canvas, Paramview, Paramlong);
Canvas.restoretocount (i);
return bool2;
}

The method of judgment is as follows:

Private Boolean Drawbackground (View paramview) {
if (misfollowed && Paramview = = munfollowtv) {
return true;
else if (!misfollowed && Paramview = = mfollowtv) {
return true;
}
return false;
}

At this point, the whole effect and know that the same, refreshing process flowing, very praise. The effect is as follows










The implementation code has been uploaded to GitHub:

Https://github.com/zgzczzw/ZHFollowButton

The above is a small set to introduce the Android imitation of the client care and to remove the attention of the button click Effects to realize the details, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.