使用viewGroupe实现左右拖到的效果

来源:互联网 发布:北京美工培训班 编辑:程序博客网 时间:2024/06/15 21:42

重写了 ViewGroupe的 onlayout  onMeasure方法 然后通过onTouchEvent事件的Action_down  Action_move 和 Activion_up进行相关处理

主要方法:

随手指拖动 滚动:

case MotionEvent.ACTION_MOVE:int deltaX = (int) (mLastMotionX - x);mLastMotionX = x;//Log.e(TAG, "moving slop"+deltaX);scrollBy(deltaX, 0);break;

手指离开判断是 滚到下一屏还是 回到原位:

case MotionEvent.ACTION_UP:Log.e(TAG, "event : up");final VelocityTracker velocityTracker = mVelocityTracker;velocityTracker.computeCurrentVelocity(1000);int velocityX = (int) velocityTracker.getXVelocity();//滑动的速度Log.e(TAG, "velocityX:" + velocityX);         // 当快速滑动的时候(速度超过此值) 不必过中间点也可以划过一屏    前提当前屏不能是第一屏和最后一屏if (velocityX > SNAP_VELOCITY && mCurScreen > 0) { // Fling enough to move leftLog.e(TAG, "snap left");snapToScreen(mCurScreen - 1);} else if (velocityX < -SNAP_VELOCITY&& mCurScreen < getChildCount() - 1) {// Fling enough to move rightLog.e(TAG, "snap right");snapToScreen(mCurScreen + 1);} else {snapToDestination(); }if (mVelocityTracker != null) {mVelocityTracker.recycle();mVelocityTracker = null;}mTouchState = TOUCH_STATE_REST;break;

   通过滚到距离是否过中间点判断是否滑动回来 还是下一屏

 

public void snapToDestination() {final int screenWidth = getWidth();final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth; //计算中间分割点 是滑动一瓶 还是恢复原来的位置snapToScreen(destScreen);}
 

手指离开时滑动操作:

/** *  * 方法名称:snapToScreen 方法描述:滑动到到第whichScreen(从0开始)个界面,有过渡效果 *  * @param whichScreen */public void snapToScreen(int whichScreen) {// get the valid layout pagewhichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));//确保大于0 小于最大的一屏Log.e(TAG, "snapToScreen"+whichScreen);if (getScrollX() != (whichScreen * getWidth())) {final int delta = whichScreen * getWidth() - getScrollX();mScroller.startScroll(getScrollX(), 0, delta, 0,Math.abs(delta) * 2);mCurScreen = whichScreen;doScrollAction(mCurScreen);invalidate(); // Redraw the layout  必须在主线程调用此方法 不是UI线程 用 postInvalidate();}}

要想滑动有效果 必须重新computeScroll 方法

/* * 重新方法  请求滚动的 scrollX 和 scrollY 如不重写此方法 子视图无法更新x和y 不能产生滚动效果 *  被父类调用来请求子类更新它们的scrollX 和y,特别当子类使用Scroller进行滑动动作的时候 */@Overridepublic void computeScroll() {// TODO Auto-generated method stubif (mScroller.computeScrollOffset()) {scrollTo(mScroller.getCurrX(), mScroller.getCurrY());postInvalidate();}}

初始化操作:

public ScrollLayout(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);mScroller = new Scroller(context);// mCurScreen = mDefaultScreen;mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();System.out.println("aaaaaaaaaaaaaaaaaaaaa" + mTouchSlop);}@Override// 当这个视图为它的子类分配大小或确定位置的时候会调用此方法 左 上 右 下 子类要调layoutprotected void onLayout(boolean changed, int l, int t, int r, int b) {Log.e(TAG, "onLayout");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) {Log.e(TAG, "onMeasure");super.onMeasure(widthMeasureSpec, heightMeasureSpec);final int width = MeasureSpec.getSize(widthMeasureSpec);final int widthMode = MeasureSpec.getMode(widthMeasureSpec);if (widthMode != MeasureSpec.EXACTLY) {throw new IllegalStateException("ScrollLayout only canmCurScreen run at EXACTLY mode!");}final int heightMode = MeasureSpec.getMode(heightMeasureSpec);if (heightMode != MeasureSpec.EXACTLY) {throw new IllegalStateException("ScrollLayout only can run at EXACTLY mode!");}// The children are given the same width and height as the scrollLayoutfinal int count = getChildCount();for (int i = 0; i < count; i++) {getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);}// Log.e(TAG, "moving to screen "+mCurScreen);scrollTo(mCurScreen * width, 0);// 滑动到现在指定的屏doScrollAction(mCurScreen);//初始化时提醒现在是第几个屏幕}

 xml 配置文件:

<?xml version="1.0" encoding="utf-8"?><com.soom.scrollLayout.ScrollLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/ScrollLayoutTest"    android:layout_width="fill_parent"    android:layout_height="fill_parent" >    <LinearLayout        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:background="#FF0000" >    </LinearLayout>    <FrameLayout        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:background="#00FF00" >    </FrameLayout>    <FrameLayout        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:background="#0000FF" >    </FrameLayout></com.soom.scrollLayout.ScrollLayout>


 

原创粉丝点击