█ 问题重现:
● 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的返回值来决定。 |
如果返回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