Half a month ago, I had the idea of imitating launcher. I have also searched a lot of information on the Internet and thought about how to implement it. I finally achieved this by referring to other people's information and solved my hard thoughts over the past half month, thanks again. I have posted the code for you to learn today, because there are few missing materials that are doing well in this area (because I have searched a lot of materials and cannot achieve the results). If you think it is good, please start.
First, define a viewgroup:
Public class myscrolllayout extends viewgroup {private velocitytracker mvelocitytracker; // used to judge the animation gesture Private Static final int snap_velocity = 600; private scroller mscroler; // sliding controller private int mcurscreen; private int mdefaultscreen = 0; private float mlastmotionx; // Private int mtouchslop; private onviewchangelistener monviewchangelistener; Public myscrolllayout (context) {super (context ); // Todo auto-generated constructor stubinit (context);} public myscrolllayout (context, attributeset attrs) {super (context, attrs ); // todo auto-generated constructor stubinit (context);} public myscrolllayout (context, attributeset attrs, int defstyle) {super (context, attrs, defstyle ); // todo auto-generated constructor stubinit (context);} private void Init (context) {mcurscreen = md Efaultscreen; // mtouchslop = viewconfiguration. get (getcontext ()). getscaledtouchslop (); mscroller = new scroller (context) ;}@ overrideprotected void onlayout (Boolean changed, int L, int T, int R, int B) {// todo auto-generated method stub if (changed) {int childleft = 0; Final int childcount = getchildcount (); For (INT I = 0; I <childcount; I ++) {final view childview = getchildat (I); If (childview. g Etvisibility ()! = View. gone) {final int childwidth = childview. getmeasuredwidth (); childview. layout (childleft, 0, childleft + childwidth, childview. getmeasuredheight (); childleft + = childwidth ;}}}@ overrideprotected void onmeasure (INT widthmeasurespec, int heightmeasurespec) {// todo auto-generated method stubsuper. onmeasure (widthmeasurespec, heightmeasurespec); Final int width = measurespec. getsize (widthmeasur Espec); Final int widthmode = measurespec. getmode (widthmeasurespec); Final int COUNT = getchildcount (); For (INT I = 0; I <count; I ++) {getchildat (I ). measure (widthmeasurespec, heightmeasurespec);} scrollto (mcurscreen * width, 0);} public void snaptodestination () {final int screenwidth = getwidth (); Final int destscreen = (getscrollx () + screenwidth/2)/screenwidth; snaptoscreen (destscreen);} Pu BLIC void snaptoscreen (INT whichscreen) {// get the valid layout page whichscreen = 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 if (monviewchangelistener! = NULL) {monviewchangelistener. onviewchange (mcurscreen) ;}}@ overridepublic void computescroll () {// todo auto-generated method stubif (mscroller. computescroloffset () {scrollto (mscroller. getcurrx (), mscroller. getcurry (); postinvalidate () ;}@ overridepublic Boolean ontouchevent (motionevent event) {// todo auto-generated method stub final int action = event. getaction (); Final float x = event. Getx (); Final float y = event. gety (); Switch (Action) {Case motionevent. action_down: log. I ("", "ontouchevent action_down"); If (mvelocitytracker = NULL) {mvelocitytracker = velocitytracker. obtain (); mvelocitytracker. addmovement (event);} If (! Mscroller. isfinished () {mscroller. abortanimation ();} mlastmotionx = x; break; Case motionevent. action_move: int deltax = (INT) (mlastmotionx-x); If (iscanmove (deltax) {If (mvelocitytracker! = NULL) {mvelocitytracker. addmovement (event);} mlastmotionx = x; scrollby (deltax, 0);} break; Case motionevent. action_up: int velocityx = 0; If (mvelocitytracker! = NULL) {mvelocitytracker. addmovement (event); mvelocitytracker. computecurrentvelocity (1000); velocityx = (INT) mvelocitytracker. getxvelocity ();} If (velocityx> snap_velocity & mcurscreen> 0) {// fling enough to move left snaptoscreen (mcurscreen-1 );} else if (velocityx <-snap_velocity & mcurscreen <getchildcount ()-1) {// fling enough to move right snaptoscreen (mcurscreen + 1);} else {Snaptodestination ();} If (mvelocitytracker! = NULL) {mvelocitytracker. recycle (); mvelocitytracker = NULL;} // mtouchstate = touch_state_rest; break;} return true;} private Boolean iscanmove (INT deltax) {If (getscrollx () <= 0 & deltax <0) {return false;} If (getscrollx () >=( getchildcount ()-1) * getwidth () & deltax> 0) {return false;} return true;} public void setonviewchangelistener (onviewchangelistener listener) {monviewchangelistener = listener ;}}
Public class switchviewdemoactivity extends activity implements onviewchangelistener, onclicklistener {/** called when the activity is first created. */private myscrolllayout mscrolllayout; private imageview [] mimageviews; private int mviewcount; private int mcursel; @ override public void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. main); Init ();} private void Init () {mscrolllayout = (myscrolllayout) findviewbyid (R. id. scrolllayout); linearlayout = (linearlayout) findviewbyid (R. id. llayout); // dynamically Add a layout control linearlayout layout = new linearlayout (this); layout. setlayoutparams (New layoutparams (layoutparams. fill_parent, layoutparams. fill_parent); layout. setbackgroundresource (R. drawable. guide01); mscrolllayout. addview (layout); // dynamically add an imageview control imageview = new imageview (this); imageview. setlayoutparams (New layoutparams (layoutparams. wrap_content, layoutparams. wrap_content); imageview. setpadding (15, 15, 15, 15); imageview. setimageresource (R. drawable. guide_round); linearlayout. addview (imageview); mviewcount = mscrolllayout. getchildcount (); mimageviews = new imageview [mviewcount]; for (INT I = 0; I <mviewcount; I ++) {mimageviews [I] = (imageview) linearlayout. getchildat (I); mimageviews [I]. setenabled (true); mimageviews [I]. setonclicklistener (this); mimageviews [I]. settag (I);} mcursel = 0; mimageviews [mcursel]. setenabled (false); mscrolllayout. setonviewchangelistener (this);} private void setcurpoint (INT index) {If (index <0 | index> mviewcount-1 | mcursel = index) {return ;} mimageviews [mcursel]. setenabled (true); mimageviews [Index]. setenabled (false); mcursel = index ;}@ overridepublic void onviewchange (INT view) {// todo auto-generated method stubsetcurpoint (View);} @ overridepublic void onclick (view V) {// todo auto-generated method stubint Pos = (integer) (V. gettag (); setcurpoint (POS); mscrolllayout. snaptoscreen (POS );}}
Finally, layout file:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <cn.com.karl.scroll.MyScrollLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ScrollLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/guide01" > </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/guide02" > </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/guide03" > </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/guide04" > </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/guide05" > </LinearLayout> </cn.com.karl.scroll.MyScrollLayout> <LinearLayout android:id="@+id/llayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="24.0dip" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="15.0dip" android:src="@drawable/guide_round" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="15.0dip" android:src="@drawable/guide_round" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="15.0dip" android:src="@drawable/guide_round" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="15.0dip" android:src="@drawable/guide_round" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="15.0dip" android:src="@drawable/guide_round" /> </LinearLayout></RelativeLayout>
Let's see how it works after running!