slideview 侧滑时上下滚动 onitemclick和滑动的冲突 解决方法
2015-12-10 16:20
519 查看
初学android不久 第一次写博客 记录下。如果有错误 请提醒,万分感谢
slideview原文地址:http://blog.csdn.net/singwhatiwanna/article/details/17515543
自定义LinearLayout ,作为listview里的item 在onslidelistner中增加个正在滑动的状态 ,凭这个状态可以让侧滑的时候 让listview不滚动
自定义listview 其中的item 为slideview 重写ontouchevent 方法 由iscroll判断是否将事件传递给子view 如果是发生了侧滑 就消费这个事件不继续往下传,也就执行不了onitemclick 不过对于判断是否侧滑事件 判断可能存在问题。
个人觉得 其中需要掌握的 知识点 merge标签 :初始化xml时 消除了多余的根布局
scrollto 绝对位移 scrollby 相对位移 getscrollx getsrcolly 在viewgroup中是 内部view相对于父布局左上角的位置
ontouchevent 和onintercepttouchevent 推荐个作者博客 写的很详细 http://blog.csdn.net/yanzi1225627/article/details/22592831
slideview原文地址:http://blog.csdn.net/singwhatiwanna/article/details/17515543
自定义LinearLayout ,作为listview里的item 在onslidelistner中增加个正在滑动的状态 ,凭这个状态可以让侧滑的时候 让listview不滚动
public class SlideView extends LinearLayout { private static final String TAG = "SlideView"; private Context mContext; private LinearLayout mViewContent; private RelativeLayout mHolder; private Scroller mScroller; private OnSlideListener mOnSlideListener; private int mHolderWidth = 120; private int mLastX = 0; private int mLastY = 0; // 用来控制滑动角度,仅当角度a满足如下条件才进行滑动:tan a = deltaX / deltaY > 2 private static final int TAN = 2; //自定义监听 监听滑动过程中的各个状态 public interface OnSlideListener { //滑动结束,侧滑删除未展开 public static final int SLIDE_STATUS_OFF = 0; //开始滑动 public static final int SLIDE_STATUS_START_SCROLL = 1; //滑动结束,侧滑删除展开 public static final int SLIDE_STATUS_ON = 2; //滑动中 public static final int SLIDEING = 4; /** * @param view current SlideView * @param status SLIDE_STATUS_ON or SLIDE_STATUS_OFF */ public void onSlide(View view, int status); } public SlideView(Context context) { super(context); initView(); } public SlideView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } private void initView() { mContext = getContext(); mScroller = new Scroller(mContext); //因为用了merge标签 指定下orientation setOrientation(LinearLayout.HORIZONTAL); View.inflate(mContext, R.layout.privatelisting_delete_merge, this); mViewContent = (LinearLayout) findViewById(R.id.view_content); //根据分辨率 计算侧滑删除 具体宽度 mHolderWidth = Math.round(TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources() .getDisplayMetrics())); Log.d("mHolderWidth", String.valueOf(mHolderWidth)); } public void setButtonText(CharSequence text) { ((TextView)findViewById(R.id.delete)).setText(text); } public void setContentView(View view) { mViewContent.addView(view); } public void setOnSlideListener(OnSlideListener onSlideListener) { mOnSlideListener = onSlideListener; } //复位 public void shrink() { if (getScrollX() != 0) { this.smoothScrollTo(0, 0); } } //关键判断 public boolean onRequireTouchEvent(MotionEvent event) { boolean result=false; //当前点击的位置 和X滚动的距离 int x = (int) event.getX(); int y = (int) event.getY(); int scrollX = getScrollX(); Log.d(TAG, "x=" + x + " y=" + y +"scrollX="+scrollX); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { if (!mScroller.isFinished()) { mScroller.abortAnimation(); } if (mOnSlideListener != null) { mOnSlideListener.onSlide(this, OnSlideListener.SLIDE_STATUS_START_SCROLL); } break; } //手指移动 滚动过程中 超过mHolderWidth 就不再滚动 case MotionEvent.ACTION_MOVE: { //滚动过程中 当前位置 和上个位置 deltaX,如果向左滚为负值 向右滚为正值 int deltaX = x - mLastX; int deltaY = y - mLastY; Log.d("test11","mLastX:"+mLastX+"x:"+x+"scrollX:"+scrollX); //手指纵向移动 不做横向滑动 if (Math.abs(deltaX) < Math.abs(deltaY) * TAN) { break; } // 计算滑动终点是否合法,防止滑动越界 int newScrollX = scrollX - deltaX; if (deltaX != 0) { if (newScrollX < 0) { newScrollX = 0; } else if (newScrollX > mHolderWidth) { newScrollX = mHolderWidth; } Log.d("newScrollX:MOVE", String.valueOf(newScrollX)); this.scrollTo(newScrollX, 0); } if (mOnSlideListener != null) { mOnSlideListener.onSlide(this, OnSlideListener.SLIDEING); } break; } case MotionEvent.ACTION_UP: { //抬起手指时 大于mHolderWidth * 0.75就展开 否则回到初始位置 int newScrollX = 0; if (scrollX - mHolderWidth * 0.75 > 0) { newScrollX = mHolderWidth; } Log.d("test123", x+","+getScrollX()+","+mLastX); Log.d("newScrollX:UP", String.valueOf(newScrollX)); this.smoothScrollTo(newScrollX, 0); //通知adapter 这个item最终展开了没有 if (mOnSlideListener != null) { mOnSlideListener.onSlide(this, newScrollX == 0 ? OnSlideListener.SLIDE_STATUS_OFF : OnSlideListener.SLIDE_STATUS_ON); } if(getScrollX()<=mHolderWidth&&getScrollX()>0){ result =true; } break; } } Log.d("hjk", String.valueOf(mLastX)); Log.d("hjk", String.valueOf(mLastY)); mLastX = x; mLastY = y; return result; } private void smoothScrollTo(int destX, int destY) { // 缓慢滚动到指定位置 int scrollX = getScrollX(); int delta = destX - scrollX; mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3); invalidate(); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { Log.d("test11","123"); scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } }
自定义listview 其中的item 为slideview 重写ontouchevent 方法 由iscroll判断是否将事件传递给子view 如果是发生了侧滑 就消费这个事件不继续往下传,也就执行不了onitemclick 不过对于判断是否侧滑事件 判断可能存在问题。
public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { //按下 case MotionEvent.ACTION_DOWN: { int x = (int) event.getX(); int y = (int) event.getY(); int position = pointToPosition(x, y); Log.e(TAG, "postion=" + position); //如果是有效触点 即点击了list,得到item if (position != INVALID_POSITION) { MessageBean data = (MessageBean) getItemAtPosition(position); mFocusedItemView = data.slideView; Log.e(TAG, "FocusedItemView=" + mFocusedItemView); } } default: break; } //事件交给item,即slideview处理 if (mFocusedItemView != null) { boolean isScroll=mFocusedItemView.onRequireTouchEvent(event); //判断是否滚动 拦截掉事件不往下传递 if (isScroll) { Log.d("test123", String.valueOf(isScroll)); return true; } } return super.onTouchEvent(event); }
个人觉得 其中需要掌握的 知识点 merge标签 :初始化xml时 消除了多余的根布局
scrollto 绝对位移 scrollby 相对位移 getscrollx getsrcolly 在viewgroup中是 内部view相对于父布局左上角的位置
ontouchevent 和onintercepttouchevent 推荐个作者博客 写的很详细 http://blog.csdn.net/yanzi1225627/article/details/22592831
相关文章推荐
- Mahout学习资料整理
- 基于贪心算法的几类区间覆盖问题
- 极客书的编程教程合集
- 学习掌握oracle外表(external table)
- 内存泄漏弄个明白
- 对自定义函数使用不当的调优案例
- Spring没有对ORM模块提供自己的实现,只对JDBC和其他ORM框架进行了封装。
- JQ中的post跟get
- [UWP开发]在windows10中设置壁纸~UserProfilePersonalizationSettings
- 提高网页响应速度
- JS—简单年历表
- Bonfire: Return Largest Numbers in Arrays
- 2016年Win10重大更新RedStone版与win10 th2版有什么不同?
- OCP-1Z0-051-2015-58题
- 如何在github上创建一个开源工程
- 一种基于TLS的高级反调试技术
- 文件中类的存放
- 如何在真机上调试Android应用程序(图文详解)
- Integer等等和equals的注意之处
- 使用IOS企业版证书发布应用