仿qq侧滑删除的一个自定义View,独立的,不需要依赖其他的view
来源:互联网 发布:屏幕录像 知乎 编辑:程序博客网 时间:2024/06/07 01:49
最近在看任玉刚写的自定义view方面的文章,跟着他的一片文章敲了一个仿微信侧滑删除效果的自定义view。
就是这篇:http://blog.csdn.net/singwhatiwanna/article/details/17515543
但是发现效果是实现了,可以侧滑,但是没办法实用,因为onclick和侧滑事件冲突了,当你想侧滑时,同时也触发了点击事件,所以如果你绑定了点击的监听,比如点击列表,查看详情,那么侧滑过程中页面就会跳到详情页。网上看的好多例子都是重写自定义的listview,或者item与listview都修改,来实现侧滑出现选项菜单,我想做一个简单点的,独立的侧滑控件,于是就在之前的基础上做了修改。
核心的原理就是这个自定义的view作为listview的itemview,它消费了touch事件,不把事件往上传,在onIntercetpt中判断action_down的时候不拦截,在action_move的时候判断,如果是左右的滑动事件,那么就拦截事件,如果不是就不拦截。这样放在SlideView里的具体的内容就可以监听到点击事件。这样做产生的一个弊端就是,listview的onitemclick等时间就不能用了,没办法,因为SlideView消费了touch事件,如果要用的话,作为父view的listview等view就不会再处理这个点击事件了,所以这些监听就会失效,但是可以的adapter里的getItemView中去convertView上监听,以达到同样的效果。
下面贴一下代码吧,然后上传一个我的sample工程,如果觉得有用的可以一下载
SlideView的布局文件
<?xml version="1.0" encoding="utf-8"?><merge xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" > <LinearLayout android:id="@+id/view_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > </LinearLayout> <RelativeLayout android:id="@+id/holder" android:layout_width="120dp" android:background="#EA4D40" android:layout_height="match_parent" android:clickable="true" > <TextView android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center" android:textColor="@android:color/white" android:text="删除" /> </RelativeLayout></merge>
import java.util.ArrayList;import java.util.List;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.util.TypedValue;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.view.ViewGroup;import android.widget.LinearLayout;import android.widget.RelativeLayout;import android.widget.Scroller;import android.widget.TextView;import com.supermap.dmpc3.R;public class SlideView extends LinearLayout{private static final String TAG="SlideView";private Context context;private LinearLayout mViewContent;public LinearLayout mHolder;private Scroller mScroller;private List<OnSlideListener> mOnSlideListener;private int mHolderWidth=120;private int mLastX;private int mLastY;private boolean isMove=false;private int min=12;private static int TAN=2;// 用来控制滑动角度,仅当角度a满足如下条件才进行滑动:tan a = deltaX / deltaY > 2public SlideView(Context context) {super(context);//min=ViewConfiguration.get(context).getScaledTouchSlop();System.out.println(ViewConfiguration.getTouchSlop()+":min");mOnSlideListener=new ArrayList<SlideView.OnSlideListener>();initView();}private void initView() {context=getContext();mScroller=new Scroller(context);View.inflate(context, R.layout.slide_view_merge, this);mViewContent=(LinearLayout)findViewById(R.id.view_content);mHolder=(LinearLayout)findViewById(R.id.holder);mHolderWidth=Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources().getDisplayMetrics()));}public void setContentView(View view){mViewContent.addView(view);}public void setOnSlideListener(OnSlideListener listener){this.mOnSlideListener.add(listener);}public void shrink(){if(getScrollX()!=0){this.scrollTo(0, 0);}}@Overridepublic boolean onTouchEvent(MotionEvent event) {int x=(int)event.getX();int y=(int)event.getY();int deltaX=x-mLastX;int deltaY=y-mLastY;switch (event.getAction()) {case MotionEvent.ACTION_DOWN://手指按下,开始滑动mLastX=x;mLastY=y;if(!mScroller.isFinished()){mScroller.abortAnimation();//停止滑动}break;case MotionEvent.ACTION_MOVE:if(Math.abs(deltaX)<Math.abs(deltaY)*TAN){ //检查是是否符合横向滑动break;}int newScrollX=0;if(Math.abs(deltaX)>min){if(deltaX<0){newScrollX=mHolderWidth;}else if(newScrollX>10){newScrollX=0;}isMove=true;this.smoothScrollTo(newScrollX, 0);}break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:if(mOnSlideListener!=null && isMove){for(OnSlideListener item:mOnSlideListener){item.onSlide(this, OnSlideListener.SLIDE_STATUS_START_SCROLL);}}break;default:break;}return true;}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {int x=(int)ev.getX();int y=(int)ev.getY();int deltaX=x-mLastX;int deltaY=y-mLastY;mLastX=x;mLastY=y;boolean intercept=false;switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:intercept=false;break;case MotionEvent.ACTION_MOVE:if(Math.abs(deltaX)>Math.abs(deltaY)*TAN && Math.abs(deltaX)>min){ intercept=true;}break;case MotionEvent.ACTION_UP:intercept=false;break;default:break;}return intercept;}public SlideView(Context context, AttributeSet attrs) {super(context, attrs);}public SlideView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public interface OnSlideListener{// SlideView的三种状态:开始滑动,打开,关闭 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; /** * * @param view * * current SlideView * * @param status * * SLIDE_STATUS_ON, SLIDE_STATUS_OFF or * * SLIDE_STATUS_START_SCROLL * */ public void onSlide(View view, int status);}private void smoothScrollTo(int destX, int destY) { // 缓慢滚动到指定位置 int scrollX = getScrollX(); int delta = destX - scrollX; // 以三倍时长滑向destX,效果就是慢慢滑动 mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 2); invalidate(); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } }}
sample:http://download.csdn.net/detail/yueyakk/9494170
- 仿qq侧滑删除的一个自定义View,独立的,不需要依赖其他的view
- Android 仿QQ侧滑删除—一个满足ListView、RecyclerView以及其他View通用的侧滑删除
- 自定义View(仿QQ侧滑删除实现,ViewDragHelper)
- # 仿QQ底部导航栏的自定义view
- 一个简单的自定义View,仿圆形进度条
- 仿新浪个人信息的自定义的view
- 自定义View仿TabHost的实现(二)
- 自定义View仿TabHost的实现(一)
- 自定义View仿TabHost的实现
- 仿IOS开关自定义View的实现
- 简单的自定义View-仿SlideMenu
- 仿海报工厂效果的自定义View
- 仿雅虎新闻的加载自定义view
- 仿海报工厂效果的自定义View
- Android自定义View之仿QQ侧滑菜单实现
- 自定义view 之 仿QQ侧滑菜单
- 自定义view 跳转到其他的ViewController
- 自定义View之仿QQ消息滑动删除
- 第四周项目四(1)-程序分析
- 指针与引用
- php中require,include,use区分
- N皇后Java算法
- 慕课 springmvc拦截器
- 仿qq侧滑删除的一个自定义View,独立的,不需要依赖其他的view
- java基础之泛型
- 逆康拓展开展开
- ORACLE 数据库名、实例名、ORACLE_SID的区别
- 专题二1008
- 进程调度分析
- Mysql和oracle区别
- 嵌入式复位流程与优化(2)
- HNOI2016游记