这里正好在项目有这么一个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的扩展类里覆盖就行。

AndroidのListView之滑动列表项(点击事件和滑动事件共存)的更多相关文章

  1. Android学习笔记(23):列表项的容器—AdapterView的子类们

    AdapterView的子类的子类ListView.GridView.Spinner.Gallery.AdapterViewFlipper和StackView都是作为容器使用,Adapter负责提供各 ...

  2. Android ListView 长按列表弹出菜单

    Android ListView 长按列表弹出菜单 设置长按菜单 listView.setOnCreateContextMenuListener(new View.OnCreateContextMen ...

  3. PyQt学习随笔:QtDesigner ListView控件列表项的初始化

    在QtDesigner中设计的界面中添加ListView控件后,是没办法添加需要在ListView控件中显示的列表项.由于ListView控件只是一个展示列表项的视图控件,实现了界面与数据的分离,其要 ...

  4. Android ListView中 每一项都有不同的布局

    实现代码 Adapter的代码 其中:ViewHolder分别是三个不同的布局,也就是ListView中每一项的布局 TYPE_1...是三种类型. 在使用不同布局的时候,getItemViewTyp ...

  5. android listview里包含组件(checkbox)点击事件和Item的点击事件冲突

    在listview的item中包含有textview和checkBox.我们既想获取listitem的点击事件,又想获取listitem中textview的点击事件和listitem中checkBox ...

  6. 建立CMenu菜单项,实现选中菜单项点击左键响应事件

    这里我只是根据自己的项目做了一些总结,实现点击右键弹出菜单项,点左键选择菜单项: CMenu menu; VERIFY(menu.CreatePopupMenu());//新建一个cmenu菜单项 m ...

  7. android Listview item 中有button,item就不响应触摸事件

    为button设置 beanButton.getButton().setFocusable(false); beanButton.getButton().setFocusableInTouchMode ...

  8. Android开发 ExpandableListView 可折叠列表详解

    前言 在需要实现一个List的item需要包含列表的时候,我们就可以选择ExpandableListView. 其实这个View的原始设计还是ListView的那套.就是增加2层的ListView而已 ...

  9. Android ListView焦点事件冲突问题与解决

    Android ListView对于单纯列表展示是很好用的,但是一旦牵扯到对listView进行操作就会遇到各种各样的问题.比如保存Checkbox状态与item复用的冲突.遇到可获取焦点的控件比如说 ...

随机推荐

  1. Android APP 分享图片文字到微信刚開始正常,后面就不弹出分享框了

    依照官方的流程走了一遍.一切顺利,分享成功了.本来以为能够大功告成了,结果睡了一觉,第二天要给客户演示了.才发现TMD坑爹了,不能分享了,第三方的分享栏弹不出来了.我一阵惊慌,还好非常快找到了解决的方 ...

  2. iOS边练边学--简单的数据操作(增、删、改),左滑动删除和弹窗

    一.数据刷新的原则: 通过修改模型数据,来修改tableView的展示 先修改数据模型 在调用数据刷新方法 不要直接修改cell上面子控件的属性 二.增删改用到的方法: <1>重新绑定屏幕 ...

  3. DataGridView使用技巧十三:点击列头实现升序和降序排序

    DataGridView 列有三种排序模式.每一列的排序模式是通过该列的 SortMode 属性指定的,该属性可以设置为以下的 DataGridViewColumnSortMode 枚举值之一. Da ...

  4. java-TokenProcessor令牌校验工具类

    TokenProcessor令牌校验工具类 public class TokenProcessor { private long privious;// 上次生成表单标识号得时间值 private s ...

  5. 用jQuery屏蔽掉按回车键时提交表单

    <script type="text/javascript"> $(function() { $("input").keypress(functio ...

  6. 初识EseNt

    转自:http://www.cnblogs.com/goosao/archive/2011/09/23/2186412.html 一.什么是EseNtEseNt(Extensible Storage ...

  7. 在 PL/SQL 块的哪部分可以对初始变量赋予新值? (选择1项)

    A.结尾部分 B.开头部分 C.执行部分 D.声明部分 解答:C

  8. (转)PS流格式

    概念: 将具有共同时间基准的一个或多个PES组合(复合)而成的单一的数据流称为节目流(Program Stream). ES是直接从编码器出来的数据流,可以是编码过的视频数据流,音频数据流,或其他编码 ...

  9. nodejs基础 -- EventEmitter

    var events = require('events'); nodejs所有的异步I/O操作在完成时都会发送一个事件到事件队列 nodejs里面的许多对象都会分发事件,如: 一个net.Serve ...

  10. linux -- 进程的查看、进程id的获取、进程的杀死

    进程查看 ps ax : 显示当前系统进程的列表 ps aux : 显示当前系统进程详细列表以及进程用户 ps ax|less : 如果输出过长,可能添加管道命令 less查看具体进程, 如:ps a ...