OnItemCLickListener在列表视图中不起作用


242

Activity 班级代码:

conversationList = (ListView)findViewById(android.R.id.list);
ConversationArrayAdapter conversationArrayAdapter=new  ConversationArrayAdapter(this, R.layout.conversation_list_item_format_left, conversationDetails);
conversationList.setAdapter(conversationArrayAdapter);
conversationList.setOnItemClickListener(new AdapterView.OnItemClickListener(){ 
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
        Log.d("test","clicked");
    }
});

该类中的getView函数Adapter

if (v == null) {                                
    LayoutInflater vi = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if(leftSideMessageNumber.equals(m.getTo())) {
        v = vi.inflate(R.layout.conversation_list_item_format_left, null);
    } else {
        v = vi.inflate(R.layout.conversation_list_item_format_right, null);
    }
}

膨胀时使用两个xml是否有问题?


4
@hiei我的问题是我在布局单元格中使用了图像按钮。即使添加了“ android:descendantFocusability”,我的点击监听器也没有响应。我所做的是,将所有ImaegButtons更改为ImageViews。那解决了我的问题。
Ajith Memana 2015年

Answers:


730

我只是从这里找到了一个解决方案,但是通过单击即可。

如果列表中的任何行项目包含可聚焦或可单击的视图,OnItemClickListener则将无法使用。

该行项目的参数必须类似于 android:descendantFocusability = "blocksDescendants"

在这里,您可以看到一个清单项目外观的示例。您的清单项目xml应该是... row_item.xmlyour_xml_file.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:baselineAligned="false"
    android:descendantFocusability="blocksDescendants"
    android:gravity="center_vertical" >

    // your other widgets here

</LinearLayout>

不适合我。任何人都可以看看[ stackoverflow.com/questions/21692209/...
suitianshi

3
您还可以设置这个编程listView.setDescendantFocusability(int focus);这里focus是一个ViewGroup.FOCUS_BEFORE_DESCENDANTSViewGroup.FOCUS_AFTER_DESCENDANTS或者ViewGroup.FOCUS_BLOCK_DESCENDANTS
最大的座狼

我认为这很有趣,有20个人在评论中感谢您。在过去的8个小时中,我一直在遇到这个问题,非常感谢。
sparticvs 2015年

1
我的问题是这是一个android bug还是设计使然?
fangzhzh

我已经坚持了6个小时,我真的需要帮助。stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/...
Ruchir Baronia酒店

89

问题是您的布局包含可聚焦或可单击的项目。如果视图包含可焦点或可单击项,则不会调用OnItemCLickListener。

单击此处了解更多信息。

如果不是这种情况,请发布您的布局xml之一。


2
这是我的解决方案,我宣称自己的观点是可点击的。谢谢!
kingraam 2012年

1
谢谢!我将2更改EditTextTextViews,并CheckBox允许保持(并保持可切换)状态并android:descendantFocusability="blocksDescendants"添加到LinearLayout
Azurespot '16

是! 我已经android:focusableInTouchMode="true"排好了,一旦删除,它终于开始工作了!:-)
SharpC

58

对于我的列表,我的行还有其他可以单击的内容,例如按钮,因此盖毯blocksDescendants是行不通的。相反,我在按钮的xml中添加了一行:

android:focusable="false"

这样可以防止按钮阻止对行的单击,但是仍然可以使按钮接受单击。


@ user1840899这是一种常见的响应,也是我从中学到的,因此我将其继续进行下去。这是正确的信息,不值得不赞成。
Janene Pappas

这对我来说适用于ListView项中的CheckBox(无blockDescendants)
thpitsch

此修复同时保持按钮(切换按钮对我来说)错误点击
穆赫辛·阿夫欣

我可以使用带有RadioButtons的GridView的唯一方法是在包含RadioButton的LinearLayout上应用android:descendantFocusability =“ blocksDescendants”,并在RadioButton本身中设置android:clickable =“ false”。
史蒂芬·麦考密克

我已经坚持了6个小时,我真的需要帮助。stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/...
Ruchir Baronia酒店

34

您需要在listview_item.xml中执行2个步骤

  1. 使用以下命令设置根布局: android:descendantFocusability="blocksDescendants"
  2. 使用以下项在此项目中设置任何可聚焦或可单击的视图:
    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false"

这是一个示例:listview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    android:layout_marginTop="10dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:gravity="center_vertical"
    android:orientation="vertical"
    android:descendantFocusability="blocksDescendants">

    <RadioButton
        android:id="@+id/script_name_radio_btn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textColor="#000"
        android:padding="5dp"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        />

</LinearLayout>

clickable="true在项目视图上进行设置将使onItemClick不会被调用。因此,请注意还要添加clickable="false"项目根视图,在这种情况下,是LinearLayout
vovahost

设置android:descendantFocusability =“ blocksDescendants”对我有帮助。谢谢!
LLIAJLbHOu

16年12月21日,经过数小时的搜索,这项工作奏效了,谢谢!
Tanner Summers

如果您的布局与景观等相同,请确保在此也进行布局。
Immy

19

在listview的自定义行布局中在button标记内使用以下代码

 android:focusable="false"
 android:clickable="false"

伟人,它真的很有帮助!
divyansh ingle

这在这里工作!我在该视图中有很多复选框,并且尝试android:descendantFocusability="blocksDescendants"并阻止这些复选框以进行单击
Armando Marques Sobrinho

17

我遇到了同样的问题,只是看到我不小心设置了以下内容:

@Override
public boolean isEnabled(int position)
{
    return false;
}

在我的CustomListViewAdapter类上。

通过将其更改为:

return true;

我设法解决了这个问题。万一有人犯了同样的错误...


7
我也曾经有过一个@Override public void onApplicationStart { ExplodeThisDevice(); }
莱昂佩尔蒂埃

17

使用android:descendantFocusability

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dip"
    android:background="@color/light_green"
    android:descendantFocusability="blocksDescendants" >

在根布局中添加以上内容


2
添加详细信息可能会是一个更好的答案,并+1。
杀手级(Killer)

这对我有用,并且我在list元素中的按钮仍然按预期工作。
古斯塔夫·埃里克森


10

如果仅在行视图中具有文本视图,按钮或stg可单击或可选

android:descendantFocusability="blocksDescendants"

是不足够的。你必须设置

android:textIsSelectable="false"

到您的textview和

android:focusable="false"

您的按钮和其他可聚焦项。


我经过惨痛的教训才学到这个。android:textIsSelectable =“ false”请注意:)
diyoda_


5

我遇到了同样的问题,并尝试了所有提到的解决方案,但没有成功。通过测试,我发现使文本成为可选内容会阻止调用侦听器。因此,通过将其切换为false或删除它,再次调用了我的监听器。

android:textIsSelectable="false"

希望这对像我一样被困的人有所帮助。


4
  1. 在主布局中添加

    android:descendantFocusability="blocksDescendants"
  2. 将此代码写入具有onClick的每个按钮,Textview,ImageView等中

    android:focusable="false"
    
    android:clickable="false"

希望它能工作。


3

这是两个很棒的解决方案,如果您从片段中扩展ListFragment知道mListView.setOnItemClickListener在创建活动之前不会调用它,那么可以确保在创建活动时就将其设置了

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mListView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long rowId) {
            // Do the onItemClick action

            Log.d("ROWSELECT", "" + rowId);
        }
    });
}

在查看ListFragment的源代码时,我遇到了这个

public class ListFragment extends Fragment {
    ...........................................
    ................................................

    final private AdapterView.OnItemClickListener mOnClickListener
                = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            onListItemClick((ListView)parent, v, position, id);
        }
    };

    ................................................................
    ................................................................

    public void onListItemClick(ListView l, View v, int position, long id) {
    }
}

onItemClickListener附加一个对象并调用它。与之onListItemClick() 类似的另一种解决方案,其工作方式与重写完全相同。onListItemClick()

@Override
public void onListItemClick(ListView l, View v, int position, long rowId) {
    super.onListItemClick(l, v, position, id);
   // Do the onItemClick action

   Log.d("ROWSELECT", "" + rowId);
} 

3

就我而言,xml布局属性均无济于事。

我只添加一行这样的代码: convertView.setClickable(false);

@NonNull
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
    ViewHolder viewHolder;
    if (convertView == null || convertView.getTag() == null) {
        LayoutInflater inflater = LayoutInflater.from(context);
        convertView = inflater.inflate(R.layout.my_layout_id, parent, false);
        viewHolder = new ViewHolder(convertView);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    ...
    convertView.setClickable(false);
    return convertView;
}

因此,基本上它的作用与在xml布局中设置属性的作用相同,但这只是对我而言有效。

这不是一个完美的时机,但也许会对某人有所帮助


1

我已经尝试了以上所有方法,但没有成功。

我解决了如下问题:

首先,我定义一个自定义按钮 ListButton

public class ListButton extends android.widget.Button
{

private ButtonClickedListener clickListener;

public ListButton(Context context)
{
    this(context, null);
}

public ListButton(Context context, AttributeSet attrs)
{
    this(context, attrs, 0);
}

public ListButton(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);
}

public void setClickListener(ButtonClickedListener listener) {
    this.clickListener = listener;
}

@Override
public boolean isInTouchMode() {
    return true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    return false;
}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

    switch (event.getAction()) 
      {
          case MotionEvent.ACTION_DOWN:
              break;
          case MotionEvent.ACTION_UP:

              eventClicked();

              break;
          case MotionEvent.ACTION_CANCEL:
              break;
          case MotionEvent.ACTION_MOVE:
              break;
          default :

      }
    return true;
}

private void eventClicked() {
    if (this.clickListener!=null) {
        this.clickListener.ButtonClicked();
    }
}

}

XML看起来像:

<dk.example.views.ListButton
android:id="@+id/cancel_button"
android:layout_width="125dp"
android:layout_height="80dp"
android:text="Cancel"
android:textSize="20sp" 
android:layout_margin="10dp"
android:padding="2dp"
android:background="#000000"
android:textColor="#ffffff"
android:textStyle="bold"  
/>

然后定义自己的ButtonClicked侦听器接口:

public interface ButtonClickedListener {
    public void ButtonClicked();
}

然后,我使用自己的监听器,就像正常的情况一样OnClickListener

final ListButton cancelButton = (ListButton) viewLayout.findViewById(R.id.cancel_button);

    cancelButton.setClickListener(new ButtonClickedListener() {

        @Override
        public void ButtonClicked() {
            //Do your own stuff here...
        }

    });




0

如果要同时使用列表视图项目的简单单击和长按,则更好的实现方式是使用上下文菜单进行长按。避免使用setItemLongClickListener,尤其是在列表视图具有多个行布局的情况下。


0

面对同样的问题,尝试了几个小时。如果您已尝试了上述所有方法,请尝试将Listview和列表项的layout_width从wrap_content更改为match_parent。


0

以上所有这些对我来说都是失败的。但是,我能够解决问题(经过数小时的反复敲击-Google,如果您正在收听,请考虑以编译器错误的形式修复我在下面遇到的问题)

您确实要小心在此处添加到xml布局中的哪些android属性(在这个原始问题中,它称为list_items.xml)。对我来说,导致问题的原因是我已经从EditText视图切换到TextView,并且剩余的属性残留在更改中(在我的情况下为inputType)。编译器没有捕获它,而当我去运行该应用程序时,可点击性只是失败了。仔细检查您在布局xml节点中拥有的所有属性。


0
private AdapterView.OnItemClickListener onItemClickListener;

@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
 .......

final View view = convertView;
convertView.setOnClickListener(new View.OnClickListener() {
    @Override
     public void onClick(View v) {
         if (onItemClickListener != null) {
             onItemClickListener.onItemClick(null, view, position, -1);
         }
      }
 });

return convertView;
}

public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
    this.onItemClickListener = onItemClickListener;
}

然后在您的活动中,使用adapter.setOnItemClickListener()在将它附加到列表视图之前。

github复制它对我有用


0

对我有用的是将以下代码添加到row.xml文件布局内的每个子视图中:

android:focusable="false"
android:focusableInTouchMode="false"

因此,就我而言:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/testingId"
        android:text="Name"
       //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/dummyId"
        android:text="icon"
        //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/assignmentColor"
       //other stuff 
       />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/testID"
        //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:text="TextView"
        //other stuff 
        />

</android.support.constraint.ConstraintLayout>

这是我的Fragment子类中的setOnItemClickListener调用:

CustomListView = (PullToRefreshListCustomView) layout.findViewById(getListResourceID());
        CustomListView.setAdapter(customAdapter);
        CustomListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.d("Testing", "onitem click working");
              //  other code
            }

        });

我从这里得到答案!


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.