【问题标题】:OnItemClickListener and OnClickListener in ListViewListView 中的 OnItemClickListener 和 OnClickListener
【发布时间】:2011-05-22 20:43:10
【问题描述】:

我在自定义 ListAdapter 中的每一行都有一个自定义视图,我正在尝试执行 onClick 操作并获取列表中单击的行位置。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:paddingLeft="10dip" android:id="@+id/itemRoot" android:clickable="false">

    <TextView android:layout_width="wrap_content" android:text="TextView"
        android:layout_height="wrap_content" android:id="@+id/itemTxt"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"></TextView>
    <TextView android:layout_toRightOf="@+id/itemTxt" android:text="TextView"
        android:layout_height="wrap_content" android:layout_alignBottom="@+id/itemTxt"
        android:id="@+id/amountTxt" android:paddingLeft="6dip"
        android:layout_centerVertical="true" android:layout_width="match_parent"></TextView>
    <ImageView android:id="@+id/delBtn" android:layout_height="wrap_content"
        android:src="@drawable/delete" android:layout_width="wrap_content"
        android:layout_alignParentRight="true" android:paddingRight="10dip"
        android:layout_centerVertical="true"></ImageView>

</RelativeLayout>

我想知道何时单击 TextView 或 ImageView,我还需要知道它来自列表中的哪一行。我试过使用 OnItemClickListener ,它可以很好地获取点击来自的行。但是,一旦我为视图注册了 OnClick 侦听器,就会跳过 onItemClicked() 方法并立即执行 onClick(),但是无法获取视图所在的行位置(或者至少不是我知道是否)。

如果我将视图的 clickable 设置为 false,则调用 onItemClicked 并尝试在给定视图上手动调用 performClick()。但这仅适用于根元素(RelativeLayout),如果点击来自布局内的 TextView,则点击不会传播。

我真的不知道如何同时获得列表中的位置并执行 onClick 操作。

欢迎提出任何想法。

亚历克斯

【问题讨论】:

  • 在你的布局中,当定位一个相对于另一个视图的视图时,你应该指定锚点的 ID,不带 + 符号:android:layout_toRightOf="@id/itemTxt"android:layout_alignBottom="@id/itemTxt""@+id/itemTxt" 在为视图创建新 id 时使用(因此在 android:id 属性的值中)。
  • 所有这些代码都是自动生成的,但我会记住这一点 :) Alex

标签: android listview


【解决方案1】:

您可以在 ListAdapter 的覆盖 getView 方法中为每个 ImageViewTextView 分配正确的 OnClickListener

在该方法中,您知道项目的位置,因此您可以将其传递给自定义侦听器类,并在其中根据需要使用它:

@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
    // TODO: instantiate the layout 
    // here I call a super method
    final View view = super.getView(position, convertView, parent);
    final TextView textView = (TextView)view.findViewById(R.id.itemTxt);
    textView.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Log.i("Click", "TextView clicked on row " + position);
        }
    });
    final ImageView imageView = (ImageView)view.findViewById(R.id.delBtn);
    imageView.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Log.i("Click", "ImageView clicked on row " + position);
        }
    });
    return view;
}

【讨论】:

  • 感谢 rekaszeru,这实际上是一个非常整洁和不错的解决方案。
【解决方案2】:

使 OnClickListener 与创建活动在同一类中的另一个可能选项是添加到活动 implements OnItemClickListener

public class DisplayListCustom extends Activity implements OnItemClickListener

然后设置自定义列表监听

ListView list = (ListView)findViewById(R.id.custom_list);
list.setClickable(true);
list.setOnItemClickListener(this);
list.setAdapter(new CustomListAdapter(getApplicationContext(), listItems));

最后在onItemClick返回中,可以通过资源ID找到内部视图

public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
    LinearLayout listItem = (LinearLayout) v;
    TextView clickedItemView = (TextView) listItem.findViewById(R.id.name);
    String clickedItemString = clickedItemView.getText().toString();
    Log.i("DisplayListCustom", "Click detected " + clickedItemString + ", position " + Integer.toString(position));

这是我采用的解决方案。我将 LinearLayout 用于我的自定义布局容器,但我假设这同样适用于 RelativeLayout。

【讨论】:

  • 不错!与 rekaszeru 建议的匿名类方法相比,我更喜欢这种方法
【解决方案3】:

您需要扩展您的 TextView 等,覆盖 click 方法,执行适当的操作,然后技巧是返回 false,然后将其传播到列表视图。

【讨论】:

  • 我想知道是否有一种方法可以覆盖它,它会返回 false 并欺骗认为事件没有被消耗。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-03
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 2012-04-17
  • 1970-01-01
  • 2016-12-11
相关资源
最近更新 更多