【安卓学习之常见问题】 Listview的setOnItemLongClickListener无法进入问题

来源:互联网 发布:怎么查看手机淘宝等级 编辑:程序博客网 时间:2024/06/05 00:32

█ 问题重现:

 ● xml代码
 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:background="@drawable/global_bg"    android:orientation="vertical" >    <ListView        android:id="@android:id/list"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:cacheColorHint="#00000000"        android:divider="#00000000"        android:drawingCacheQuality="low"        android:fadingEdge="none"        android:listSelector="#00000000"        android:scrollingCache="true"         android:transcriptMode="disabled" >    </ListView></LinearLayout>

 ● java代码
 

public class MyListActivity extends ListActivity {    private ArrayList<DeviceInfo> deviceList = null;    private MyAdapter adapter = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_mylist);        initData();        adapter = new MyAdapter(this);        setListAdapter(adapter);        getListView().setOnItemLongClickListener(new OnItemLongClickListener() {            @Override            public boolean onItemLongClick(AdapterView<?> parent, View view,                    int position, long id) {                return false;            }        });     }    ......}

  
出现的问题:当长按Item时,onItemLongClick()长按事件无法响应,当然我在另一个界面上面也实现类似的方法,长按Item是可以进入onItemLongClick()事件函数。
 

█ 问题原因:

 ● 和ListView的item中的Button有冲突
 ● 可以参考以下的相关资料收集内容
 ● 本来这个是前任写的代码,因为某种原因,需要进行修改,而原本长按功能和点击功能都是进入其他界面的,所以看起来并不冲突,但现在长按功能变成弹出菜单,然后就发现在长按和短按的分水线上的某个特定时间点,就会同时执行长按和点击的功能,这样就会进入到其他界面,当其他界面返回时,就发现原来的界面上面有个弹出的菜单。这样就影响了美观,这个算是一个bug
  

█ 解决方法:

 ● 前任的解决方法:对item中采用手势GestureDetector的方法
 在适配器MyAdapter的getView() 实现方法中:

final GestureDetector mGestureDetector = new GestureDetector(this,        new GestureDetector.SimpleOnGestureListener() {            @Override            public void onLongPress(MotionEvent e) {            ......            }        });button.setOnTouchListener(new OnTouchListener() {        @Override        public boolean onTouch(View v, MotionEvent event) {            ......              return mGestureDetector.onTouchEvent(event);            }        });

 ● 对于前任的解决方法我觉得可以直接对item中的Button设置setOnLongClickListener的方法更方便

button.setOnLongClickListener(new OnLongClickListener() {        @Override        public boolean onLongClick(View v) {            ......            return false;            }        });

 ● 正常我们采用的方法,直接对ListView()进行设置
 ○ 在onCreate()中添加getListView().setOnItemLongClickListener()
 ○ 在MyAdapter的getView() 找到对于的item的layout文件:

 convertView = mInflater.inflate(                        R.layout.activity_mylist_item, null);

 ○ 修改activity_mylist_item.xml中的Button属性
 原来:

    <Button        android:id="@+id/button"        android:layout_width="fill_parent"        android:layout_height="49dp"        android:background="@drawable/button_icon"        android:gravity="center|left"        android:paddingLeft="70dp"        android:textColor="#ff000000" />

修改后:

    <Button        android:id="@+id/button"        android:layout_width="fill_parent"        android:layout_height="49dp"        android:background="@drawable/button_icon"        android:gravity="center|left"        android:longClickable="true"        android:paddingLeft="70dp"        android:textColor="#ff000000" />

 ● 直接对ListView()进行设置,但是因为item中包含Button,而存在冲突问题,虽然在Button属性中添加了longClickable属性,但是如果还想直接对ListView()进行点击事件的处理呢?在Button属性中增加clickable属性?测试过,是不行的,其实还可以更灵活点,直接将Button 修改为TextView就可以解决所有问题了。

PS : 然而以上的问题只是解决了可以响应点击和长按事件的响应问题,但是没有解决,长按某个时间点松开后,发现点击和长按的功能都给执行的问题。
 

█ 最终答案:

 ● 将OnItemLongClickListener() 的返回值设置为true即可在响应长按事件后,阻止点击事件的响应,就不会同时响应两个事件

 最后代码就是这样的:
 ● 在onCreate()中

        getListView().setOnItemLongClickListener(new OnItemLongClickListener() {            @Override            public boolean onItemLongClick(AdapterView<?> parent, View view,                    int position, long id) {                ......                return true ;            }        });        getListView().setOnItemClickListener(new OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view,                    int position, long id) {                ......            }        });

 ● 在MyAdapter的getView() 中的item的layout文件activity_mylist_item.xml:
 

    <TextView        android:id="@+id/button"        android:layout_width="fill_parent"        android:layout_height="49dp"        android:background="@drawable/button_icon"        android:gravity="center|left"        android:paddingLeft="70dp"        android:textColor="#ff000000" />

█ 相关资料收集:

1.Android下Listview的onItemClick以及onItemLongClick等易模糊问题验证

  做好准备后开始验证以下几个问题:
  1.ListView本身可不可以调用setOnClickListner()?
  代码上可以,但是运行马上会丢出异常,所以是不可以拦截Listview本身的click事件。
  2.ListView.setOnItemClickListener设置的listener什么时候会被调用?
  当点击某行内容是会被调用,但是如果这行内容中包含Button,ImgButton等控件时就不会被调用,为什么以及怎么解决见后面。
  3.ListView.setOnItemLongClickListener设置的listener什么时候被调用?
  当长按某一行时会被调用,而且在抬起之前就已经调用了。
  4.收到LongClick的调用后还会调用click吗?
  这个要根据LongClick listener的返回值来决定。
  lv.setOnItemLongClickListener(new OnItemLongClickListener() {              public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {                  System.out.println("Item LONG clicked. Position:" + position);                  return false;              }          });  
  如果返回false那么click仍然会被调用。而且是先调用Long click,然后调用click。
  如果返回true那么click就会被吃掉,click就不会再被调用了。
  5.监听click以及long click影响弹出菜单吗?
click不影响;long click如果返回true那么就会吃掉click事件,导致菜单不能弹出。
  6.如果让包含button的item也能弹出菜单,回调click以及long click的监听器呢?
查看Android源代码,查看源代码,发现在AbsListView.onTouchEvent中有调用View.hasFocusable(),所以只要设置button属性:
android:focusable="false"  
  另外还要设置 Xml代码
android:longClickable="true"  
  否则无法收到long click。
  这样就可以看到有button没有button的item行为就统一了。
  PS: 如果包含的Button是ImageButton,那么在xml中设置了
  android:focusable=”false”
  设置一次。 或者: 在父Item里面加上  
  android:descendantFocusability=”blocksDescendants”
  以上基本上就是Listview使用时常见问题了,在配合上前面博文提到的手势处理,很多Listview的使用就都包含了

 摘自:Android下Listview的onItemClick以及onItemLongClick等易模糊问题验证 - 点点滴滴,持之以恒 - ITeye技术网站
   http://mypyg.iteye.com/blog/850624

2.android 处理 onLongClickLisener, 长按和短按都被响应了解决办法

  对于onLongClickLisener是有一个返回值标识。
  对于一次长按操作,如果返回false,则2个lisener都会相应,如果返回true则事件被longClick链式拦截,后面的【clickLisener处于后面的位置】的注册的lisener将不再向上回调;
  在处理长按时,注意的细节是把onItemLongClick返回设置为true,否则长按是会执行setOnItemClickListener

 摘自:android 处理 onLongClickLisener, 长按和短按都被响应了解决办法_老穆溜土豆_新浪博客
   http://blog.sina.com.cn/s/blog_4e1e357d0102uwhe.html

转载请注明出处:
http://blog.csdn.net/ljb568838953/article/details/52964581

0 0
原创粉丝点击