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
- Android滑动冲突--代码
- Android滑动冲突解决
- Android滑动冲突
- Android-滑动冲突解决方案
- Android的滑动冲突
- Android滑动冲突处理
- Android滑动冲突解决方法
- Android滑动冲突解决
- Android滑动冲突解决方法
- Android滑动冲突解决
- android 滑动冲突问题
- Android滑动冲突解决方案
- Android滑动事件冲突
- android滑动冲突解决方案
- Android滑动冲突解决方案
- Android滑动事件冲突
- Android滑动冲突解决方法
- 【Android】滑动冲突解决机制
- 字符串操作strcpy、strstr、strcat函数如何实现
- WEB开发中路径的问题
- 多种JS引擎的介绍与比较
- 大二上java结课实验:模仿炸弹人的小游戏
- HDU1005
- Android滑动冲突--代码
- 判断移动网络是否连接可用!
- udp协议简单实现登录功能
- c语言中,逗号运算符的问题
- OV2685翻转问题
- 《笨办法学Python》 第26课手记
- 算法导论15.1钢条切割 练习总结
- hook模板x86/x64通用版(3)--CHook.h说明
- 多线程浅析(2)