onItemClickListener 未在自定义 ArrayAdapter 上触发

Posted

技术标签:

【中文标题】onItemClickListener 未在自定义 ArrayAdapter 上触发【英文标题】:onItemClickListener not firing on custom ArrayAdapter 【发布时间】:2011-07-28 10:13:38 【问题描述】:

我有一个Activity,它从 Web 服务中检索数据。该数据通过 ArrayAdapter 以 ListView 的形式呈现,该 ArrayAdapter 将 RelativeLayout 与内部的三个 TextViews 膨胀,没什么花哨的,它工作正常。

现在我想实现一个详细信息Activity,当用户单击 ListView 中的项目时应该调用它,这听起来很容易,但我一辈子都无法让 onItemClickListener 在我的 ArrayAdapter 上工作。

这是我的主要Activity

public class Schema extends Activity 

    private ArrayList<Lesson> lessons = new ArrayList<Lesson>();
    private static final String TAG = "Schema";
    ListView lstLessons;
    Integer lessonId;

    // called when the activity is first created.
    @Override
    public void onCreate(Bundle savedInstanceState) 

        super.onCreate(savedInstanceState);

        // can we use the custom titlebar?
        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

        // set the view
        setContentView(R.layout.main);

        // set the title
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.titlebar);

        // listview called lstLessons
        lstLessons = (ListView)findViewById(R.id.lstLessons);

        // load the schema
        new loadSchema().execute();

        // set the click listeners
        lstLessons.setOnItemClickListener(selectLesson);      

    // onCreate

// declare an OnItemClickListener for the AdapterArray (this doesn't work)
private OnItemClickListener selectLesson = new OnItemClickListener() 
    @Override
    public void onItemClick(AdapterView<?> parent, View v, int i, long l)   
        Log.v(TAG, "onItemClick fired!");
                    
;

private class loadSchema extends AsyncTask<Void, Void, Void> 

    private ProgressDialog progressDialog; 

    // ui calling possible
    protected void onPreExecute() 
        progressDialog = ProgressDialog.show(Schema.this,"", "Please wait...", true);
    

    // no ui from this one
    @Override
    protected Void doInBackground(Void... arg0) 
    // get some JSON, this works fine
    

    @Override
    protected void onPostExecute(Void result) 
        progressDialog.dismiss();
        // apply to list adapter
        lstLessons.setAdapter(new LessonListAdapter(Schema.this, R.layout.list_item, lessons));        
    

我的 ArrayAdapter 代码:

// custom ArrayAdapter for Lessons 
private class LessonListAdapter extends ArrayAdapter<Lesson> 
    private ArrayList<Lesson> lessons;

    public LessonListAdapter(Context context, int textViewResourceId, ArrayList<Lesson> items) 
        super(context, textViewResourceId, items);
        this.lessons = items;
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        View v = convertView;
        if (v == null) 
                LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = vi.inflate(R.layout.list_item, null);
        
        Lesson o = lessons.get(position);

        TextView tt = (TextView) v.findViewById(R.id.titletext);
        TextView bt = (TextView) v.findViewById(R.id.timestarttext);
        TextView rt = (TextView) v.findViewById(R.id.roomtext);

        v.setClickable(true);
        v.setFocusable(true);

        tt.setText(o.title);
        bt.setText(o.fmt_time_start);
        rt.setText(o.room);
        return v;
    
// LessonListAdapter

main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/main"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_ android:layout_
    android:screenOrientation="portrait"
    >

    <!-- student name -->
    <TextView 
      android:id="@+id/schema_view_student"
      android:text="Name"  android:padding="4dip"
      android:layout_
      android:layout_
      android:gravity="center_vertical|center_horizontal"
      style="@style/schema_view_student"
    />

    <!-- date for schema -->    
    <TextView
      android:id="@+id/schema_view_title"   
      android:layout_
      android:layout_margin="0dip" 
      style="@style/schema_view_day"
      android:gravity="center_vertical|center_horizontal"
      android:layout_below="@+id/schema_view_student"         
      android:text="Date" android:padding="6dip"
      android:layout_
    />

    <!-- horizontal line -->
    <View
      android:layout_
      android:layout_
      android:background="#55000000"
      android:layout_below="@+id/schema_view_title"
    />

    <!--  list of lessons -->
    <ListView
      android:id="@+id/lstLessons" 
      android:layout_
      android:layout_
      android:layout_below="@+id/schema_view_title"
    />

</RelativeLayout>

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:padding="12dip">

    <TextView
        android:id="@+id/timestarttext"
        android:text="09:45"
        style="@style/LessonTimeStartText"

        android:layout_

        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"

        android:layout_ android:gravity="center_vertical|right" android:paddingRight="6dip"/>

    <TextView
        android:id="@+id/titletext"
        android:text="Test"
        style="@style/LessonTitleText"

        android:layout_
        android:layout_

        android:layout_toRightOf="@+id/timestarttext"

        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true" android:gravity="center_vertical|center_horizontal"/>

    <TextView
        android:id="@+id/roomtext"
        android:text="123"

        android:layout_
        android:layout_

        style="@style/LessonRoomText"
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:gravity="center_vertical" />

</RelativeLayout>

过去几个小时一直在搞砸这个问题,我似乎无法理解问题所在。我的问题看起来与this question 非常相似,但我没有扩展ListActivity,所以我仍然不知道我的onListClickItem() 应该去哪里。

更新:现在我已经为此困惑了几天,但仍然找不到问题所在。

我是否应该重写 Activity,这次扩展 ListActivity 而不是 Activity?因为它本身提供了 onItemClick 方法,而且可能更容易覆盖。

或者,我应该在我的 ArrayAdapter 的每个 getView() 中直接绑定一个侦听器吗?我相信我已经读过这是不好的做法(我应该按照我在帖子中尝试但失败的方式去做)。

【问题讨论】:

我无法弄清楚这两件事都没有帮助我:***.com/questions/18237218/… 【参考方案1】:

发现错误 - 它似乎是this issue。为每个 list_item.xml 元素添加android:focusable="false" 解决了这个问题,并且现在使用原始代码触发了 onclick。

【讨论】:

我花了一个多小时才找到您的解决方案(可行)。 Android 平台可以很出色,但这对他们来说是个彻底的失败。 似乎是轨迹球/dpad 问题。不过谢谢,这个解决了。【参考方案2】:

我遇到了同样的问题并尝试了您的修复,但无法使其正常工作。对我有用的是将android:descendantFocusability="blocksDescendants"从项目布局xml添加到&lt;RelativeLayout&gt;,在你的情况下list_item.xml。这允许调用onItemClick()

【讨论】:

android:focusable="false" 和 android:desendantFocusability="blocksDescendants" 都不适合我。 如果有android:clickable="true" 删除它。 当我将CheckBox 添加到我的项目视图时,我的问题才开始发生。将CheckBox 设置为不可聚焦解决了我的问题。但是,我更喜欢这个解决方案,因为它会为所有子视图处理它,以防我将来再次这样做,或者另一个智利 View 类默认为可聚焦的。 我讨厌说“我也是”……但这确实为我解决了同样的问题。我只是希望我真的明白为什么。 谢谢。补充我的轶事,只要 android:clickable="true" 被删除(我之前在试图找到解决方案时错误地添加了), follandroid:descendantFocusability="blocksDescendants" 就对我有用。【参考方案3】:

什么对我有用:

1) 将 android:descendantFocusability="blocksDescendants" 添加到相对布局标签。 结果如下图:

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

2) 将 android:focusable="false" 添加到 list_item.xml 中的每个元素 示例:

<TextView
        android:id="@+id/textView2"
        android:layout_
        android:layout_     
        android:text="TextView"
        android:focusable="false" />

【讨论】:

将 android:descendantFocusability="blocksDescendants" 添加到单元格布局的父级对我有用【参考方案4】:

曾经我遇到过类似的问题。每个列表项都有一个文本视图和一个复选框,并且仅仅因为复选框,整个列表项没有“启用”来触发事件。当我得到视图时,我通过在适配器内部做了一个小技巧来解决它。

就在返回我放置的视图之前:

v.setOnClickListener(listener);

(对象listener 是我给Adapter 的构造函数的onItemClickListener)。

但我必须告诉你,问题是因为平台,是一个bug。

【讨论】:

【参考方案5】:

我遇到了同样的问题,我尝试通过添加来解决它

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

到我的 item.xml 但它仍然不起作用!事实上,我在相关布局中发现了这个问题,女巫包含

 android:focusableInTouchMode="true" android:focusable="true"

当我删除它时一切正常

【讨论】:

【参考方案6】:
protected void onPostExecute(Void result)  
     progressDialog.dismiss();  stLessons.setAdapter(new LessonListAdapter(Schema.this, R.layout.list_item, lessons)); 
    //add this  
ListView lv = getListView();  lv.setOnItemClickListener(new ListView.OnItemClickListener() 
                @Override
                public void onItemClick(AdapterView<?> a, View v, int i, long l) 
                    //do stuff
                
            );
     

【讨论】:

“Schema.loadSchema 类型的方法 getListView() 未定义” - lv 不会与 lstLessons 相同(lstLessons 是 ListView)? 我认为可能是因为 Schema 没有扩展 ListActivity。

以上是关于onItemClickListener 未在自定义 ArrayAdapter 上触发的主要内容,如果未能解决你的问题,请参考以下文章

CAShapeLayers 未在自定义子类 (UIControl) 中绘制

动画未在自定义布局中显示

UIImageView 未在自定义 UITableViewCell 中显示图像

iOS - WKURLSchemeHandler 未在自定义方案上调用

按钮未在自定义 UIButton 中注册触摸

recharts img 未在自定义点中呈现