The third article today, imitating the home page of ucweb, is a dual screen that can slide left and right.
In fact, it is not difficult to achieve this effect in Android, because the official launcher already has the ready-made source code there, that is, the workspace. java. You can go to http://android.git.kernel.org/download.
What we need to do is to analyze it and streamline it (after all, we just want to slide left and right, and do not need to create shortcuts, folders, and other things, and do not need to drag and drop icons on it ).
Public class workspace extends viewgroup <br/> implements droptarget, dragsource, dragscroller {</P> <p >}</P> <p>
Therefore, neither drop nor drag is required:
Public class workspace extends viewgroup {</P> <p >}</P> <p>
At the same time, remove the methods required by those interfaces and the member variables related to drag/drop.
Let's see what member variables I have after streamlining:
Private Static final int invalid_screen =-1; </P> <p> private int mdefaultscreen; </P> <p> private Boolean mfirstlayout = true; </P> <p> private int mcurrentscreen; <br/> private int mnextscreen = invalid_screen; <br/> private scroller mscroller; </P> <p> private float mlastmotionx; <br/> private float mlastmotiony; </P> <p> private final static int touch_state_rest = 0; <br/> private final static int touch_state_scrolling = 1; </P> <p> private int mtouchstate = touch_state_rest; </P> <p> private int mtouchslop; </P> <p>
The above is enough.
There will be a lot of errors in eclipse. It doesn't matter. delete them.
Addview is a method used to add a new sub-View to the code. It is not required. You only need to specify it directly in layout XML.
Getopenfolder/getopenfolders folder is not required.
Addincurrentscreen/addwidget is useless and can be deleted.
Cell-related objects can also be deleted.
Because our code cannot directly access mscrollx, we need to replace it with getscrollx (). Pay special attention to this.
Let's take a look at the remaining methods after I simplified them:
Finally, as long as no error is reported, it will be OK.
Let's analyze several key methods, one of which is ontouchevent:
@ Override <br/> Public Boolean ontouchevent (motionevent eV) {</P> <p> final int action = eV. getaction (); <br/> final float x = eV. getx (); </P> <p> switch (Action) {<br/> case motionevent. action_down: </P> <p> If (! Mscroller. isfinished () {<br/> mscroller. abortanimation (); <br/>}</P> <p> // remember where the motion event started <br/> mlastmotionx = x; <br/> break; <br/> case motionevent. action_move: <br/> // process the screen by dragging your finger. <Br/> If (mtouchstate = touch_state_scrolling) {<br/> // scroll to follow the motion event <br/> final int deltax = (INT) (mlastmotionx-x); <br/> mlastmotionx = x; </P> <p> If (deltax <0) {<br/> If (getscrollx ()> 0) {<br/> scrollby (math. max (-1 * getscrollx (), deltax), 0); <br/>}< br/>} else if (deltax> 0) {<br/> final int availabletoscroll = getchildat (getchildcount ()-1 ). getright ()-<br/> getscrollx ()-getwidth (); <br/> If (availabletoscroll> 0) {<br/> scrollby (math. min (availabletoscroll, deltax), 0); <br/>}< br/> break; <br/> case motionevent. action_up: <br/> // after raising your finger, switch the screen processing <br/> If (mtouchstate = touch_state_scrolling) {<br/> snaptodestination (); <br/>}< br/> mtouchstate = touch_state_rest; <br/> break; <br/> case motionevent. action_cancel: <br/> mtouchstate = touch_state_rest; <br/>}</P> <p> return true; <br/>}</P> <p>
Second, snaptodestination and snaptoscreen:
Private void snaptodestination () {<br/> // calculate the screen to which you want to go <br/> final int screenwidth = getwidth (); <br/> final int whichscreen = (getscrollx () + (screenwidth/2)/screenwidth; <br/> // switch <br/> snaptoscreen (whichscreen ); <br/>}</P> <p> void snaptoscreen (INT whichscreen) {<br/> If (! Mscroller. isfinished () return; </P> <p> whichscreen = math. max (0, math. min (whichscreen, getchildcount ()-1); <br/> Boolean changingscreens = whichscreen! = Mcurrentscreen; </P> <p> mnextscreen = whichscreen; </P> <p> View focusedchild = getfocusedchild (); <br/> If (focusedchild! = NULL & changingscreens & focusedchild = getchildat (mcurrentscreen) {<br/> focusedchild. clearfocus (); <br/>}</P> <p> // enables mscroller to start the scroll <br/> final int Cx = getscrollx (); <br/> final int newx = whichscreen * getwidth (); <br/> final int Delta = newx-cx; <br/> mscroller. startscroll (CX, 0, Delta, 0, math. ABS (DELTA) * 4); <br/> invalidate (); <br/>}</P> <p>
Third, computescroll enables the workspace to scroll to the appropriate position:
@ Override <br/> Public void computescroll () {<br/> If (mscroller. computescroloffset () {<br/> scrollto (mscroller. getcurrx (), mscroller. getcurry (); <br/> postinvalidate (); <br/>} else if (mnextscreen! = Invalid_screen) {<br/> mcurrentscreen = math. max (0, math. min (mnextscreen, getchildcount ()-1); <br/> mnextscreen = invalid_screen; <br/>}</P> <p>
This is basically the case. Other methods are auxiliary and easy to understand.
In fact, there is a problem. We found that there are three points on the ucweb homepage to indicate the current location. My idea is that this indicator can be placed outside the workspace, use the current mcurrentscreen value of the workspace to display the current screen.
My layout XML description is provided:
<CN. sharetop. demo. UI. workspace <br/> Android: Id = "@ ID/friends_switcher" <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "6401_dip" <br/> Android: layout_weight = "1.0" <br/> xmessenger: defaultscreen = "0" <br/> <include layout = "@ layout/screen1"/> <br/> <include layout = "@ layout/screen2" /> </P> <p> </CN. sharetop. demo. UI. workspace> <br/> <textview <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "wrap_content" <br/> Android: textcolor = "#000000" <br/> Android: Background = "@ Android: color/transparent" <br/> Android: gravity = "center" <br/> Android: TEXT = "[1] 2"/> </P> <p>
That's it. This paging indicator is left for you to use.