Today to introduce the Android in the slide screen function of a basic implementation process and principle, and finally give you the key to explain the view of the Scrollto and Scrollby the difference between the two functions.
First, we have to understand that there is no boundary to the Android view, canvas, except that we do something about the canvas object by drawing a particular view, such as translate (translation), Cliprect (cut), etc. In order to meet our requirements for drawing the canvas object, we can call this borderless view the "view coordinates"-----It is not subject to physical screen restrictions. Usually we understand that a layout layout file is just the display area of the view, and that the display area will not be able to be displayed in the parent view, and, correspondingly, we can refer to this bounded view as a layout (layout) size assigned to the child view by the "layout coordinates" parent view. Also, the starting coordinates of a view's screen are at the beginning of the view coordinates, as shown in the following illustration.
In this way, the world is boundless, but our eyes are bound by our hearts to see the "world."
As shown below:
The black box represents the layout coordinates of the child view, and the brown box represents the view coordinate of the child view-the coordinate is infinite, beyond the area specified by the parent view to the child view, and no longer displays the excess content.
So the question is: how can we display any coordinates of our view to the central coordinates of the view? Because the layout location is only a specific piece of view content, we need to "scroll" the desired view to the layout coordinates through the Scrollto () or Scrollby () method.
The following two variables and corresponding property methods are provided in the View.java to read the scrolling values, as follows: View.java class
/**
* The offset, in pixels, by which the content of this view is scrolled
* horizontally.
* {@hide}
*/
Protected int mScrollX; //The content of the view is equivalent to the offset of the starting coordinates of the view, the direction of the X axis
/**
* The offset, in pixels, by which the content of this view is scrolled
* vertically.
* {@hide}
*/
Protected int mScrollY; //The content of this view is equivalent to the offset of the starting coordinates of the view, the direction of the Y axis
/**
* Return the scrolled left position of this view. This is the left edge of
*the displayed part of your view. You do not need to draw any pixels
* farther left, since those are 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. This is the top edge of
*the displayed part of your view. You do not need to draw any pixels above
* it, since those are outside of the frame of your view on screen.
*
* @return The top edge of the displayed part of your view, in pixels.
*/
Public final int getScrollY() {
Return mScrollY;
}
Note that the so-called "by which the content of this view is scrolled" means that the offset is implemented only for specific content in the OnDraw () method of the view, not for drawing background pictures, and so on. Specific reasons can be referenced in <android view drawing process and invalidate () and other related methods analysis >
Tip: The contents of the current view described in the following section are plotted at the layout coordinates.
public void Scrollto (int x, int y)
Description: The display (visible) area is located at (x, y) coordinates at the current view content offset to (x, y) coordinates.
The method prototype is: View.java class
/**
* 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 The x position
to scroll to * @param y the y position
to scroll to *
/public void Scrollto (int x, I NT y) {
//offset position changed
if (mscrollx!= x | | | mscrolly!= y) {
int oldx = MSCROLLX;
int oldy = mscrolly;
MSCROLLX = x; Assign a new value, save the current cheap amount
mscrolly = y;
Callback Onscrollchanged Method
onscrollchanged (MSCROLLX, mscrolly, OLDX, oldy);
if (!awakenscrollbars ()) {
invalidate ();//generally cause redraw}}} public
void Scrollby (int x, int y)
Note: When the current view content continues to offset (x, Y) units, the display (viewable) area also follows the offset (x,y) unit. The method prototype is: View.java class
/**
* 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
//
See the reason. Mscrollx and mscrolly represent the position of our current offset, continue to offset at the current position (x, y) units public
void Scrollby (int x, int y) {
Scrollto (mscrollx + x, m scrolly + y);
}
The first small demo is very simple, we focus on understanding and mastering the Scrollto () and Scrollby () function of the use and difference.
The second small demo has the appearance of launcher, can switch the screen left and right. The implementation functions are as follows: A custom viewgroup is used, the ViewGroup object contains 3 linearlayout views, and is displayed on ViewGroup with a certain layout coordinates (specified by the layout () method). Next, you can invoke the Scrollto or Scrollby () method of the ViewGroup object to toggle the specified view contents, that is, to toggle the screen. Oh, it is very fun.
The
Custom ViewGroup is as follows:
Custom ViewGroup, containing three linearlayout controls, stored in different layout locations, switching public class Multiviewgroup via Scrollby or Scrollto method extends
ViewGroup {private context mcontext;
private static String TAG = "Multiviewgroup";
Public Multiviewgroup {Super (context);
Mcontext = context;
Init ();
Public Multiviewgroup (context, AttributeSet attrs) {Super (context, attrs);
Mcontext = context;
Init ();
private void Init () {//initialization of 3 LinearLayout controls LinearLayout Onell = new LinearLayout (mcontext);
Onell.setbackgroundcolor (color.red);
AddView (Onell);
LinearLayout twoll = new LinearLayout (mcontext);
Twoll.setbackgroundcolor (Color.yellow);
AddView (Twoll);
LinearLayout Threell = new LinearLayout (mcontext);
Threell.setbackgroundcolor (Color.Blue);
AddView (Threell); }//Measure procedure @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {LOG.I (TAG, "---start onmeasure-");
Set the size of the viewgroup int width = measurespec.getsize (widthmeasurespec);
int height = measurespec.getsize (heightmeasurespec);
Setmeasureddimension (width, height);
int childcount = Getchildcount ();
LOG.I (TAG, "---onmeasure childcount is-->" + childcount);
for (int i = 0; i < ChildCount. i++) {View child = Getchildat (i);
Sets the size of each child view, which is full screen child.measure (Multiscreenactivity.screenwidth, multiscreenactivity.scrrenheight); }//Layout procedure @Override protected void OnLayout (Boolean changed, int l, int t, int r, int b) {//TOD
O auto-generated Method Stub log.i (TAG, "---start onlayout-"); int startleft = 0; The starting layout coordinate int starttop = 10 for each child view;
The spacing is set to 10px equivalent to android:margintop= "10px" int childcount = Getchildcount ();
LOG.I (TAG, "---onlayout childcount is-->" + childcount); for (int i = 0; i < ChildCount i++) {View chilD = Getchildat (i); Child.layout (Startleft, starttop, Startleft + multiscreenactivity.screenwidth, Starttop + MULTISCR
Eenactivity.scrrenheight); Startleft = Startleft + multiscreenactivity.screenwidth;
Calibrate the starting layout position of each child view//Three The distribution of the views in the screen below [0, 320]/[320,640]/[640,960]}}
About the setting/value of Scrollto () and Scrollby () and offset coordinates
The primary role of the Scrollto () and Scrollby () is to move the view/viewgroup to the specified coordinates and save the offset. Other than that:
The MSCROLLX represents the offset coordinate of the x-axis direction, and the mscrolly represents the offset coordinates of the Y axis.
About the offset of the settings we can refer to the source code:
package com.qin.customviewgroup; public class View {.... protected int mscrollx; The view content corresponds to the offset of the starting coordinate of the view, the x-axis direction protected int mscrolly;
The view content corresponds to the offset of the starting coordinate of the view, the y-axis direction//return value public final int getscrollx () {returns MSCROLLX;
Public final int getscrolly () {return mscrolly; The public void Scrollto (int x, int y) {//offset position has changed if (mscrollx!= x | | mscrolly!= y) {int oldx = MS
CROLLX;
int oldy = mscrolly; MSCROLLX = x;
Assign a new value, save the current cheap amount mscrolly = y;
Callback Onscrollchanged Method Onscrollchanged (Mscrollx, mscrolly, OLDX, Oldy); if (!awakenscrollbars ()) {invalidate ();///generally cause redrawing}}//See the reason. Mscrollx and mscrolly represent the position of our current offset, continue to offset at the current position (x, y) units public void Scrollby (int x, int y) {Scrollto (mscrollx + x, m
scrolly + y);
}
//...
}
So, at any moment, we can get the offset position of the view/viewgroup, that is, call the Getscrollx () method and the Getscrolly () method
Introduction to the Scroller class
in the first time to see launcher slide screen, I was scroller class of learning feel very egg pain, completely lost the desire to continue research. Today, there is no way, you have to look back at the Launcher module, basically launcher most of the classes and functions to master. Of course, also spent a day to learn launcher in the sliding screen to achieve, basically the industry is to brush off the clouds to see the truth.
We know that we want to offset a view to the specified coordinates (X,Y), using the Scrollto () method to call directly OK, but we can not ignore the side effects of the method itself: very quickly to the View/viewgroup offset to the target point, Without any control over the migration process, it may not be very friendly to the user. Thus, based on this migration control, the Scroller class is designed, and the main function of the class is to develop a certain control flow for the offset process (we will know more later), thus making the offset smoother and more perfect.
Perhaps the above said the comparison poised, the truth also did not speak through. Below, I will help you analyze under specific situations:
Scenario: How to get to Wuhan from Shanghai?
Ordinary people may think, so easy: airplanes, ships, No. 11 bus ...
Literary people may think, small case: time and Space forbearance (the tricks of the fire), flip a somersault (Sun Dasan tricks) ...
In any case, there may be two kinds of routines that we think about:
1, there is a time control process to arrive (slow forward), corresponding to the role of scroller
Suppose to do a train, this process may include: train speed, cost cycle, etc.;
2, Instant arrival (Super God too fast, are dizzy, user experience is not very good), corresponding to the role of Scrollto ()
Simulate the implementation of the Scroller class:
It takes 10 hours to make a train from Shanghai to Wuhan, with a travel distance of 1000km and a 200/h speed. The first time control method to reach Wuhan may be as follows: We calculate the distance the train should travel at intervals (for example, 1 hours), and then call the Scrollto () method and proceed to the place. After 10 hours, we reached our destination. I believe you should have a feeling in your heart. We will analyze the source code to see the Scroller class related methods.
its source code (partial) is as follows:
Path is located in \frameworks\base\core\java\android\widget\scroller.java
public class Scroller {private int mstartx; Starting coordinate point, X axis direction private int mstarty; Starting coordinate point, Y axis direction private int mcurrx; The current coordinate point x axis, that is, the call Startscroll function, after a certain amount of time to achieve the value of private int mcurry; The current coordinate point Y axis, that is, call the Startscroll function, after a certain amount of time to achieve the value of private float mdeltax; Should continue to slide the distance, the x axis direction private float Mdeltay; Should continue to slide the distance, Y axis direction private Boolean mfinished;
Whether this slide operation has been completed, or true//constructor public scroller (context, NULL) if completed;
Public Final Boolean isfinished () {return mfinished;
//force End of this slide screen operation public final void Forcefinished (Boolean finished) {mfinished = finished;
Public final int Getcurrx () {return mcurrx; }/* Call this when you are want to know the new location. If it returns True, * The animation is not yet finished. Loc would be altered to provide the * new location. Draw control, straightReturns false to return false;
int timepassed = (int) (Animationutils.currentanimationtimemillis ()-mstarttime); if (timepassed < mduration) {switch (mmode) {case Scroll_mode:float x = (float) timepassed * m
durationreciprocal;
... mcurrx = Mstartx + math.round (x * mdeltax);
Mcurry = Mstarty + math.round (x * mdeltay);
Break
...
}
else {Mcurrx = Mfinalx;
Mcurry = Mfinaly;
Mfinished = true;
return true; //Start an animation control, by (StartX, Starty) in duration time forward (Dx,dy) units, that is, the arrival coordinates (STARTX+DX, starty+dy) out of public void startscroll (int s
TARTX, int starty, int dx, int dy, int duration) {mfinished = false;
mduration = Duration;
Mstarttime = Animationutils.currentanimationtimemillis (); Mstartx = StartX;
Mstarty = Starty; MFINALX = startx + dx;
Mfinaly = Starty + dy; Mdeltax = DX;
Mdeltay = dy;
...
}
}
Among the more important two methods are:
public void Startscroll (int startx, int starty, int dx, int dy, int duration)
Function Description: Calculates the current coordinate point according to the current elapsed time, and saves it in the Mcurrx and Mcurry values
public void Startscroll (int startx, int starty, int dx, int dy, int duration)
Function Description: Start an animation control, by (StartX, Starty) in the duration time forward (Dx,dy) units, to reach the coordinates (STARTX+DX, starty+dy) place.
PS: We strongly recommend that you take a look at the source code to facilitate follow-up understanding.
Computescroll () Method Introduction
For easy control of sliding screen control, the Android framework provides a computescroll () method to control this process. When you draw a view, the method is called in the Draw () procedure. So, in conjunction with the Scroller instance, we can get the current offset coordinates and manually offset the view/viewgroup to that location.
The Computescroll () method prototype is located in the Viewgroup.java class
/**
* Called by a parent to request "a child update it values for MSCROLLX
* and mscrolly if necessary. This would typically be done if the child is
* animating a scroll using a {@link Android.widget.Scroller scroller}
* Object.
* * is invoked by the parent view to request a child view to redraw
the public void Computescroll () {//empty method based on the offset value mscrollx,mscrolly, the custom ViewGroup must implement the method body
}
In order to achieve the offset control, the general custom View/viewgroup needs to overload the method. Its calling procedure is in the view drawing process draw (), as follows
: @Override protected void Dispatchdraw (Canvas Canvas) {
...
for (int i = 0; i < count; i++) {
final View child = Children[getchilddrawingorder (count, i)];
if ((Child.mviewflags & visibility_mask) = = VISIBLE | | child.getanimation ()!= null) {More
|= drawchild (canvas, C Hild, drawingtime);
}
}
Protected Boolean drawchild (Canvas Canvas, View Child, Long drawingtime) {
...
Child.computescroll ();
...
}
Demo Description:
We simply reused a custom viewgroup that was previously written, and, once again, we did not invoke the Scrollto () method to make an instantaneous offset. The practice is as follows:
First, invoke the scroller instance to produce an offset control (corresponding to the Startscroll () method)
Second, manually call the invalid () method to repaint, and the rest is to get the coordinates that should be offset (calculated by Computescrolloffset () corresponding to the Scroller instance) based on the current elapsed time in Computescroll (). ,
Third, the current should offset the coordinates, call the Scrollby () method to slowly move to the coordinates.
Attached: Because the slide screen is very difficult, just a simple interception of two static pictures, touch words can be achieved left and right slide cut screen.
Custom ViewGroup, containing three linearlayout controls, stored in different layout locations, switching public class Multiviewgroup via Scrollby or Scrollto method extends
ViewGroup {...//startscroll begins to move to the next screen public void Startmove () {curscreen + +;
LOG.I (TAG, "----startmove----curscreen" + curscreen);
Use animation to control the migration process, 3s inside place Mscroller.startscroll ((curScreen-1) * getwidth (), 0, GetWidth (), 0,3000);
In fact, when you click the button, the system will automatically redraw the view, we still manually add it.
Invalidate ();
Use of Scrollto one-step//scrollto (Curscreen * multiscreenactivity.screenwidth, 0); ///Is invoked by the parent view to request that the child view be redrawn based on the offset value mscrollx,mscrolly @Override public void Computescroll () {//TODO Auto-generat
Ed method Stub log.e (TAG, "Computescroll");
If true, indicates that the animation is not finished//because the front is startscroll, so the Startscroll is False if (Mscroller.computescrolloffset ()) {
LOG.E (TAG, Mscroller.getcurrx () + "= = =" + Mscroller.getcurry ());
Produces an animation effect, depending on the current value of each scroll a little Scrollto (Mscroller.getcurrx (), Mscroller.getcurry ()); LOG.E (TAG, "### getleft is" + getleft () + "### GetRight is" + GetRight ());
At this time also need to refresh view, otherwise the effect may be error postinvalidate ();
else log.i (TAG, "have done the scoller-----");
//immediately stop moving, if already more than half of the next screen, we force the slide to the next screen public void Stopmove () {LOG.V (TAG, "----stopmove----");
if (Mscroller!= null) {//If the animation is not finished, we press the end button, then we end the animation, that is, immediately slide the specified position if (!mscroller.isfinished ()) {
int scrollcurx= Mscroller.getcurrx (); Judge whether to exceed the middle position of the next screen, if reached to the next screen, otherwise keep in the original screen//So a simple formula means: Assuming that the current slide screen offset value is Scrollcurx plus the width of each screen half, divided by the width of each screen is//we The location of the target screen. If each screen width is 320dip, we slide to 500dip, it is obvious that we should reach the second screen, index value is 1//That is (+ 320/2)/320 = 1 int descscreen = (Scrollcurx
+ getwidth ()/2)/getwidth ();
LOG.I (TAG, "-mscroller.is not finished Scrollcurx +" + Scrollcurx);
LOG.I (TAG, "-mscroller.is not finished Descscreen +" + descscreen);
Mscroller.abortanimation (); Stopped the animation, we immediately slipped the target position Scrollto (Descscreen *getwidth (), 0); Curscreen = Descscreen;
Correct target screen location} else log.i (TAG, "----OK mscroller.is finished----");
}
}
...
}
How do I implement a touch screen?
In fact, there are a lot of online on the launcher to achieve the slide screen Bowen, basically also explain the truth of the comparison understand. I am also here based on my own understanding of some
Important aspects of the knowledge point to add, I hope to help you understand. To implement a slide-screen operation, it is worth considering the following aspects:
Where: Onintercepttouchevent () The main function is to control the distribution of touch events, such as the child view of the click or Slide event. All other processes are implemented in the Ontouchevent () method.
1, screen sliding according to the movement of the finger----mainly implemented in the Ontouchevent () method
2. When the finger is released, we may not be completely sliding to a screen, this is we need to manually determine the current offset to calculate the target screen (current screen or front and rear screen), and gracefully offset to the target screen (of course, with the scroller instance).
3, call Computescroll () to achieve the slow moving process.
Knowledge Point Introduction:
Velocitytracker class
Function: Calculates the rate of movement per pixel based on the touch position.
Common methods are:
public void addmovement (motionevent ev)
Function: Add Touch object motionevent to calculate the touch rate.
public void computecurrentvelocity (int units)
Function: Check the rate of movement per pixel units unit. Well, actually I don't quite understand, give a value of 1000 can.
Reference source The meaning of the units is as follows:
Parameter units:the units you would like the velocity in. A value of 1
Provides pixels per millisecond, 1000 provides pixels-per second, etc.
public float getxvelocity ()
Function: Gets the movement rate of the x-axis direction.
Viewconfiguration class
Function: Get some standard constant values about timeouts (time), sizes (size), distances (distance).
Common methods:
public int Getscalededgeslop ()
Description: Gets a touch-moving minimum pixel value. In other words, only if we exceed this value, we can handle the slide screen.
public static int Getlongpresstimeout ()
Description: Obtain a CEO by Event Listener (Onlongclicklistener) value. In other words, when you touch a view, it only exceeds the time value, which means that we should have a long press event on the view callback; otherwise, release the finger at less than this point, and perform only onclick
There's just so much I can write about, more things to refer to code comments. After mastering the knowledge I have listed above (Focus Scrollto, Scroller Class), the other aspects of knowledge are the calculation of points and points and the distribution of touch events. There is nothing to write about in this sense.
Custom ViewGroup, containing three linearlayout controls, stored in different layout locations, switching public class Multiviewgroup via Scrollby or Scrollto method extends
ViewGroup {private static String TAG = "Multiviewgroup"; private int curscreen = 0; Current screen private scroller Mscroller = null;
Scroller object Instance public Multiviewgroup (context) {super (context);
Mcontext = context;
Init ();
Public Multiviewgroup (context, AttributeSet attrs) {Super (context, attrs);
Mcontext = context;
Init ();
}//Initialize private void init () {...//initialize scroller instance Mscroller = new Scroller (mcontext); Initialize 3 LinearLayout Controls ...//initialize a minimum sliding distance of mtouchslop = Viewconfiguration.get (GetContext ()). GETSCALEDTOUCHSL
OP (); ///Is invoked by the parent view to request that the child view be redrawn based on the offset value mscrollx,mscrolly @Override public void Computescroll () {//TODO Auto-generat
Ed method Stub log.e (TAG, "Computescroll"); If true, indicates that the animation has not ended//because the front is startscroll, so only startscroll completewill be false if (Mscroller.computescrolloffset ()) {LOG.E (TAG, Mscroller.getcurrx () + "= = =" + MSCROLLER.GETCU
Rry ());
Produces an animation effect, depending on the current value of each scroll a little Scrollto (Mscroller.getcurrx (), Mscroller.getcurry ());
LOG.E (TAG, "### getleft is" + getleft () + "### GetRight is" + GetRight ());
At this time also need to refresh view, otherwise the effect may be error postinvalidate ();
else log.i (TAG, "have done the scoller-----"); }//Two states: whether in the sliding state private static final int touch_state_rest = 0; I didn't do anything. State private static final int touch_state_scrolling = 1; Start the state of the slide screen private int mtouchstate = Touch_state_rest; Default is nothing done in the state//--------------------------//Handle touch Event ~ public static int snap_velocity = 600; Minimum sliding rate private int mtouchslop = 0; Minimum sliding distance, more than, just think start sliding private float Mlastionmotionx = 0;
Remember the last touch screen position//processing touch rate private velocitytracker mvelocitytracker = null; This feeling doesn't work, either true or False will execute ontouchevent because the child view inside OntouChevent returned false @Override public boolean onintercepttouchevent (motionevent ev) {//TODO auto-generated method
Stub log.e (TAG, "onintercepttouchevent-slop:" + mtouchslop);
Final int action = Ev.getaction ();
The expression has started to slide and does not need to go to the Action_move method (which may be invoked the first time). This method is mainly used for the user to quickly release the finger, and quickly press the behavior.
This is considered to be a sliding screen state.
if (action = = motionevent.action_move) && (mtouchstate!= touch_state_rest)) {return true;
Final float x = Ev.getx ();
Final float y = ev.gety ();
Switch (action) {case MOTIONEVENT.ACTION_MOVE:LOG.E (TAG, ' onintercepttouchevent move ');
Final int xdiff = (int) math.abs (mlastionmotionx-x);
When the minimum sliding distance is exceeded, it is assumed that the Xdiff > mtouchslop {mtouchstate = touch_state_scrolling is started to slide;
} break;
Case MOTIONEVENT.ACTION_DOWN:LOG.E (TAG, "onintercepttouchevent down");
Mlastionmotionx = x;
Mlastmotiony = y; LOG.E (TAG, mscroller.isfinished ()+ ""); Mtouchstate = mscroller.isfinished ()?
touch_state_rest:touch_state_scrolling;
Break
Case MotionEvent.ACTION_CANCEL:case MOTIONEVENT.ACTION_UP:LOG.E (TAG, "onintercepttouchevent up or Cancel");
Mtouchstate = Touch_state_rest;
Break
LOG.E (TAG, mtouchstate + "= =" + touch_state_rest);
return mtouchstate!= touch_state_rest;
public boolean ontouchevent (Motionevent event) {super.ontouchevent (event);
LOG.I (TAG, "---ontouchevent-->");
TODO auto-generated Method Stub log.e (TAG, "ontouchevent start");
Gets the Velocitytracker object and adds a sliding object if (Mvelocitytracker = = null) {Mvelocitytracker = Velocitytracker.obtain ();
} mvelocitytracker.addmovement (event);
Touch Point Float x = Event.getx ();
Float y = event.gety (); Switch (event.getaction ()) {case Motionevent.action_down://If the screen animation is not finished, you press, we end the last animation, that is, to start the new Action_down animation
if (Mscroller!= null) {if (!mscroller.isfinished ()) {mscroller.abortanimation (); } Mlastionmotionx = x;
Remember the start of the screen Point break; Case MotionEvent.ACTION_MOVE:int detax = (int) (MLASTIONMOTIONX-X); Each time you slide the screen, the screen should move the distance Scrollby (detax, 0);//start slowly sliding the screen.
Detax > 0 slide to the right, Detax < 0 to the left, LOG.E (TAG, "---motionevent.action_move--> detax is" + detax);
Mlastionmotionx = x;
break;
Case MotionEvent.ACTION_UP:final Velocitytracker velocitytracker = Mvelocitytracker;
Velocitytracker.computecurrentvelocity (1000);
COMPUTE rate int Velocityx = (int) velocitytracker.getxvelocity ();
LOG.E (TAG, "---velocityx---" + velocityx); The sliding rate reached a standard (quickly slide to the right, return to the previous screen) and immediately cut screen processing if (Velocityx > snap_velocity && curscreen > 0) {//
Fling enough to move left LOG.E (TAG, ' snap left '); Snaptoscreen (CURSCREEN-1);
//Fast to Zoshi, back to next screen) else if (Velocityx <-snap_velocity && Curscreen < (Getchildcount ()-1)) {
LOG.E (TAG, "snap Right");
Snaptoscreen (Curscreen + 1);
}//above for fast moving, Force toggle screen else{//We are moving slowly, so first decide whether to keep on this screen or to the next screen snaptodestination ();
///Recycle Velocitytracker object if (mvelocitytracker!= null) {mvelocitytracker.recycle ();
Mvelocitytracker = null;
}//correction mtouchstate value mtouchstate = touch_state_rest;
Break
Case MotionEvent.ACTION_CANCEL:mTouchState = touch_state_rest;
Break
return true;
////We are moving slowly, so we need to determine which is the target screen based on the offset value?
private void Snaptodestination () {//current offset position int scrollx = GETSCROLLX ();
int scrolly = getscrolly ();
LOG.E (TAG, "### ontouchevent snaptodestination ### scrollx is" + scrollx); To determine whether to exceed the middle position of the next screen, if reached on the next screen, otherwise remain in the original screen//direct useThis formula determines whether or not the screen is above or below the middle position of the next screen. If reached to the next screen, otherwise remain in the original screen//This simple formula means: Suppose the current sliding screen offset value is Scrollcurx plus the width of each screen half, divided by each screen The width of the screen is//the location of our target screen. If each screen width is 320dip, we slide to 500dip, obviously we should reach the second screen int destscreen = (GETSCROLLX () + MULTISCREENACTIVITY.SCREENWIDTH/2)/M
Ultiscreenactivity.screenwidth;
LOG.E (TAG, "### ontouchevent action_up### dx destscreen" + destscreen);
Snaptoscreen (Destscreen);
//True implementation of the method of the jump screen private void snaptoscreen (int whichscreen) {//simple move to the target screen, may be the current screen or next screen//Direct jump past, not very friendly
Scrollto (Mlastscreen * multiscreenactivity.screenwidth, 0);
For the sake of friendliness, we are adding an animated effect//need to slide again the distance screen or the next screen continues to slide away curscreen = Whichscreen;
Prevents the screen from crossing over, that is, exceeding the screen number if (Curscreen > Getchildcount ()-1) Curscreen = Getchildcount ()-1;
In order to reach the next screen or the current screen, we need to continue to slide the distance. Depending on the DX value, you may want to slide left, or it may be like sliding int dx = Curscreen * getwidth ()-GETSCROLLX ();
LOG.E (TAG, "### ontouchevent action_up### dx is" + dx);Mscroller.startscroll (GETSCROLLX (), 0, DX, 0,math.abs (DX) * 2);
Because the touch event does not redraw view, it is not effective to manually refresh the view at this time invalidate ();
//Start sliding to next screen public void Startmove () {...}
Understanding stop sliding public void stopmove () {...}
Measure procedure @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {...}
Layout procedure @Override protected void OnLayout (Boolean changed, int l, int t, int r, int b) {...}
}