Problems with the "Android Troubleshooter" Scrollto and Scrollby

Source: Internet
Author: User

First of all, you need to know that view can be extended beyond the screen, you can imagine a ListView or a GridView. This means that the view size can exceed the size of the screen. View size is the size of the canvas canvas in OnDraw (). Canvas can do transformations such as translate (), Cliprec () T, which can be said that canvas is borderless. And what we see on the screen is just part of the canvas. You can call the view's Scrollto () and Scrollby () to draw the views to the specified area. So what about the Scrollto () and Scrollby () in view?

To find out, we need to look at the source of the view.

In the view source code, MSCROLLX and mscrolly are the offsets of the view on the X and Y axes. The source notes are very clear about what Xscrollx and xscrolly represent.

    /** * The offset, in pixels, by which the content of this view is scrolled * horizontally.    * {@hide} */@ViewDebug. Exportedproperty (category = "scrolling") protected int mscrollx;     /** * The offset, in pixels, by which the content of this view is scrolled * vertically.             * {@hide} */@ViewDebug. Exportedproperty (category = "scrolling") protected int mscrolly; /** * Return The scrolled left position for this view. The the left edge of * The displayed part of your view.     You don't need to draw any pixels * farther left, since those is outside of the frame of your view on * screen.     * * @return the left edge of the displayed part of your view, in pixels.    */Public final int getscrollx () {return mscrollx; }/** * Return the scrolled top position of this view. The top edge of * The displayed part of your view. Need to draw any pixels above * it, since thoSe is outside of the frame of your view.     * * @return the top edge of the displayed part of your view, in pixels.    */Public final int getscrolly () {return mscrolly; }

Know the meaning of Mscrollx and mscrolly, and then look at the specific implementation of Scrollto () and Scrollby (), the code is as follows:

    /** * Set The scrolled position of your view.     This would cause a call to * {@link #onScrollChanged (int, int, int, int)} and the view would be * invalidated. * @param x position to scroll to * @param y the y position to scroll to */public void ScrollTo (Int. x, in            T y) {if (Mscrollx! = x | | mscrolly! = y) {int oldx = MSCROLLX;            int OldY = mscrolly;            MSCROLLX = x;            mscrolly = y;            Onscrollchanged (MSCROLLX, mscrolly, OLDX, OldY);            if (!awakenscrollbars ()) {invalidate (); }}}/** * Move the scrolled position of your view.     This would cause a call to * {@link #onScrollChanged (int, int, int, int)} and the view would be * invalidated.     * @param x The amount of pixels to scroll by horizontally * @param y the amount of pixels to scroll by vertically */public void Scrollby (int x, int y) {scrollTo (mscrollx + x, mscrolly + y); }

As you can see from the source, the inside of Scrollby () is actually called Scrollto (). In Scrollto (), onscrollchanged () and invalidate () are called.

The function of onscrollchanged () is to tell the system (which can be understood as the Android framework) that the view's Scrollto () or Scrollby () has ever been called, while Invalidate () is telling the system that the view needs to be redrawn.

Next, explore the specific implementations of onscrollchanged () and Invalidate (), which are as follows:

/** * This was called in response to a internal scroll in this view (i.e., the * View scrolled its own contents). This is typically as a result of * {@link #scrollBy (int, int.)} or {@link #scrollTo (int, int)} having been * called     .     * * @param l Current Horizontal scroll origin.     * @param t current vertical scroll origin.     * @param OLDL Previous Horizontal scroll origin.     * @param Oldt Previous Vertical scroll origin.        */protected void onscrollchanged (int l, int t, int oldl, int oldt) {mbackgroundsizechanged = true;        Final Attachinfo ai = mattachinfo;        if (AI! = null) {ai.mviewscrollchanged = true; }    }
/** * Invalidate the whole view. If The view is visible, {@link #onDraw} 'll * be called at some point in the future. This must is called from A * UI thread.     To call from a Non-ui thread, call {@link #postInvalidate ()}. */public void invalidate () {if (viewdebug.trace_hierarchy) {viewdebug.trace (this, Viewdebug.hierar        Chytracetype.invalidate); } if (Mprivateflags & (Drawn | has_bounds) = = (Drawn |            Has_bounds) {mprivateflags &= ~drawn & ~drawing_cache_valid;            Final viewparent p = mparent;            Final Attachinfo ai = mattachinfo;                if (P! = NULL && AI! = null) {final Rect r = ai.mtmpinvalrect;                R.set (0, 0, Mright-mleft, mbottom-mtop); Don ' t call invalidate--we don ' t want to internally scroll//our own bounds P.invalidat            Echild (this, r); }        }    }

Know the meaning of Scrollto () and Scrollby (), so give an example and get to know it emotionally.

Suppose there is a view, which is called Sview.

If you want to move the Sview from (0, 0) to (100, 100). Notice what is said here (0, 0) and (100, 100), referring to the coordinates of the upper-left corner of the Sview. then the offset is the distance from the origin (0, 0) to the target point (100, 100), i.e. (0, 0)-(100, 100) = (-100,-100).

Just call Sview.scrollto (-100,-100) on it. again, note that the two parameters x and y of scrollTo (int x, int y) represent an offset, at which point the reference is (0, 0).

However, there is a certain difference in Scrollby (). The reference for Scrollby () is the coordinates after the (0, 0) point plus the offset.

This describes the comparison abstract, for example. Suppose Sview calls Scrollto (-100,-100), at which point the coordinates of the upper-left corner of the Sview are (100, 100), and then the Scrollby (-20,-20) is called, at which point the upper left corner of the Sview is plotted (120, 120) in this position.

To sum up, scrollTo () is one step, and Scrollby () is gradually accumulating.


So where are mscrollx and mscrolly used?

As stated above, ScrollTo () will redraw the view, how exactly is it drawn? See the Draw () method with the following code:

    /** * Manually render this view (and all of it children) to the given Canvas.  * The view must has already do a full layout before this function is * called. When implementing a view, does not override the This method;     Instead, * you should implement {@link #onDraw}.     * * @param canvas the canvas to which the View is rendered. */public void draw (canvas canvas) {if (viewdebug.trace_hierarchy) {viewdebug.trace (this, viewdebug .        Hierarchytracetype.draw);        } final int privateflags = mprivateflags;  Final Boolean dirtyopaque = (Privateflags & dirty_mask) = = Dirty_opaque && (Mattachinfo = = NULL ||        !mattachinfo.mignoredirtystate); Mprivateflags = (privateflags & ~dirty_mask) |        Drawn;         /* * Draw Traversal performs several drawing steps which must be executed * in the appropriate order: * * 1. Draw the background * 2. If necessary, SAve The canvas ' layers to prepare for fading * 3. Draw View ' s content * 4. Draw Children * 5. If necessary, draw the fading edges and restore layers * 6. Draw decorations (scrollbars for instance) *//Step 1, draw the background, if needed int Savecoun        T            if (!dirtyopaque) {final drawable background = mbgdrawable;                if (background! = NULL) {final int scrollx = MSCROLLX;                Final int scrolly = mscrolly;                    if (mbackgroundsizechanged) {background.setbounds (0, 0, Mright-mleft, mbottom-mtop);                Mbackgroundsizechanged = false;                } if ((Scrollx | scrolly) = = 0) {background.draw (canvas);                    } else {canvas.translate (scrollx, scrolly);                    Background.draw (canvas); Canvas.translate (-SCROLLX,-scrolly);                }}}//Skip step 2 & 5 if possible (common case) Final int viewflags        = Mviewflags;        Boolean horizontaledges = (ViewFlags & fading_edge_horizontal)! = 0;        Boolean verticaledges = (ViewFlags & fading_edge_vertical)! = 0; if (!verticaledges &&!horizontaledges) {//Step 3, draw the content if (!dirtyopaque) Ondr            AW (canvas);            Step 4, Draw the children Dispatchdraw (canvas);            Step 6, Draw decorations (scrollbars) ondrawscrollbars (canvas);        We ' re done ... return;          }/* * Here we do the full fledged routine ... * (this was an uncommon case where speed matters less, * This is what we repeat some of the tests that has been * done above) */Boolean Drawtop        = false;        Boolean drawbottom = false;        Boolean drawleft = false; Boolean drawright = FALse        float topfadestrength = 0.0f;        float bottomfadestrength = 0.0f;        float leftfadestrength = 0.0f;        float rightfadestrength = 0.0f;        Step 2, save the canvas ' layers int paddingleft = Mpaddingleft;        int paddingtop = Mpaddingtop;        Final Boolean offsetrequired = Ispaddingoffsetrequired ();            if (offsetrequired) {paddingleft + = Getleftpaddingoffset ();        Paddingtop + = Gettoppaddingoffset ();        } int left = Mscrollx + paddingleft;        int right = left + Mright-mleft-mpaddingright-paddingleft;        int top = mscrolly + paddingtop;        int bottom = top + mbottom-mtop-mpaddingbottom-paddingtop;            if (offsetrequired) {right + = Getrightpaddingoffset ();        Bottom + = Getbottompaddingoffset ();        } final Scrollabilitycache scrollabilitycache = Mscrollcache;        int length = Scrollabilitycache.fadingedgelength; Clip the fade length if top andBottom fades overlap//overlapping fades produce odd-looking artifacts if (verticaledges && (top +        Length > Bottom-length)) {length = (bottom-top)/2; }//also clip horizontal fades if necessary if (Horizontaledges && (left + length > Right-leng        th)) {length = (right-left)/2;            } if (verticaledges) {topfadestrength = Math.max (0.0f, Math.min (1.0f, Gettopfadingedgestrength ()));            Drawtop = Topfadestrength >= 0.0f;            Bottomfadestrength = Math.max (0.0f, Math.min (1.0f, Getbottomfadingedgestrength ()));        Drawbottom = Bottomfadestrength >= 0.0f;             } if (horizontaledges) {leftfadestrength = Math.max (0.0f, Math.min (1.0f, Getleftfadingedgestrength ()));            Drawleft = Leftfadestrength >= 0.0f;            Rightfadestrength = Math.max (0.0f, Math.min (1.0f, Getrightfadingedgestrength ())); Drawright = RightfadEstrength >= 0.0f;        } Savecount = Canvas.getsavecount ();        int solidcolor = Getsolidcolor ();            if (Solidcolor = = 0) {Final int flags = Canvas.has_alpha_layer_save_flag;            if (drawtop) {Canvas.savelayer (left, top, right, top + length, NULL, flags);            } if (Drawbottom) {Canvas.savelayer (left, bottom-length, right, bottom, NULL, flags);            } if (Drawleft) {Canvas.savelayer (left, top, left + length, bottom, NULL, flags);            } if (drawright) {Canvas.savelayer (right-length, top, right, bottom, NULL, flags);        }} else {Scrollabilitycache.setfadecolor (solidcolor);        }//Step 3, draw the content if (!dirtyopaque) OnDraw (canvas);        Step 4, Draw the children Dispatchdraw (canvas); Step 5, draw the fade effect and restore layers final Paint p = ScroLlabilitycache.paint;        Final Matrix matrix = Scrollabilitycache.matrix;        Final Shader fade = Scrollabilitycache.shader;        Final float fadeheight = scrollabilitycache.fadingedgelength;            if (drawtop) {Matrix.setscale (1, fadeheight * topfadestrength);            Matrix.posttranslate (left, top);            Fade.setlocalmatrix (matrix);        Canvas.drawrect (left, top, right, top + length, p);            } if (Drawbottom) {Matrix.setscale (1, fadeheight * bottomfadestrength);            Matrix.postrotate (180);            Matrix.posttranslate (left, bottom);            Fade.setlocalmatrix (matrix);        Canvas.drawrect (left, bottom-length, right, bottom, p);            } if (Drawleft) {Matrix.setscale (1, fadeheight * leftfadestrength);            Matrix.postrotate (-90);            Matrix.posttranslate (left, top);            Fade.setlocalmatrix (matrix);   Canvas.drawrect (left, top, left + length, bottom, p);     } if (drawright) {Matrix.setscale (1, fadeheight * rightfadestrength);            Matrix.postrotate (90);            Matrix.posttranslate (right, top);            Fade.setlocalmatrix (matrix);        Canvas.drawrect (Right-length, top, right, bottom, p);        } canvas.restoretocount (Savecount);    Step 6, Draw decorations (scrollbars) ondrawscrollbars (canvas); }


Resources

http://blog.csdn.net/qinjuning/article/details/7247126

http://blog.csdn.net/vipzjyno1/article/details/24577023

Http://developer.android.com/reference/android/view/View.html#scrollTo%28int,%20int%29


Problems with the "Android Troubleshooter" Scrollto and Scrollby

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.