This cardstackviewpager inspiration comes from the Flippablestackview open source project above GitHub, and the effect I want to achieve is exactly the opposite of Flippablestackview, and there are some differences in detail. See the effect comparison chart below:
Flippablestackview Operation Effect Chart:
Cardstackviewpager Operation Effect Chart:
Here is a little episode, I try to implement Cardstackviewpager process, because of the beginning of Pagetransformer ontransform (View page, float position) is really confused, So I wrote an email to Flippablestackview's developer in my primary school English, and it was embarrassing that he hadn't returned my mail so far.
Back to the point, I would like to specifically talk about the implementation of Cardstackviewpager, in fact, the entire core in the following section of code, the following code to understand, You can customize your own pagetransformer to achieve a variety of viewpager effects.
The core of the Verticalstacktransformer Ontransform method final version
@Override protected void Ontransform (View page, float position) {if (position <=
0.0f) {Page.setalpha (1.0f);
LOG.E ("Ontransform", "Position <= 0.0f ==>" + position);
Page.settranslationy (0f);
When the control stops the sliding switch, only the top card can click Page.setclickable (true);
else if (position <= 3.0f) {log.e ("ontransform", "Position <= 3.0f ==>" + position); Float scale = (float) (Page.getwidth ()-screenutils.dp2px (context, Spacebetweenfirandsecwith * position))/(float) (page
. getwidth ());
Control the visibility of the card below Page.setalpha (1.0f);
When the control stops the sliding switch, only the top card can click Page.setclickable (false);
Page.setpivotx (Page.getwidth ()/2f);
Page.setpivoty (Page.getheight ()/2f);
Page.setscalex (scale);
Page.setscaley (scale); Page.settranslationy (-page.getheight () * position + (page.getheight () * 0.5f) * (1-scale) + screenutils.dp2px (context, S
pacebetweenfirandsecheight) * position); }
}
Before analyzing the above code, we need to have the following knowledge to prepare:
The first parameter of the 1.Viewpager Setpagetransformer (boolean reversedrawingorder, Viewpager.pagetransformer transformer) method, To control whether the views objects added to the Viewpager are positive or reverse, here in order to achieve the desired effect, we need to let the first view of the layout be added to the first display, so pass in true;
2.Viewpager setoffscreenpagelimit (int limit) method, set how many cached views, this will determine the effect of our card overlay display several layers of card effect.
Now we continue to look at the Ontransform (view page, float position) method, which is designed so cleverly that when I was exploring it, by printing a log to determine how the method was executed, found that the value of this position seemingly irregular, and then I thought of the previous mathematical reasoning theorem, from the special situation, and then a little bit more analysis of other situations, and then step by step to implement the code.
The first step is to analyze the position when the application initialization comes in.
The Ontransform (View page, float position) method at this point is as follows:
@Override
protected void Ontransform (View page, float position) {
log.e ("Ontransform", "position ==>" + position);
Set the Y-direction offset for each card so that the cards are completely stacked
page.settranslationy (-page.getheight () * position);
}
The corresponding log is as follows:
According to this log it is obvious to judge: because I now set the setoffscreenpagelimit (int limit) value is 4, so you can see position there are several cases, it is obvious that each position corresponds to a card, This time the interface effect as shown in the diagram:
Now that the 2,3,4,5 card is under card 1th, now we have to figure out a way to confirm our conjecture by changing the Ontransform (View page, float position) method to the following:
@Override
protected void Ontransform (View page, float position) {
log.e ("Ontransform", "position ==>" + position);
Set the card transparency
Page.setalpha (0.5f);
Set zoom midpoint
Page.setpivotx (Page.getwidth ()/2f);
Page.setpivoty (Page.getheight ()/2f);
To set the scale of the zoom this setting two adjacent cards has a scaling ratio of 0.9f
Page.setscalex ((float) Math.pow (0.9f,position));
Page.setscaley ((float) Math.pow (0.9f,position));
Set the Y-direction offset for each card so that the cards are completely stacked
page.settranslationy (-page.getheight () * position);
}
After running, it confirms our idea:
The second step is to realize the final effect of card stacking
Analysis of the above picture effect, you can find that the second card to move down a distance, you can form a card superposition of the initial effect, into the following:
Other cards, for the same reason, how do you implement this downward-offset value, how does this value behave in an expression, first look at the following a,b,c steps of the analysis diagram:
Obviously, the two-card offset is: (H2-H1) +d1, we slightly change the Ontransform (View page, float position) method as follows:
@Override
protected void Ontransform (View page, float position) {
log.e ("Ontransform", "position ==>" + position);
Page.setalpha (0.5f);
Page.setpivotx (Page.getwidth ()/2f);
Page.setpivoty (Page.getheight ()/2f);
Page.setscalex ((float) Math.pow (0.9f, position));
Page.setscaley ((float) Math.pow (0.9f, position));
Modified Code
Page.settranslationy (-page.getheight () * position + (page.getheight () * 0.5f) * (1-(float) Math.pow (0.9f, p osition)) + screenutils.dp2px (context, ten);
}
The effect at this point is shown below:
When the card translucent, the effect is not particularly obvious, the Page.setalpha (0.5f) to Page.setalpha (1.0f) and try again:
Surprise found that this is not the card overlay effect, although the effect of the details of the present there are some problems, we are not anxious, this detail of a simple analysis will think, is our scaling problem caused by the next step to optimize, we will solve this problem.
The third step is to dynamically set the scaling value according to the spacing value of the adjacent cards
The above Ontransform (View page, float position) method, our X,y scaling is written a fixed value of 0.9f, this obviously does not meet the day-to-day needs, I am here to set up the width of the next two cards as the final desired scaling ratio, Modify the Ontransform (View page, float position) method as follows:
@Override
protected void Ontransform (View page, float position) {
log.e ("Ontransform", "position ==>" + position);
Float scale = (float) (Page.getwidth ()-screenutils.dp2px (context, position))/(float) (Page.getwidth ());
Page.setalpha (1.0f);
Page.setpivotx (Page.getwidth ()/2f);
Page.setpivoty (Page.getheight ()/2f);
Page.setscalex (scale);
Page.setscaley (scale);
Modified Code
Page.settranslationy (-page.getheight () * position + (page.getheight () * 0.5f) * (1-scale) + SCREENUTILS.DP 2PX (context, ten) * position);
}
Run the program again, the perfect card effect appears:
Fourth Step , special to general, to achieve the final card sliding effect
At this point, we try to slide Viewpager, found that the card switching effect did not appear as scheduled, through many attempts and analysis, I found that because we do not have the current sliding past the card to do special treatment, here special treatment refers to: in order to achieve the card twitch switching effect, The current sliding card should not perform any scaling and offset operations, modified to Page.settranslationy (0f), the specific code is as follows:
Here is a blog: http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0814/1650.html, he mainly talked about Ontransform (View page, The understanding of position in float position)
@Override
protected void Ontransform (View page, float position) {
log.e ("Ontransform", "position ==>" + position);
if (position <= 0.0f) {
page.setalpha (1.0f);
Key code Page.settranslationy (0f) with a card twitch effect
;
} else {
float scale = (float) (Page.getwidth ()- SCREENUTILS.DP2PX (context, * position))/(float) (Page.getwidth ());
Page.setalpha (1.0f);
Page.setpivotx (Page.getwidth ()/2f);
Page.setpivoty (Page.getheight ()/2f);
Page.setscalex (scale);
Page.setscaley (scale);
Modified Code
Page.settranslationy (-page.getheight () * position + (page.getheight () * 0.5f) * (1-scale) + SCREENUTILS.DP 2PX (context, ten) * position);
}
At this point, you can already implement the animation effect at the beginning of the article. Think about it, we have been based on a special situation to write code, and finally found that he is in fact all of the general situation, but special circumstances because of his particularity is easiest to analyze the summary, more conducive to our writing easy to understand the code.
Finally, in the actual project, there may be a click area on each card, more likely the whole card is a click area, and this time will find a problem when in this situation:
I can not only point to the card 1, will also point to the card 2, card 3 ... This is definitely not going to work, so we go back to Ontransform (View page, float position) method and add a control inside:
@Override
protected void Ontransform (View page, float position) {
log.e ("Ontransform", "position ==>" + position);
if (position <= 0.0f) {
//top card can be clicked on
page.setclickable (true);
.......
} else {
//The following card is not clickable
page.setclickable (false);
........
}
}
In addition, we may only need 4 cards overlapping effect on the line, this time to change the judgment conditions can:
@Override
protected void Ontransform (View page, float position) {
log.e ("Ontransform", "position ==>" + position);
if (position <= 0.0f) {
...
Control shows several cards
, else if (position <= 3.0f) {
...
}
}
Here is the end of the article, this is my summary, I hope to help you to Ontransform (View page, float position) method has a deeper understanding.
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.