Scrolllayout. xml file
Package COM. teleca. robin; import android. content. context; import android. util. attributeset; import android. util. log; import android. view. motionevent; import android. view. velocitytracker; import android. view. view; import android. view. viewconfiguration; import android. view. viewgroup; import android. widget. scroller;/*** similar to the worksapce in launcher, you can slide left and right to switch the screen class ** @ author Yao. guet ** blog: http://blog.csdn.NET/Yao_GUET ** Date: */public class scrolllayout extends viewgroup
{Private Static final string tag = "scrolllayout"; private scroller mscroller; private velocitytracker mvelocitytracker; private int mcurscreen; private int mdefaultscreen = 0; Private Static final int touch_state_rest = 0; private Static final int touch_state_scrolling = 1; Private Static final int snap_velocity = 600; private int mtouchstate = touch_state_rest; private int mtouchslop; private float mlastmo Tionx; private float mlastmotiony; Public scrolllayout (context, attributeset attrs) {This (context, attrs, 0); // todo auto-generated constructor stub} public scrolllayout (context, attributeset attrs, int defstyle) {super (context, attrs, defstyle); // todo auto-generated constructor stubmscroller = new scroller (context); mcurscreen = mdefaultscreen; listener = viewconfiguration. get (getco Ntext ()). getscaledtouchslop () ;}@ overrideprotected void onlayout (Boolean changed, int L, int T, int R, int B) {// todo auto-generated method stubif (changed) {int childleft = 0; Final int childcount = getchildcount (); For (INT I = 0; I <childcount; I ++) {final view childview = getchildat (I ); if (childview. getvisibility ()! = View. gone) {final int childwidth = childview. getmeasuredwidth (); childview. layout (childleft, 0, childleft + childwidth, childview. getmeasuredheight (); childleft + = childwidth ;}}}@ overrideprotected void onmeasure (INT widthmeasurespec,
Int heightmeasurespec) {log. E (TAG, "onmeasure"); super. onmeasure (widthmeasurespec, heightmeasurespec); Final int width = measurespec. getsize (widthmeasurespec); Final int widthmode = measurespec. getmode (widthmeasurespec); If (widthmode! = Measurespec. Exactly) {Throw new illegalstateexception ("scrolllayout only canmcurscreen run at exactly mode! ");} Final int heightmode = measurespec. getmode (heightmeasurespec); If (heightmode! = Measurespec. Exactly) {Throw new illegalstateexception ("scrolllayout only can run at exactly mode! ");} // The children are given the same width and height as the scrolllayoutfinal int COUNT = getchildcount (); For (INT I = 0; I <count; I ++) {getchildat (I ). measure (widthmeasurespec, heightmeasurespec);} // log. E (TAG, "moving to screen" + mcurscreen); scrollto (mcurscreen * width, 0 );} /*** according to the position of current layout *** scroll to the destination Page. */Public void snaptodestination () {Final int screenwidth = getwidth (); Final int destscreen = (getscrollx () + screenwidth/2)/screenwidth; snaptoscreen (destscreen);} public void snaptoscreen (INT whichscreen) {// get the valid layout pagewhichscreen = math. max (0, math. min (whichscreen, getchildcount ()-1); If (getscrollx ()! = (Whichscreen * getwidth () {final int Delta = whichscreen * getwidth ()-getscrollx (); mscroller. startscroll (getscrollx (), 0,
Delta, 0, math. ABS (DELTA) * 2); mcurscreen = whichscreen; invalidate (); // redraw the layout} public void settoscreen (INT whichscreen) {whichscreen = math. max (0, math. min (whichscreen, getchildcount ()-1); mcurscreen = whichscreen; scrollto (whichscreen * getwidth (), 0);} public int getcurscreen () {return mcurscreen ;} @ overridepublic void computescroll () {// todo auto-generated method stubif (mscroller. c Omputescroloffset () {scrollto (mscroller. getcurrx (), mscroller. getcurry (); postinvalidate () ;}@ overridepublic Boolean ontouchevent (motionevent event) {// todo auto-generated method stubif (mvelocitytracker = NULL) {mvelocitytracker = velocitytracker. obtain ();} mvelocitytracker. addmovement (event); Final int action = event. getaction (); Final float x = event. getx (); Final float y = event. gety (); Switch (Action) {Case motionevent. action_down: log. E (TAG, "event down! "); If (! Mscroller. isfinished () {mscroller. abortanimation ();} mlastmotionx = x; break; Case motionevent. action_move: int deltax = (INT) (mlastmotionx-x); mlastmotionx = x; scrollby (deltax, 0); break; Case motionevent. action_up: log. E (TAG, "Event: Up"); // If (mtouchstate = touch_state_scrolling) {final velocitytracker = mvelocitytracker; velocitytracker. computecurrentvelocity (1000); int velocityx = (INT) velocitytracker. getxvelocity (); log. E (TAG, "velocityx:" + velocityx); If (velocityx> snap_velocity & mcurscreen> 0) {// fling enough to move leftlog. E (TAG, "snap left"); snaptoscreen (mcurscreen-1);} else if (velocityx <-snap_velocity & mcurscreen <getchildcount ()-1) {// fling enough to move rightlog. E (TAG, "snap right"); snaptoscreen (mcurscreen + 1);} else {snaptodestination ();} If (MVE Locitytracker! = NULL) {mvelocitytracker. recycle (); mvelocitytracker = NULL;} //} mtouchstate = touch_state_rest; break; Case motionevent. action_cancel: mtouchstate = touch_state_rest; break;} return true ;}@ overridepublic Boolean onintercepttouchevent (motionevent eV) {// todo auto-generated method stublog. E (TAG, "onintercepttouchevent-slop:" + mtouchslop); Final int action = eV. getaction (); If (Action = motionevent. acti On_move) & (mtouchstate! = Touch_state_rest) {return true;} final float x = eV. getx (); Final float y = eV. gety (); Switch (Action) {Case motionevent. action_move: Final int xdiff = (INT) math. ABS (mlastmotionx-x); If (xdiff> mtouchslop) {mtouchstate = touch_state_scrolling;} break; Case motionevent. action_down: mlastmotionx = x; mlastmotiony = y; mtouchstate = mscroller. isfinished ()? Touch_state_rest: touch_state_scrolling; break; Case motionevent. action_cancel: Case motionevent. action_up: mtouchstate = touch_state_rest; break;} return mtouchstate! = Touch_state_rest ;}}