Scroroller for Android (5)-detailed explanation of scroroller call process and View re-painting

Source: Internet
Author: User

Scroroller for Android (5)-detailed explanation of scroroller call process and View re-painting
MainActivity is as follows:

package cc.ww;import android.os.Bundle;import android.widget.ImageView;import android.widget.ImageView.ScaleType;import android.widget.RelativeLayout;import android.widget.RelativeLayout.LayoutParams;import android.app.Activity;import android.content.Context;public class MainActivity extends Activity {private Context mContext;private int [] imagesArray;    private ScrollLauncherViewGroup mScrollLauncherViewGroup;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);init();}private void init(){mContext=this;imagesArray=new int []{R.drawable.a,R.drawable.b,R.drawable.c,R.drawable.d};mScrollLauncherViewGroup=new ScrollLauncherViewGroup(mContext);ImageView imageView=null;RelativeLayout.LayoutParams layoutParams=null;for (int i = 0; i < imagesArray.length; i++) {imageView=new ImageView(mContext);imageView.setScaleType(ScaleType.FIT_XY);imageView.setImageResource(imagesArray[i]);layoutParams=new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);imageView.setLayoutParams(layoutParams);mScrollLauncherViewGroup.addView(imageView);}setContentView(mScrollLauncherViewGroup);}}

ScrollLauncherViewGroup:
Package cc. ww; import android. content. context; import android. graphics. canvas; import android. util. attributeSet; import android. view. motionEvent; import android. view. view; import android. view. viewGroup; import android. widget. scroller; import android. widget. toast;/*** Scroller principle: * to move the content of a View or ViewGroup, we often use scrollTo () and scrollBy () methods. * However, the two methods are executed quickly, and it feels stiff to complete the movement in an instant. * In order to make the View or ViewGroup content move smoothly or otherwise The gradient effect can be achieved using Scroller. * In actual implementation, a scroler can be generated when we inherit and override the View or ViewGroup. It is used to control the moving process and call scrollTo () and scrollBy () together with the interpolation device Interpolator () method. * ** two main constructor methods of Scroller: * 1 public Scroller (Context context) {} * 2 public Scroller (Context context, Interpolator interpolator) {} * when the first constructor is used, a default interpolation device Interpolator * can also be used in the movement, specify the call process of Interpolator *** Scroller and View redrawing for the moving process: * 1 call public void startScroll (I Nt startX, int startY, int dx, int dy) * This method is used to prepare scroll. * For example, you have set the starting coordinate of the Movement, the sliding distance, the direction, and the duration. * This method does not really start with sliding scroll. It feels like prepareScroll () is more appropriate. ** 2 call invalidate () or postInvalidate () so that the View (ViewGroup) tree re-painting * re-painting will call the View draw () method * draw () in six steps: * 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) * the most important of which is step 3 and Step 4 * Step 3 calls onDraw () to Draw content * Step 4 calls dispatchDraw () draw a sub-View * re-painting is divided into two situations: * 2.1 re-painting of ViewGroup * after completing step 3 onDraw, in step 4, ViewGroup overwrites * parent Class View's dispatchDraw () to draw the child View, so we can continue to call: * dispatchDraw () --> drawChild () --> child. computeSc Roll (); * 2.2 redrawing of View * we noticed the "Call invalidate ()" mentioned in 2. How does it * Call computeScroll () for View? The View does not have a subview. so in the View source code, we can see that * dispatchDraw () is an empty method. therefore, its call path is different from that of ViewGroup. * If a ButtonSubClass extends Button is executed when mButtonSubClass. how does one trigger the computeScroll () method in the ButtonSubClass class when the scrollTo () method is used ??? * I am also confused here. I only need to use the online materials and source code to start from invalidate. * In general, when the View calls the invalidate () method, the entire View tree will be re-painted * from top to bottom. for example, from the Layout of the outermost layer to the Layout of the interior layer, until each sub-View. * When the View tree is re-painted, ViewGroup and View are processed by onMeasure (), onLayout (), and * onDraw. of course, the system will determine whether all three methods must be executed. If not, the system will not call them. * When the parent container of this Sub-View is re-painted, the line mentioned above will also be called: * onDraw () --> dispatchDraw () --> drawChild () --> child. computeScroll (); * The computeScroll () method is rewritten in the subview (for example, the ButtonSubClass class in this example ). * Will be called. ** 3 the redrawing of the View tree will call the computeScroll () method in the View ** 4. In the computeScroll () method * you can see the public void computeScroll () in the View source code () {} is an empty method. * The specific implementation needs to be written by yourself. in this method, we can call scrollTo () or scrollBy () * to implement moving. this method is the core of mobile. * 4.1 Use Scroller's mScroller. computescroloffset () determines whether the mobile process is completed * Note: This method is a method in Scroller, not in View !!!!!! * Public boolean computescroloffset () {} * Call this when you want to know the new location. * If it returns true, the animation is not yet finished. * loc will be altered to provide the new location. * If the return value is true, the operation is still not completed. * 4.2 If the animation does not end, call scrollTo (By) (); * slide scrolling ** 5. Call invalidate () again (). * When the invalidate () method is called, the View tree is re-painted. * This redirects to Step 1. This loop continues until computescroloffset returns false ***** for the specific slide process, see the diagram *** * ** Easy to understand: * The three core methods in the Scroller execution process can be seen from the preceding figure * mScroller. startScroll () * mScroller. computescroloffset () * view. computeScroll () * 1 in mScroller. startScroll () has made some initialization preparations for slide. * For example, start coordinates, sliding distance and direction, and duration (with default values. * In addition to this, some other things have been done in this method: * It is important to set the animation start time. ** 2 The computescroloffset () method mainly calculates the current coordinate point based on the elapsed time * and stores it in mCurrX and mCurrY values. * Because in mScroller. when the animation time is set in startScroll (), * in the computescroloffset () method, the animation time will be quite different. It is easy to * get the location of the current time and save it in the mCurrX and mCurrY variables. * In addition, this method can also determine whether the animation has ended. ** so in this example: * @ Override * public void computeScroll () {* super. computeScroll (); * if (mScroller. computescroloffset () {* scrollTo (mScroller. getCurrX (), 0); * invalidate (); *} * first execute mScroller. computescroloffset () determines whether the slide ends * 2.1 returns false, and the slide has ended. * 2.2 returns true, and the slide is not over yet. * The latest coordinate values mCurrX and mCurrY are also calculated in this method. * That is, where should I slide at the current time. * Since co Mputescroloffset () is so considerate and difficult! * So we will overwrite the View's computeScroll () method, * Call scrollTo (By) to slide there! Satisfy its painstaking efforts. * ** Note: * 1. The boundary judgment and optimization are not performed in the example, and there are bugs in this regard. * The key is to learn the Scroller process. * 2 you don't have to worry about the difference between getCurrX () and getScrollX (). The two get the same value. * Note that they belong to different classes. * getCurrX () -------> Scroller. getCurrX () * getScrollX () -----> View. getScrollX () *** references: * 0 http://androidxref.com/2.3.6/xref * 1 http://blog.csdn.net/wangjinyu501/article/details/32339379 * 2 http://blog.csdn.net/zjmdp/article/details/7713209 * 3 http://blog.csdn.net/xiaanming/article/details/17483273 * Thank you very much **/public class ScrollLauncherViewGroup extends ViewGroup {private int lastX; private int currentX; private int distanceX; private Context mContext; private Scroller mScroller; public ScrollLauncherViewGroup (Context context) {super (context); mContext = context; mScroller = new Scroller (context);} public ScrollLauncherViewGroup (Context context, AttributeSet attrs) {super (context, attrs);} public ScrollLauncherViewGroup (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle) ;}@ Overrideprotected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {super. onMeasure (widthMeasureSpec, heightMeasureSpec);}/*** Note: * 1 getWidth () and getHeight () the screen width and height are obtained * because the width and height of the control are specified as fill_parent * 2 view during layout. getScrollX (Y) () is used to obtain mScrollX (Y) * 3. After scrollTo (x, y) is called, x and y are assigned to mScrollX and mScrollY respectively. * pay attention to the rollback direction. * // @ Overrideprotected void onLayout (boolean arg0, int l, int t, int r, int B) {for (int I = 0; I <getChildCount (); I ++) {View childView = getChildAt (I); childView. layout (I * getWidth (), 0, getWidth () + I * getWidth (), getHeight () ;}@ Overrideprotected void onDraw (Canvas canvas) {super. onDraw (canvas) ;}@ Overridepublic boolean onTouchEvent (MotionEvent event) {switch (event. getAction () {case MotionEvent. ACTION_DOWN: lastX = (int) event. getX (); break; case MotionEvent. ACTION_MOVE: currentX = (int) event. getX (); distanceX = currentX-lastX; mScroller. startScroll (getScrollX (), 0,-distanceX, 0); break; case MotionEvent. ACTION_UP: // slide the finger from the right of the screen to the left. When the finger is raised, it slides to the next screen if (distanceX <0 & Math. abs (distanceX)> 50) {mScroller. startScroll (getScrollX (), 0, getWidth ()-(getScrollX () % getWidth (), 0); // slide the finger from the left to the right of the screen, sliding your finger up to the last screen} else if (distanceX> 0 & Math. abs (distanceX)> 50) {mScroller. startScroll (getScrollX (), 0,-(getScrollX () % getWidth (), 0);} break; default: break;} // re-paint the View tree invalidate (); return true;} @ Overridepublic void computeScroll () {super. computeScroll (); if (mScroller. computescroloffset () {scrollTo (mScroller. getCurrX (), 0); invalidate ();} else {if (mScroller. getCurrX () = getWidth () * (getChildCount ()-1) {Toast. makeText (mContext, "slide to the last screen", Toast. LENGTH_SHORT ). show ();}}}}




<喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHA + PGJyPgo8L3A + signature + csignature vcD4KPHA + PGJyPgo8L3A + signature + PGJyPgo8L3A + authorization + cda-vcd4kpha + PGJyPgo8L3A + authorization + cda-vcd4kpha + bWFpbi54bWzI58/co1_vcd4kpha + PC9wPgo8cHJlIGNsYXNzPQ = "brush: java; ">

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.