Android滑动冲突--代码

来源:互联网 发布:c语言vector用法 编辑:程序博客网 时间:2024/05/17 18:25

Android滑动冲突解决的实现

在之前的章节Anddroid滑动冲突中我们分析了Android的滑动冲突的解决办法,本节贴出实现的代码供参考,代码中注释的比较详细,就不再过多介绍。

在这段代码中,我们自定义了一个可以水平滚动的ViewGroup,然后在该ViewGroup中放入listview以制造滑动冲突,自定义控件如下代码所示:

package com.example.zhangyi.hdct;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.VelocityTracker;import android.view.View;import android.view.ViewGroup;import android.widget.Scroller;/** * Created by ZhangYi on 2016/1/28. */public class HorizontalView extends ViewGroup{    private Scroller mScroller;//滑动    private VelocityTracker mVelocityTracker;//速度追踪    private int mLastInterceptX = 0;    private int mLastInterceptY = 0;    private int mLastTouchX = 0;    private int mLastTouchY = 0;    private int mChildWidth; //记录child的宽度    private int mChildSize; //记录child的个数    private int mChildIndex;    //记录当前chld的偏移量    public HorizontalView(Context context) {        super(context);        init();    }    public HorizontalView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    private void init() {        if(mScroller == null){            mScroller = new Scroller(getContext());            mVelocityTracker = VelocityTracker.obtain();        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);        measureChildren(widthMeasureSpec,heightMeasureSpec);        int childCount = getChildCount();        if(childCount == 0){            setMeasuredDimension(0,0);        }else if(heightSpecMode == MeasureSpec.AT_MOST && widthSpecMode == MeasureSpec.AT_MOST){            //即如果宽高都是wrap_content,那么测量的宽应该是单个子view的宽度乘以个数,高为单个view的高度            View view = getChildAt(0);            heightSpecSize = view.getMeasuredHeight();            widthMeasureSpec = view.getMeasuredWidth()*childCount;//假定所有子view的宽度相同            setMeasuredDimension(widthSpecSize,heightSpecSize);        }else if(heightSpecMode ==MeasureSpec.AT_MOST){            //高是wrap_content,那么高度应该是单个子view的高度,宽度为屏幕宽度            View view = getChildAt(0);            heightSpecSize = view.getMeasuredHeight();            setMeasuredDimension(widthSpecSize,heightSpecSize);        }else if(widthSpecMode == MeasureSpec.AT_MOST){            //宽是wrap_content,那么高度应该是屏幕高度,宽度为子view的宽度乘以个数            View view = getChildAt(0);            widthSpecSize = view.getMeasuredWidth()*childCount;            setMeasuredDimension(widthSpecSize,heightSpecSize);        }    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        //放置元素        int childLeft = 0;        int childCount = getChildCount();        mChildSize = childCount;        for (int i = 0 ; i < childCount ; i ++ ){            View view = getChildAt(i);            int childWidth = view.getMeasuredWidth();            mChildWidth = childWidth;            view.layout(childLeft,0,childLeft+childWidth,view.getMeasuredHeight());            childLeft += childWidth;        }    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        boolean intercept = false;        int x = (int) ev.getX();//获取当前手指位置的X坐标        int y = (int) ev.getY();//获取当前手指位置的Y坐标        switch(ev.getAction()){            case MotionEvent.ACTION_DOWN:                //当点击事件发生时,首先判断之前的滑动过程是否结束                intercept = false;                if(!mScroller.isFinished()){                    mScroller.abortAnimation();                    intercept = true;                }                break;            case MotionEvent.ACTION_MOVE:                //判断水平滑动和垂直方向滑动的距离,如果水平距离大于垂直距离,进行拦截                int deltaX = x - mLastInterceptX;                int deltaY = y - mLastInterceptY;                if(Math.abs(deltaX) > Math.abs(deltaY)){                    //拦截,然后会调用OnTouchEvent                    intercept = true;                }else{                    intercept = false;                }                break;            case MotionEvent.ACTION_UP:                intercept = false;                break;        }        mLastInterceptX = x;        mLastInterceptY = y;        return intercept;    }    @Override    public boolean onTouchEvent(MotionEvent event) {        /**         * 对水平滑动时间进行处理         * 考虑到两种情况:         * 1.水平滑动速度比较快,则直接滑动到第二屏         * 2.水平滑动距离大于屏幕宽度一半,则也直接滑动到第二屏,否则还是当前屏         */        mVelocityTracker.addMovement(event);        int x = (int) event.getX();        int y = (int) event.getY();        switch (event.getAction()){            case MotionEvent.ACTION_DOWN:                break;            case MotionEvent.ACTION_MOVE:                break;            case MotionEvent.ACTION_UP:                int scrollX = getScrollX();//滑动的距离,相对于原始位置                mVelocityTracker.computeCurrentVelocity(1000);                float xVelocity = mVelocityTracker.getXVelocity();                //如果水平速度大于50,则滑动到下一页或者上一页                if(Math.abs(xVelocity) > 50){                    //向右滑动为正,显示上一页                    mChildIndex = xVelocity > 0 ? mChildIndex - 1 : mChildIndex + 1;                }else{                    mChildIndex = (scrollX + mChildWidth/2)/mChildWidth;                }                mChildIndex = Math.max(0,Math.min(mChildIndex,mChildSize-1));                int dx = mChildIndex*mChildWidth-scrollX;                smoothScrollBy(dx,0);                mVelocityTracker.clear();                break;        }        mLastTouchX = x;        mLastTouchY = y;        return true;    }    private void smoothScrollBy(int dx,int dy){        mScroller.startScroll(getScrollX(),0,dx,0,500);        invalidate();    }    @Override    public void computeScroll() {        if(mScroller.computeScrollOffset()){            scrollTo(mScroller.getCurrX(),mScroller.getCurrY());            postInvalidateDelayed(20);        }    }    @Override    protected void onDetachedFromWindow() {        mVelocityTracker.recycle();        super.onDetachedFromWindow();    }}

然后我们在Activity的布局中使用它,布局文件如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity">    <com.example.zhangyi.hdct.HorizontalView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="@android:color/darker_gray">        <ListView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:entries="@array/testInfo"></ListView>        <ListView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:entries="@array/testInfo"></ListView>        <ListView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:entries="@array/testInfo"></ListView>    </com.example.zhangyi.hdct.HorizontalView></LinearLayout>

其中的 android:entries=”@array/testInfo” 中的testInfo为我们在/res/values/arrays.xml中定义的数组:

<?xml version="1.0" encoding="utf-8"?><resources>    <string-array name="testInfo">        <item>hello world</item>        <item>hello world</item>        <item>hello world</item>        <item>hello world</item>        <item>hello world</item>        <item>hello world</item>        <item>hello world</item>        <item>hello world</item>        <item>hello world</item>        <item>hello world</item>        <item>hello world</item>        <item>hello world</item>        <item>hello world</item>    </string-array></resources>
0 0
原创粉丝点击