OnItemCLickListener 在列表视图中不起作用

Posted

技术标签:

【中文标题】OnItemCLickListener 在列表视图中不起作用【英文标题】:OnItemCLickListener not working in listview 【发布时间】:2011-07-29 21:25:22 【问题描述】:

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");
    
);

Adapter 类中的getView 函数:

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);
    

inflating时使用两个xml有问题吗?

【问题讨论】:

@hiei 我的问题是我在布局单元格中使用了图像按钮。即使添加了“android:descendantFocusability”,我的点击监听器也没有响应。我所做的是,我将所有 ImaegButtons 更改为 ImageViews。这解决了我的问题。 【参考方案1】:

我刚刚从这里找到了一个解决方案,但是通过深度点击。

如果列表的任何行项包含可聚焦或可点击的视图,则 OnItemClickListener 将不起作用。

行项目必须有一个参数 android:descendantFocusability = "blocksDescendants".

您可以在此处查看列表项的外观示例。 您的列表项 xml 应该是... row_item.xml (your_xml_file.xml)

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

    // your other widgets here

</LinearLayout>

【讨论】:

不适合我。谁能看看[***.com/questions/21692209/… 您也可以使用listView.setDescendantFocusability(int focus); 以编程方式设置它,其中focusViewGroup.FOCUS_BEFORE_DESCENDANTSViewGroup.FOCUS_AFTER_DESCENDANTSViewGroup.FOCUS_BLOCK_DESCENDANTS 之一 我觉得这很有趣,有 20 个人在评论中感谢了你。过去 8 小时我一直遇到这个问题,非常感谢。 我的问题是这是一个 android 错误还是设计使然? 我已经坚持了 6 个小时,我真的需要帮助。 ***.com/questions/35108940/why-cant-i-remove-an-item/…【参考方案2】:

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

点击here了解更多信息。

如果不是这样,请发布您的布局 xml。

【讨论】:

这是我的解决方案,我将我的视图声明为可点击。谢谢! 谢谢!我将我的 2 EditTexts 更改为 TextViews,并允许 CheckBox 保留(并保持可切换),并将 android:descendantFocusability="blocksDescendants" 添加到我的 LinearLayout 是的!我的行有android:focusableInTouchMode="true",一旦删除,它终于开始工作了! :-)【参考方案3】:

对于我的列表,我的行还有其他可以点击的东西,比如按钮,所以做一个毯子 blocksDescendants 是行不通的。相反,我在按钮的 xml 中添加了一行:

    android:focusable="false"

这样可以防止按钮阻止对行的点击,但仍然让按钮也可以进行点击。

【讨论】:

@user1840899 这是一个常见的回应,也是我从中学到的,所以我把它传下去了。这是正确的信息,不值得投反对票。 这适用于我在 ListView 项目中的 CheckBox(没有 blocksDescendants) 这修复了错误,同时保持按钮(对我来说是 ToggleButton)可点击 我可以让带有 RadioButtons 的 GridView 工作的唯一方法是在包含 RadioButton 的 LinearLayout 上应用 android:descendantFocusability="blocksDescendants",并在 RadioButton 中设置 android:clickable="false"本身。 我已经坚持了 6 个小时,我真的需要帮助。 ***.com/questions/35108940/why-cant-i-remove-an-item/…【参考方案4】:

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

    设置根布局为:android:descendantFocusability="blocksDescendants" 在此项目中设置任何可聚焦或可点击的视图: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_
    android:layout_
    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_
        android:layout_
        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 设置 android:descendantFocusability="blocksDescendants" 对我有帮助。谢谢! 2016 年 12 月 21 日,经过数小时的搜索,终于成功了,谢谢! 如果您的布局与横向等相同,请确保您也在那里进行。 请帮助***.com/questions/66336648/…【参考方案5】:

在列表视图的自定义行布局中使用按钮标签内的以下代码

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

【讨论】:

伟人真的很有帮助!! 这在这里工作!我在这个视图中有很多复选框,我尝试使用 android:descendantFocusability="blocksDescendants" 并阻止这些复选框以供点击【参考方案6】:

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

@Override
public boolean isEnabled(int position)

    return false;

在我的 CustomListViewAdapter 类上。

通过将其更改为:

return true;

我已经设法解决了这个问题。 以防万一有人犯了同样的错误……

【讨论】:

我也有一个@Override public void onApplicationStart ExplodeThisDevice(); 【参考方案7】:

使用 android:descendantFocusability

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:background="@color/light_green"
    android:descendantFocusability="blocksDescendants" >

在根布局中添加上面

【讨论】:

添加详细信息可能会使其成为更好的答案和 +1。 这对我有用,我在列表元素中的按钮仍然按预期工作。【参考方案8】:

我在this answer的帮助下解决了这个问题

1.在list_items.xml的Linear Layout中添加以下内容 android:descendantFocusability="blocksDescendants"

2.list_items.xml中LinearLayout的子视图

 android:focusable="false" 

【讨论】:

您的链接已损坏。 @JasonC 感谢您的信息。这是链接***.com/a/14915758/5740760【参考方案9】:

如果您的文本视图、按钮或 stg 仅在您的行视图中可点击或可选择

android:descendantFocusability="blocksDescendants"

还不够。你必须设置

android:textIsSelectable="false"

到你的文本视图和

android:focusable="false"

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

【讨论】:

我很难学到这一点。 android:textIsSelectable="false" 注意这个:)【参考方案10】:

即使我遇到了同样的问题,我也有复选框,做了以下屏蔽 itemClickListener 的工作,

在复选框中添加了以下属性,

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

ItemClickListner 开始工作了。

详细示例可以通过链接查看,

http://knowledge-cess.com/android-itemclicklistner-with-checkbox-or-radiobutton/

希望对你有帮助 干杯!!

【讨论】:

【参考方案11】:

我遇到了同样的问题,并尝试了所有提到的解决方案都无济于事。通过测试,我发现使文本可选会阻止调用侦听器。因此,通过将其切换为 false 或将其删除,我的侦听器再次被调用。

android:textIsSelectable="false"

希望这可以帮助像我一样被困的人。

【讨论】:

【参考方案12】:

    在主布局中添加这个

    android:descendantFocusability="blocksDescendants"
    

    将此代码写入每个按钮、Textview、ImageView 等 点击

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

希望它会起作用。

【讨论】:

【参考方案13】:

这是两个很棒的解决方案,如果您从片段扩展 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);
 

【讨论】:

【参考方案14】:

在我的例子中,没有一个 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 布局中设置属性做同样的事情,但它只是在我的情况下有效。

这不是完美的时机,但也许它会对某人有所帮助 快乐编码

【讨论】:

【参考方案15】:

我已经尝试了以上所有方法,但没有任何效果。

我解决的问题如下:

首先我定义了一个名为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_
android:layout_
android:text="Cancel"
android:textSize="20sp" 
android:layout_margin="10dp"
android:padding="2dp"
android:background="#000000"
android:textColor="#ffffff"
android:textStyle="bold"  
/>

然后我定义自己的ButtonClickedListener接口:

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...
        

    );

【讨论】:

【参考方案16】:

我遇到了同样的问题,我在具有“可聚焦”属性的行布局中为我的文本使用了一种样式。我删除它后它起作用了。

【讨论】:

【参考方案17】:

就我而言,我必须从Layout 中删除下一行

android:clickable="true"

【讨论】:

【参考方案18】:

Android:autoText 属性还可以让 TextView 自动聚焦。

【讨论】:

【参考方案19】:

如果您想在列表视图项上同时使用简单单击和长单击,更好的实现方法是使用上下文菜单进行长单击。避免使用 setItemLongClickListener,尤其是当您的列表视图有多个行布局时。

【讨论】:

【参考方案20】:

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

【讨论】:

【参考方案21】:

以上所有对我来说都失败了。但是,我能够解决问题(经过数小时的敲打——谷歌,如果你在听,请考虑以编译器错误的形式修复我在下面遇到的问题,如果可能的话)

你真的必须小心你在这里添加到你的 xml 布局中的 android 属性(在这个原始问题中,它被称为 list_items.xml)。对我来说,导致问题的原因是我已从 EditText 视图切换到 TextView,并且更改后留下了剩余的属性(在我的情况下为 inputType)。当我去运行应用程序时,编译器没有捕捉到它并且可点击性失败了。仔细检查布局 xml 节点中的所有属性。

【讨论】:

【参考方案22】:
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复制它对我有用

【讨论】:

【参考方案23】:

对我有用的事情是将以下代码添加到我的 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_
    android:layout_>


    <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
            

        );

我从here得到了答案!

【讨论】:

【参考方案24】:

onClick 也有同样的问题。解决方案是从 xml 中删除以下内容

android:tooltipText=""

【讨论】:

【参考方案25】:

我通过从列表中删除可点击视图解决了这个问题。

【讨论】:

以上是关于OnItemCLickListener 在列表视图中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

滚动后单击项目时列表视图中 onitemclicklistener 上的 Nullpointerexception

将数据从片段列表视图项传递到活动字符串变量 onitemclicklistener

设置为null后如何将onItemClickListener重置为true?

使用 OnItemClickListener 列出视图片段到片段事务

如何使用 Android Studio 在 Twitter Kit 的 TweetUI 列表上设置 OnItemClickListener?

Listview onItemClickListener 问题适配器与适配器