The following example is also obtained from the Internet. I did not write it myself. I always wanted to learn it, but I didn't write it. I used to study the page Jump of launcher, launcher modification-source code tracking for switching between the left and right sliding screens to tell the truth, that code is a bit complicated, so it is not very thorough understanding. It is easier to see this example. Here we will learn:
First of all, let's take a look: although it's pretty fancy, It's all background images.
View the layout file:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <com.genius.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"> <FrameLayout android:background="@drawable/guide01" android:layout_width="fill_parent" android:layout_height="fill_parent"> </FrameLayout> <FrameLayout android:background="@drawable/guide02" android:layout_width="fill_parent" android:layout_height="fill_parent"> </FrameLayout> <FrameLayout android:background="@drawable/guide03" android:layout_width="fill_parent" android:layout_height="fill_parent"> </FrameLayout> <FrameLayout android:background="@drawable/guide04" android:layout_width="fill_parent" android:layout_height="fill_parent"> </FrameLayout> <FrameLayout android:background="@drawable/guide05" android:layout_width="fill_parent" android:layout_height="fill_parent"> </FrameLayout> </com.genius.scroll.MyScrollLayout> <LinearLayout android:orientation="horizontal" android:id="@+id/llayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="24.0dip" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"> <ImageView android:clickable="true" android:padding="15.0dip" android:layout_gravity="center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/guide_round" /> <ImageView android:clickable="true" android:padding="15.0dip" android:layout_gravity="center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/guide_round" /> <ImageView android:clickable="true" android:padding="15.0dip" android:layout_gravity="center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/guide_round" /> <ImageView android:clickable="true" android:padding="15.0dip" android:layout_gravity="center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/guide_round" /> <ImageView android:clickable="true" android:padding="15.0dip" android:layout_gravity="center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/guide_round" /> </LinearLayout> </RelativeLayout>
At the bottom of linearlayout, five buttons are put, and a custom control is used above: myscrolllayout. Next, let's look at this custom control: framelayout has five images in it.
Public class myscrolllayout extends viewgroup {Private Static final string tag = "scrolllayout"; private velocitytracker mvelocitytracker; // used to determine the animation gesture Private Static final int snap_velocity = 600; private scroller mscroeller; // sliding controller private int mcurscreen; private int mdefaultscreen = 0; private float mlastmotionx; private onviewchangelistener monviewchangelistener; Public myscrolllayout (context Co Ntext) {super (context); Init (context);} public myscrolllayout (context, attributeset attrs) {super (context, attrs); Init (context );} public myscrolllayout (context, attributeset attrs, int defstyle) {super (context, attrs, defstyle); Init (context);} private void Init (context) {mcurscreen = mdefaultscreen; mscroller = new scroller (context) ;}@ overrideprotected void onlayout (Boolean Cha Nged, 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 childdview = 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) {// 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) {log. E (TAG, "snap left"); snaptoscreen (mcurscreen-1);} else if (velocityx <-snap_velocity & mcurscreen <getchildcount ()-1) {log. E (TAG, "snap right"); snaptoscreen (mcurscreen + 1);} else {snaptop Estination ();} If (mvelocitytracker! = NULL) {mvelocitytracker. recycle (); mvelocitytracker = NULL;} 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 ;}}
First of all, he inherits the viewgroup class. Here he mainly overrides onmeasure (), ontouchevent (), and other methods. Here he uses a custom interface private onviewchangelistener monviewchangelistener. Let's take a look at its definition:
public interface OnViewChangeListener {public void OnViewChange(int view);}
This interface defines a callback method: the specific implementation of onviewchange () is in the main activity:
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 = (LinearLayout) findViewById(R.id.llayout); 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);}}
This onviewchange () method mainly calls the setcurpoint () method to complete the page Jump. The snaptoscreen () method in myscrolllayout is a typical callback method:
public 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); } } }
mOnViewChangeListener.OnViewChange(mCurScreen);
This code is a typical callback.
In the ontouchevent () method of myscrolllayout, it is a response to the touch screen event:
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) { Log.e(TAG, "snap left"); snapToScreen(mCurScreen - 1); } else if (velocityX < -SNAP_VELOCITY && mCurScreen < getChildCount() - 1) { Log.e(TAG, "snap right"); snapToScreen(mCurScreen + 1); } else { snapToDestination(); } if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } break; }
Make different responses by judging the moving distance and the moving direction.
Other codes are easy to understand. You are welcome to discuss any issues. The following is the code:
Http://download.csdn.net/detail/aomandeshangxiao/4017928