博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AndroidのListView之滑动列表项(点击事件和滑动事件共存)
阅读量:7219 次
发布时间:2019-06-29

本文共 7255 字,大约阅读时间需要 24 分钟。

这里正好在项目有这么一个bt的需求,如下图ListView的item可以响应点击事件也可以响应item的左右滑动事件,两个事件可以相互独立互不影响。

听说iphone的list选项就有这样bt的功能,安卓版的手机QQ和微信和QQ通讯录也有类似的效果,在网上各种寻早方案都试过,要不只能滑动不能点击要么就只能点击不能滑动,而且操作很不灵敏,网上的代码都是在itemView的onTouch方法里处理,判断down和up的像素差。其实这样操作相当不便,down-up这样的其实只能算拖动事件而不是滑动事件,所以你会联想到scroll和fling的区别。

大家可以看看我之前的做法,使用ontouch方法处理的,很难独立滑动事件跟点击事件,就算可以滑动也是很灵敏,操作10次难得一次成功。

class SwipeListener implements View.OnTouchListener{                ViewHolder holder;        HouseList_Item item;        int startX = 0;        int endX = 0;                public SwipeListener(ViewHolder holder, HouseList_Item item) {            super();            this.holder = holder;            this.item = item;        }        @Override        public boolean onTouch(View v, MotionEvent event) {            // TODO Auto-generated method stub                        if(event.getAction() == MotionEvent.ACTION_DOWN){                startX = (int)event.getX();                Debuger.log_e("startX", ""+startX);                return true;            }else if(event.getAction() == MotionEvent.ACTION_UP){                endX = (int)event.getX();                Debuger.log_e("endX", ""+endX);                if(startX - endX > 120){                    Debuger.log_e("触发", "左划");                    holder.llMenu.setVisibility(View.VISIBLE);                    return false;                }else if(endX - startX >120){                    Debuger.log_e("触发", "右划");                    holder.llMenu.setVisibility(View.GONE);                    return true;                }else{                    Toast.makeText(ctx, "点击item", 3000).show();                    return true;                }                           }            return true;        }            }

代码有注释相信大家都看得懂,像上面这样子也差不多让滑动事件和点击事件独立出来了。一开始还傻乎乎的用ListView的OnItemClick事件,搭配这样功能真的是碉堡。

 

经过半天的努力探索,今天终于很流畅得实现这效果。下面是新的代码:

这个是适配器的代码,有部分省略,主要是GestureDetector 这样一个手势监听器。

public class HouseList_Adapter extends BaseAdapter{    private GestureDetector detector;    private List
list ; private Context ctx = null; private LayoutInflater inflater = null; FlingListeber listener; public HouseList_Adapter( Context ctx,List
list) { super(); this.list = list; this.ctx = ctx; inflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); listener = new FlingListeber(); detector = new GestureDetector(listener); } @Override public View getView(int arg0, View arg1, ViewGroup arg2) { // TODO Auto-generated method stub ViewHolder holder = null; if(arg1==null){ arg1 = inflater.inflate(R.layout.house_item_layout, null); holder = new ViewHolder(); holder.llItem = (LinearLayout)arg1.findViewById(R.id.llItem); holder.tvTitle = (TextView)arg1.findViewById(R.id.tvTitle); holder.tvBuildeArea = (TextView)arg1.findViewById(R.id.tvArea); holder.tvPrice = (TextView)arg1.findViewById(R.id.tvPrice); holder.tvPriceUnit = (TextView)arg1.findViewById(R.id.tvPriceUnit); holder.tvRoom = (TextView)arg1.findViewById(R.id.tvRoom); holder.llFlag = (LinearLayout)arg1.findViewById(R.id.llFlag); holder.ivFlag1 = (ImageView)arg1.findViewById(R.id.ivFlag1); holder.ivFlag2 = (ImageView)arg1.findViewById(R.id.ivFlag2); holder.ivFlag3 = (ImageView)arg1.findViewById(R.id.ivFlag3); holder.ivFlag4 = (ImageView)arg1.findViewById(R.id.ivFlag4); holder.llMenu = (LinearLayout)arg1.findViewById(R.id.house_ltem_menu); holder.ivCall = (Button)arg1.findViewById(R.id.ivCall); holder.ivDetails = (Button)arg1.findViewById(R.id.ivCall); holder.ivMap = (Button)arg1.findViewById(R.id.ivMap); holder.ivSend = (Button)arg1.findViewById(R.id.ivSend); arg1.setTag(holder); }else{ holder = (ViewHolder)arg1.getTag(); } final HouseList_Item item = list.get(arg0); listener.setItem(item); //holder.llItem.setOnTouchListener(new SwipeListener(holder,item)); holder.llItem.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub return detector.onTouchEvent(event); } });      } class FlingListeber implements GestureDetector.OnGestureListener{ HouseList_Item item; ViewHolder holder; public HouseList_Item getItem() { return item; } public void setItem(HouseList_Item item) { this.item = item; } public ViewHolder getHolder() { return holder; } public void setHolder(ViewHolder holder) { this.holder = holder; } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // TODO Auto-generated method stub if(e2.getX()-e1.getX()>20){ Toast.makeText(ctx, "左滑"+item.areaName, 3000).show(); }else if(e1.getX()-e2.getX()>20){ Toast.makeText(ctx, "右滑"+item.areaName, 3000).show(); } return false; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub Toast.makeText(ctx, "点击item", 3000).show(); return false; } }}

这样让item的滑动事件交给onFling去处理,点击事件交给onSingleTapUp这样就可以让两个事件相互独立了,但是这样执行发现还是会有很不顺畅滑动的时候,后来我一想那肯定是listview的上下滑动跟item的左右滑动事件有冲突,所以就把之前定义的一个ScrollView里处理touch事件拷过去就很灵敏了,百发百中。

// 滑动距离及坐标      private float xDistance, yDistance, xLast, yLast;    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        // TODO Auto-generated method stub         switch (ev.getAction()) {           case MotionEvent.ACTION_DOWN:               xDistance = yDistance = 0f;               xLast = ev.getX();               yLast = ev.getY();               break;           case MotionEvent.ACTION_MOVE:               final float curX = ev.getX();               final float curY = ev.getY();                              xDistance += Math.abs(curX - xLast);               yDistance += Math.abs(curY - yLast);               xLast = curX;               yLast = curY;                              if(xDistance > yDistance){                   return false;               }         }          return super.onInterceptTouchEvent(ev);    }

把这段代码复制到一个ListView的扩展类里覆盖就行。

 

转载地址:http://sptym.baihongyu.com/

你可能感兴趣的文章
多个线程之间共享数据的方式(卖票问题,存取款问题)
查看>>
观察者模式
查看>>
Bzoj2882 工艺 [线性算法]
查看>>
Bzoj2251 [2010Beijing Wc]外星联络
查看>>
python 发送邮件
查看>>
在凡客四个月的工作总结
查看>>
Qt颜色下拉框
查看>>
31、springboot与任务
查看>>
【转】 一个fork的面试题
查看>>
20131108
查看>>
django.http.request中HttpRequest对象的一些属性与方法
查看>>
英文对应解释
查看>>
Robotics ToolBox机械臂仿真
查看>>
linux添加环境变量
查看>>
【uva 1312】Cricket Field(算法效率--技巧枚举)
查看>>
VS2017 MVC项目,新建控制器提示未能加载文件或程序集“Dapper.Contrib解决方法
查看>>
【ora-err】ORA-03113: end-of-file on communication channel
查看>>
00.索引-综述
查看>>
strcpy
查看>>
AC3 Rematrix
查看>>