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

小菜鸟战斗机 2018-3-27 206

█ 问题重现:

 ● 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>1234567891011121314151617181920

 ● 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;
            }
        }); 
    }
    ......
}123456789101112131415161718192021

   
出现的问题:当长按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);
            }
        });1234567891011121314

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

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

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

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

 ○ 修改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" />12345678

修改后:

    <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" />123456789

 ● 直接对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) {
                ......
            }
        });12345678910111213141516

 ● 在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" />12345678

█ 相关资料收集:

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;  
            }  
        });  123456
  如果返回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"  1
  另外还要设置 Xml代码 
android:longClickable="true"  1
  否则无法收到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


最新回复 (0)
返回