【问题标题】:listview item with button not responding to onListItemClick带有按钮的列表视图项目不响应 onListItemClick
【发布时间】:2013-11-25 08:35:49
【问题描述】:

我正在开发一个列表项很复杂的应用程序,TextView 和两个 ImageButtons。我环顾四周寻找解决方案,并尝试了所有我所看到的,仍然没有。

该列表是我已覆盖 onListItemClick 上的 ListFragment 的一部分。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFF" >

    <TextView
        android:id="@+id/medcine_info_txt"
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:padding="3dp"
        android:textColor="@color/black" />

    <ImageButton
        android:id="@+id/item_edit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/medcine_info_txt"
        android:layout_alignParentLeft="true"
        android:contentDescription="@string/item_edit"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:src="@android:drawable/ic_menu_edit" />

    <ImageButton
        android:id="@+id/item_history"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/medcine_info_txt"
        android:layout_centerHorizontal="true"
        android:contentDescription="@string/item_history"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:src="@android:drawable/btn_star" />

</RelativeLayout>

这是我处理按钮单击的适配器 getView,它实现了 OnClickListener

public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflator = (LayoutInflater) getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View listItem = inflator.inflate(R.layout.medcince_list_item, null);

    ImageButton mEdit = (ImageButton)listItem.findViewById(R.id.item_edit);
    mEdit.setOnClickListener(this);
    mEdit.setTag(getItem(position));

    ImageButton mHistory = (ImageButton)listItem.findViewById(R.id.item_history);
    mHistory.setOnClickListener(this);
    mHistory.setTag(getItem(position));

    return listItem;
}

关于为什么 onListItemClick 不处理点击有什么想法吗?

【问题讨论】:

    标签: android listview android-arrayadapter custom-adapter


    【解决方案1】:

    我认为您的 ImageButton 正在窃取 onItemClickLister 事件。将此属性添加到您的布局中

    android:descendantFocusability="blocksDescendants"

    <TextView
        android:id="@+id/medcine_info_txt"
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:padding="3dp"
        android:textColor="@color/black" />
    
    <ImageButton
        android:id="@+id/item_edit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        .......
    

    谢谢

    【讨论】:

    • 类似更好的答案here。您需要在布局中添加 android:descendantFocusability="blocksDescendants" 并在 imagebutton 上添加 android:focusable="false" 和 android:focusableInTouchMode="false"
    【解决方案2】:

    这是ListView 的常见问题。我阅读了有关此的源代码。
    问题:为什么onListItemClick不被调用?
    答案:

    • AbsListView 类覆盖 onTouchEvent 方法。
    • Snip 代码来自onTouchEvent 方法。
       
      if (inList && !child.hasFocusable()) {
                          if (mPerformClick == null) {
                              mPerformClick = new PerformClick();
                          }
      .....
      }
      

      如果child.hasFocusable() return false 将调用PerformClick 你是哪个子ListView 项目视图;
    • Snip 代码来自hasFocusable 方法。
     
    @Override
        public boolean hasFocusable() {
            if ((mViewFlags & VISIBILITY_MASK) != VISIBLE) {return false; }
            if (isFocusable()) {return true;}
            final int descendantFocusability = getDescendantFocusability();
            if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) {
                final int count = mChildrenCount;
                final View[] children = mChildren;
                for (int i = 0; i 


    所以解决方案:
    方案A,设置ListView item的descendantFocusability属性,让它的getDescendantFocusability()不等于FOCUS_BLOCK_DESCENDANTS
    方案B,ListView项所有子view都不是hasFocusable(hasFocusable() return false)。

    【讨论】:

    • 出色的分析。但是..对于解决方案A,您的意思是descendantFocusability 属性应该设置为blocksDescendants 对吗?您的行 - “让它的 getDescendantFocusability() 不等于 FOCUS_BLOCK_DESCENDANTS”意味着完全相反。无论如何对我都不起作用。
    • @faizal 你设置的只是确保 hasFocusable() 返回 false;您可以将 FOCUS_BEFORE_DESCENDANTS 或 FOCUS_AFTER_DESCENDANTS 传递给 setDescendantFocusability 方法。
    • 谢谢。我的问题是我在项目布局的元素之一中有`android:LongClickable="true"'。删除此属性后,单击侦听器开始工作。
    • @faizal 你的意思是'删除 android:LongClickable="true" 属性,listview 点击监听器可以工作'或'删除 android:descendantFocusability 属性,android:LongClickable="true" 点击监听器可以工作'。你能提供完整的细节吗?
    • 我的意思是 - 删除 android:LongClickable="true" 属性,listview 点击监听器可以工作'
    【解决方案3】:

    您可以创建 View.OnClickListner 对象,该对象可以在 getView 中侦听您的图像按钮单击。 onListItemClick 一般用于处理行点击事件,而不是行中的项目。

    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflator = (LayoutInflater) getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View listItem = inflator.inflate(R.layout.medcince_list_item, null);
    
        ImageButton mEdit = (ImageButton)listItem.findViewById(R.id.item_edit);
        mEdit.setOnClickListener(new View.OnClickListener(){
    
        @Override
        public void onClick(View v) {
            // HERE YOU CAN HANDLE BUTTON CLICK. POSITION YOU CAN HAVE FROM getView already.
        }
    
        });
        mEdit.setTag(getItem(position));
    
        ImageButton mHistory = (ImageButton)listItem.findViewById(R.id.item_history);
        mHistory.setOnClickListener(new View.OnClickListener(){
    
        @Override
        public void onClick(View v) {
            // HERE YOU CAN HANDLE BUTTON CLICK. POSITION YOU CAN HAVE FROM getView already.
        }
    
        });
        mHistory.setTag(getItem(position));
    
        return listItem;
    }
    

    【讨论】:

      【解决方案4】:

      使ListFragment实现View.OnClickListener接口,并在方法OnClick(View view)中实现你希望按钮按下时调用的代码,即@Override

      【讨论】:

        猜你喜欢
        • 2013-03-10
        • 1970-01-01
        • 1970-01-01
        • 2018-03-07
        • 2011-06-22
        • 1970-01-01
        • 1970-01-01
        • 2013-05-24
        • 1970-01-01
        相关资源
        最近更新 更多