Using scroller to achieve smooth scrolling of view

Source: Internet
Author: User

In the article "Summary of methods for realizing the movement of view", several methods to realize the movement of view are introduced: Setlayoutparams (), ScrollTo () and Scrollby (), layout (), Offsetleftandright () and Offsettopandbottom (), displacement animations and property animations. In these methods, only the displacement animation and property animation is smooth scrolling, the other methods are instantaneous to move the view to the target location, the visual experience is not very good, Android in some ViewGroup use scroller class to solve this problem, Viewpager and ScrollView, for example, use Scroller to make the sub-view smooth scrolling.

Although the scroller can make the view smooth scrolling effect, but in fact, scroller itself does not directly let the view scroll, it is passive action on the view. Here is an example of how scroller is used:

Mybutton.java

Import Android.content.context;import Android.util.attributeset;import Android.widget.button;import Android.widget.scroller;public class MyButton extends Button {private Scroller mscroller;public MyButton (Context Context, AttributeSet Attrs) {Super (context, attrs);//Instantiation Scrollermscroller = new Scroller (context);} @Overrideprotected void onsizechanged (int w, int h, int oldw, int oldh) {super.onsizechanged (W, H, OLDW, OLDH); width = w;h eight = h;} public void Startscroll (int startX, int starty, int dx, int dy, int duration) {//Scroller are initially set Mscroller.startscroll (STA RtX, starty, DX, dy, duration); invalidate ();} private int Currx, curry;private int width, height, @Overridepublic void Computescroll () {//If sliding is still in progress if (Mscroller.compute Scrolloffset ()) {Currx = Mscroller.getcurrx (); CurrY = Mscroller.getcurry (); Layout (Currx, CurrY, Currx + width, CurrY + Hei ght); invalidate ();}}}

Firstactivity.java

Import Android.app.activity;import Android.os.bundle;import Android.view.view;import Android.view.view.onclicklistener;public class Firstactivity extends Activity implements Onclicklistener {private MyButton button; @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (r.layout.activity_first); button = (MyButton) Findviewbyid (R.id.button1); Button.setonclicklistener ( this);} @Overridepublic void OnClick (View v) {button.startscroll (0, 0, 200, 0, 1500);}

Activity_first.xml

<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android"    android:layout_width= "Match_ Parent "    android:layout_height=" match_parent "    android:orientation=" vertical ">    < Com.hellomagic.learnscroller.MyButton        android:id= "@+id/button1"        android:layout_width= "Wrap_content"        android:layout_height= "wrap_content"        android:text= "button"/></linearlayout>

The effect after the run is this:

In general, the use of scroller is divided into the following steps:

    1. Create an instance of Scroller
    2. Let the view or viewgroup that needs scrolling override the Computescroll () method
    3. Call the Scroller.computescrolloffset () method in the overridden Computescroll () method to determine if the swipe is in progress
    4. Implement the view slide in the IF (Scroller.computescrolloffset ()) code block and call the Invalidate () method to notify the view redraw
    5. To start sliding, call the Scroller.startscroll () method to slide the parameter settings and call the view's invalidate () method to start sliding

Why does the call to the view's invalidate () method start sliding after the scroller Startscroll () method is called? Why does the swipe do it by itself?

As you can see, after the view calls invalidate (), if Scroller.computescrolloffset () returns True, that is, when the slide is in progress, a loop is formed, and the view is continually redrawn, and the layout continues. Each time the Scroller.computescrolloffset () is called, the scroller internally changes the values of CURRX and curry.

/** * Call this is the new location of want to know.     If it returns True, * The animation is not yet finished.        */Public Boolean computescrolloffset () {if (mfinished) {//) returns False if the swipe is finished; }
With the current time-the time at which the swipe starts = the time that the slide was made (that is, how long the slide has been) int timepassed = (int) (Animationutils.currentanimationtimemillis ()-mSt Arttime); if (timepassed < mduration) {//If sliding time < slide duration switch (mmode) {case Scroll_mode:
         The current Currx and curry final float x = Minterpolator.geti are calculated based on the time timepassed and Interpolator minteerpolator of the slide Nterpolation (timepassed * mdurationreciprocal); Mcurrx = Mstartx + math.round (x * mdeltax); Mcurry = Mstarty + math.round (x * mdeltay); Break Case fling_mode:final Float t = (float) timepassed/mduration; Final int index = (int) (Nb_samples * t); float Distancecoef = 1.f; float Velocitycoef = 0.f; if (Index < nb_samples) {final float T_inf = (float) index/nb_samples; Final float T_sup = (float) (index + 1)/nb_samples; Final float d_inf = Spline_position[index]; Final float D_sup = spline_position[index + 1]; Velocitycoef = (d_sup-d_inf)/(T_sup-t_inf); Distancecoef = D_inf + (t-t_inf) * VELOCITYCOEF; } mcurrvelocity = Velocitycoef * mdistance/mduration * 1000.0f; Mcurrx = Mstartx + Math.Round (DISTANCECOEF * (MFINALX-MSTARTX)); Pin to Mminx <= mcurrx <= Mmaxx mcurrx = Math.min (Mcurrx, Mmaxx); Mcurrx = Math.max (Mcurrx, Mminx); Mcurry = Mstarty + Math.Round (DISTANCECOEF * (Mfinaly-mstarty)); Pin to Mminy <= mcurry <= mmaxy mcurry = Math.min (Mcurry, Mmaxy); Mcurry = Math.max (Mcurry, Mminy); if (Mcurrx = = Mfinalx && Mcurry = = mfinaly) {mfinished = true; } break; }} else {//If the sliding time >= the duration of the slide Mcurrx = mfinalx; Mcurry = Mfinaly; Mfinished = true; } return true; }

Thus, the values of Scroller.getcurrx () and Scroller.getcurry () change with the time of the slide, so each call to View.layout (Currx, CurrY, Currx + width, CurrY + Height method), the position of each view will change a little bit, because in the duration time, the view each layout will move a bit of position, so it creates the view slide animation effect.

Using scroller to achieve smooth scrolling of view

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.