文档章节

AndroidのListView之滑动列表项(点击事件和滑动事件共存) - bvin

andyhe91
 andyhe91
发布于 2015/06/15 15:13
字数 1234
阅读 8443
收藏 13


返回脚本百事通

这里正好在项目有这么一个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<HouseList_Item> list ;
private Context ctx = null;
private LayoutInflater inflater = null;
FlingListeber listener;

public HouseList_Adapter( Context ctx,List<HouseList_Item> 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的扩展类里覆盖就行。

 


原文链接:/link.php?url=http://www.cnblogs.com/bvin/p/3153191.html,转载请注明。




更多文章:





百度统计

为您推荐


© 著作权归作者所有

共有 人打赏支持
andyhe91
粉丝 58
博文 129
码字总数 209109
作品 0
长沙
私信 提问
Android 中 ListView 分页加载数据

熟悉Android的朋友们都知道,不管是微博客户端还是新闻客户端,都离不开列表组件,可以说列表组件是Android数据展现方面最重要的组 件,我们今天就要讲一讲列表组件ListView加载数据的相关内...

Taki
2012/08/13
0
0
安卓大神告诉我怎么让ListView的点击事件(不是item的点击事件,就点击ListView本身)和上下滑动事件共存

安卓大神告诉我怎么让ListView的点击事件(不是item的点击事件,屏蔽掉item的点击事件,就点击ListView本身)和上下滑动事件共存。

寒平洛一
2016/07/29
273
2
Android 中 ListView 分页加载数据

熟悉Android的朋友们都知道,不管是微博客户端还是新闻客户端,都离不开列表组件,可以说列表组件是Android数据展现方面最重要的组 件,我们今天就要讲一讲列表组件ListView加载数据的相关内...

鉴客
2011/10/26
21.2K
9
Android ListView两种长按弹出菜单方式

@author xianglong guo 2012-05-17 22:15 知识点1:ListView item:两种长按弹出菜单方式 知识点2:ListView SimpleAdapter的使用 知识点 3:在java代码中创建一个ListView */ Activity?代码片...

一别经年
2013/12/05
0
2
高仿微信对话列表滑动删除效果

转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/17515543 前言 用过微信的都知道,微信对话列表滑动删除效果是很不错的,这个效果我们也可以有。思路其实很简单,弄个...

长平狐
2013/12/25
6.8K
1

没有更多内容

加载失败,请刷新页面

加载更多

MySQL查询执行

当我们希望MySQL能够以更高的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的。一旦理解了这一点,很多查询优化工作实际上就是遵循一些原则让优化器能够按照预想的合理方式...

Linux就该这么学
9分钟前
0
0
爱可生开源社区官网正式发布啦!

近期大事记 2018/12/31 DBLE年度报告发版 2019/01/07 DBLE 2.18.12.0 新版发布,修复 issue 60+ 2019/01/09 DBLE 2.18.12.0 Release Notes 详细解读 2019/01/15 DBLE Logo 首发 + DBLE 团队迎......

爱可生
16分钟前
0
0
【分布式缓存系列】Redis实现分布式锁的正确姿势

一、前言   在我们日常工作中,除了Spring和Mybatis外,用到最多无外乎分布式缓存框架——Redis。但是很多工作很多年的朋友对Redis还处于一个最基础的使用和认识。所以我就像把自己对分布式...

编辑之路
27分钟前
0
0
3.x 在Unix系统上面启动守护进程

12.14 在Unix系统上面启动守护进程 问题 你想编写一个作为一个在Unix或类Unix系统上面运行的守护进程运行的程序。 解决方案 创建一个正确的守护进程需要一个精确的系统调用序列以及对于细节的...

dragon_tech
27分钟前
0
0
ES6中的class

class Point {constructor(x, y, z) {this.x = x;this.y = y;this.z = z;}toString() {return `${this.x},${this.y}`}get prop() {return `获取的是get${this.z...

chinahufei
30分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部