Android 页面滑动切换(类Launcher滑动屏幕实现)
来源:互联网 发布:linux 引导文件丢失 编辑:程序博客网 时间:2024/05/16 13:02
Android 页面滑动切换(类Launcher滑动屏幕实现)
下面的这个例子也是从网上找来的,不是自己写的,一直想学习下,但是一直没有写,以前也研究研究的是launcher的页面跳转,launcher修改--左右滑动屏幕切换源码追踪说实话,那个代码有点复杂,所以理解的也不是很透彻。看到这个例子,比较简单些,再这里学习下:
首先,看下效果图吧:虽然很花哨,都是背景图片。
看下他的布局文件:
<?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>
底部的LinearLayout是放了5个按钮,上面使用到了一个自定义的控件:MyScrollLayout下面再看下这个自定义控件:里面使用frameLayout放了5张图片。
public class MyScrollLayout extends ViewGroup{ private static final String TAG = "ScrollLayout"; private VelocityTracker mVelocityTracker; // 用于判断甩动手势 private static final int SNAP_VELOCITY = 600; private Scroller mScroller;// 滑动控制器 private int mCurScreen; private int mDefaultScreen = 0; private float mLastMotionX; private OnViewChangeListener mOnViewChangeListener; public MyScrollLayout(Context context) {super(context);init(context);}public MyScrollLayout(Context context, AttributeSet attrs) {super(context, attrs);init(context);}public MyScrollLayout(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(context);}private void init(Context context){mCurScreen = mDefaultScreen; 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.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(widthMeasureSpec); 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); } 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); } } } @Overridepublic void computeScroll() {// TODO Auto-generated method stubif (mScroller.computeScrollOffset()) { 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 { snapToDestination(); } 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;}}
首先注意,他继承了ViewGroup类,在这里面主要重写了onMeasure()、onTouchEvent()等方法,在这里使用了一个自定义的接口private OnViewChangeListener mOnViewChangeListener。看下它的定义:
public interface OnViewChangeListener {public void OnViewChange(int view);}
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);}}
在MyScrollLayout的onTouchEvent()的方法里面是对触屏事件做出的响应:
其他的代码都比较好懂了,有什么问题欢迎大家讨论,下面是代码的下载地址:
代码下载地址
- Android 页面滑动切换(类Launcher滑动屏幕实现)
- Android 页面滑动切换(类Launcher滑动屏幕实现)
- 页面滑动切换(类Launcher滑动屏幕实现)
- 页面滑动切换(类Launcher滑动屏幕实现)
- 页面滑动切换(类Launcher滑动屏幕实现)
- 页面滑动切换(类Launcher滑动屏幕实现)
- 使用ViewPage实现类launcher屏幕滑动
- 使用ViewPage实现类launcher屏幕滑动
- 使用ViewPage实现类launcher屏幕滑动
- 使用ViewPage实现类launcher屏幕滑动
- JQuery Mobile实现滑动屏幕切换页面
- Android 滑动切换页面 以及屏幕手势
- Android 滑动切换页面 以及屏幕手势
- Android 滑动切换页面 以及屏幕手势
- Android 滑动切换页面 以及屏幕手势
- Android 滑动切换页面 以及屏幕手势
- Android 滑动切换页面 以及屏幕手势
- Android 滑动切换页面 以及屏幕手势
- HTTP运行期与页面执行模型
- 深入理解js闭包
- ASP.NET数据缓存四大方案
- 【腾讯2012年实习生笔试加分题】不使用除法,由给定数组a[N]构造数组b [N],其中b[j]=a[0]*a[1]*…*a[N-1] / a[j]
- android开发之播放音乐的方法
- Android 页面滑动切换(类Launcher滑动屏幕实现)
- ip查询网址收集
- IO 流-字节流-字符流-缓冲流
- HTTP状态管理
- Android底部菜单栏 仿微博效果
- 简单的I2C协议理解
- 回车触发函数
- 每天一个反汇编,我就强力了---用vs查看汇编代码
- 判断CheckBox是否被选中,.net中javascript取服务器端控件的值