在上一篇文章《Android自定义组件系列【3】——自定义ViewGroup实现侧滑》中实现了仿Facebook和人人网的侧滑效果,这一篇我们将接着上一篇来实现双面滑动的效果。
1、布局示意图:
2、核心代码
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidth = MeasureSpec.getSize(widthMeasureSpec); //获取MyScrollView的宽度 mHeight = MeasureSpec.getSize(heightMeasureSpec); //获取MyScrollView的高度 if(!isLocked){ initX = getScrollX(); isLocked = true; } }在该方法中获取到初始的视图坐标偏移量getScrollX()
@Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: System.out.println("ACTION_DOWN"); mDownX = x; //记录按下时的x坐标 break; case MotionEvent.ACTION_UP: System.out.println("ACTION_UP"); int dis = (int) (x - mDownX); //滑动的距离 if(Math.abs(dis) > (mWidth * mMenuWeight / 2)){ if(dis > 0){ //如果>0则是向右滑动 toRightMove(); }else{ //如果<0则是向左滑动 toLeftMove(); } } break; default: break; } return true; }监听函数记录下按下和移动的屏幕坐标,求差计算出移动距离,如果这个距离大于阀值 (mWidth * mMenuWeight / 2)则滑动
public void toRightMove(){ System.out.println("maxRight = " + maxRight); System.out.println("X = " + getScrollX()); if(getScrollX() >= initX){ int dx = (int)(mWidth * mMenuWeight); mScroller.startScroll(getScrollX(), 0, -dx, 0, 500); if(mListener != null){ mListener.onChanged(); } invalidate(); } }如果是向右滑动则,如果当前是初始位置(centerView在中间)则可以向右滑动(getScrollX == initX),或者当前左边View可以看见,则可以向右滑动将centerView移动到中间(getScrollX > initX).同理有向左滑动的方法。
public void toLeftMove(){ System.out.println("maxLeft = " + maxLeft); System.out.println("X = " + getScrollX()); if(getScrollX() <= initX){ int dx = (int)(mWidth * mMenuWeight); mScroller.startScroll(getScrollX(), 0, dx, 0, 500); if(mListener != null){ mListener.onChanged(); } invalidate(); } }3、全部代码
MyScrollView.java
package com.example.testscrollto;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.LinearLayout;import android.widget.Scroller;public class MyScrollView extends LinearLayout{ private Context mContext; private int mWidth; private int mHeight; private float mMenuWeight = 3.0f / 5; //菜单界面比例 private View mMenuView; //菜单界面 private View mPriView; //内容界面 private View mRightView; //右边界面 private int maxLeft; private int maxRight; private int initX; private boolean isLocked = false; private Scroller mScroller; private OnMenuChangedListener mListener; public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mScroller = new Scroller(mContext); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); mMenuView.layout(-(int)(mWidth * mMenuWeight), 0, 0, mHeight); mPriView.layout(0, 0, mWidth, mHeight); mRightView.layout(mWidth, 0, mWidth + (int)(mWidth * mMenuWeight), mHeight); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidth = MeasureSpec.getSize(widthMeasureSpec); //获取MyScrollView的宽度 mHeight = MeasureSpec.getSize(heightMeasureSpec); //获取MyScrollView的高度 if(!isLocked){ initX = getScrollX(); isLocked = true; } } /**设置右滑的菜单View*/ public void setMenu(View menu){ mMenuView = menu; addView(mMenuView); } /** * 设置主界面View */ public void setPrimary(View primary){ mPriView = primary; addView(mPriView); } public void setRightView(View rightview){ mRightView = rightview; addView(mRightView); } private float mDownX; @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: System.out.println("ACTION_DOWN"); mDownX = x; //记录按下时的x坐标 break; case MotionEvent.ACTION_UP: System.out.println("ACTION_UP"); int dis = (int) (x - mDownX); //滑动的距离 if(Math.abs(dis) > (mWidth * mMenuWeight / 2)){ if(dis > 0){ //如果>0则是向右滑动 toRightMove(); }else{ //如果<0则是向左滑动 toLeftMove(); } } break; default: break; } return true; } @Override public void computeScroll() { super.computeScroll(); if(mScroller.computeScrollOffset()){ scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } public void toRightMove(){ System.out.println("maxRight = " + maxRight); System.out.println("X = " + getScrollX()); if(getScrollX() >= initX){ int dx = (int)(mWidth * mMenuWeight); mScroller.startScroll(getScrollX(), 0, -dx, 0, 500); if(mListener != null){ mListener.onChanged(); } invalidate(); } } public void toLeftMove(){ System.out.println("maxLeft = " + maxLeft); System.out.println("X = " + getScrollX()); if(getScrollX() <= initX){ int dx = (int)(mWidth * mMenuWeight); mScroller.startScroll(getScrollX(), 0, dx, 0, 500); if(mListener != null){ mListener.onChanged(); } invalidate(); } } public interface OnMenuChangedListener{ public void onChanged(); } public void setOnMenuChangedListener(OnMenuChangedListener listener){ mListener = listener; }}MainActivity.java
package com.example.testscrollto;import android.app.Activity;import android.os.Bundle;import android.view.View;import com.example.testscrollto.MyScrollView.OnMenuChangedListener;public class MainActivity extends Activity { private MyScrollView mScrollView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mScrollView = (MyScrollView)findViewById(R.id.rightscrollview); final View menu = getLayoutInflater().inflate(R.layout.rightscrollview_menu, null); final View primary = getLayoutInflater().inflate(R.layout.rightscrollview_primary, null); final View rightview = getLayoutInflater().inflate(R.layout.rightscrollview_right_menu, null); mScrollView.setMenu(menu); mScrollView.setPrimary(primary); mScrollView.setRightView(rightview); mScrollView.setOnMenuChangedListener(new OnMenuChangedListener() { @Override public void onChanged() { System.out.println("窗口切换了一次"); } }); }}activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.example.testscrollto.MyScrollView android:id="@+id/rightscrollview" android:layout_width="match_parent" android:layout_height="match_parent" /></LinearLayout>其余三个视图界面无限制,可以自由定义,这里就不贴出来了。
4、运行效果:
源代码下载:http://download.csdn.net/detail/lxq_xsyu/7232701