onItemClickListener не срабатывает на пользовательском ArrayAdapter

У меня есть Activity, который извлекает данные из веб-службы. Эти данные представлены в ListView через ArrayAdapter, который раздувает RelativeLayout с тремя TextViews внутри, ничего особенного, и все работает нормально.

Теперь я хочу реализовать Details 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

Основной.xml

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

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

    <!-- date for schema -->    
    <TextView
      android:id="@+id/schema_view_title"   
      android:layout_height="wrap_content"
      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_width="fill_parent"
    />

    <!-- horizontal line -->
    <View
      android:layout_width="fill_parent"
      android:layout_height="1dip"
      android:background="#55000000"
      android:layout_below="@+id/schema_view_title"
    />

    <!--  list of lessons -->
    <ListView
      android:id="@+id/lstLessons" 
      android:layout_height="wrap_content"
      android:layout_width="fill_parent"
      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_width="fill_parent"
    android:layout_height="60px"
    android:padding="12dip">

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

        android:layout_width="60dip"

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

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

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

        android:layout_width="wrap_content"
        android:layout_height="fill_parent"

        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_width="wrap_content"
        android:layout_height="fill_parent"

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

</RelativeLayout>

Возился с этим последние пару часов, и я не могу понять, в чем проблема. Моя проблема очень похожа на этот вопрос, но Я не расширяю ListActivity, поэтому я до сих пор не знаю, куда должен идти мой onListClickItem().

ОБНОВЛЕНИЕ: вот уже несколько дней я ломаю голову над этим и до сих пор не могу найти проблему.

Должен ли я переписать активность, на этот раз расширив ListActivity вместо Activity? Потому что он предоставляет сам метод onItemClick и, вероятно, его легче перезаписать.

Или мне следует привязать прослушиватель непосредственно к каждому getView() в моем ArrayAdapter? Я считаю, что читал, что это плохая практика (я должен делать то, что пытался и потерпел неудачу в своем посте).


person cvaldemar    schedule 02.04.2011    source источник
comment
Я не могу понять, ни одна из этих двух вещей не помогла мне: блокируется progressbar"> stackoverflow.com/questions/18237218/   -  person Dylan Holmes    schedule 14.08.2013


Ответы (6)


Обнаружена ошибка — похоже, это эта проблема. Добавление android:focusable="false" к каждому из элементов list_item.xml решило проблему, и теперь onclick запускается с исходным кодом.

person cvaldemar    schedule 06.04.2011
comment
Мне потребовалось больше часа, чтобы найти ваше решение (которое работает). Платформа Android может быть блестящей, но это полный провал с их стороны. - person farm ostrich; 21.05.2011
comment
Похоже на проблему с трекболом/dpad. Но спасибо, этот решил это. - person Meet Vora; 25.07.2016

Я столкнулся с той же проблемой и попробовал ваше исправление, но не смог заставить его работать. Что сработало для меня, так это добавление android:descendantFocusability="blocksDescendants" к <RelativeLayout> из макета элемента xml, list_item.xml в вашем случае. Это позволяет вызывать onItemClick().

person slybloty    schedule 05.04.2012
comment
android:focusable=false и android:desendantFocusability=blocksDescendants у меня не работали. - person jsDebugger; 16.09.2012
comment
если есть android:clickable="true" удалите его. - person Tom Siwik; 06.12.2012
comment
Проблема для меня начала возникать только тогда, когда я добавил CheckBox в свой вид элемента. Установка CheckBox на невозможность фокусировки решила мою проблему. Однако мне это решение нравится больше, потому что оно обрабатывает его для всех дочерних представлений на случай, если я сделаю это снова в будущем или другой класс chile View по умолчанию будет фокусироваться. - person Chris Feist; 21.01.2014
comment
Я ненавижу говорить «я тоже» ... но это решило ту же проблему для меня. Я просто хочу, чтобы я действительно понял, почему. - person alpartis; 12.08.2015
comment
Спасибо. Чтобы добавить мой анекдот, follandroid:descendantFocusability=blocksDescendants работал для меня до тех пор, пока android:clickable=true был удален (который я ошибочно добавил ранее, пытаясь найти разрешение). - person sobelito; 28.10.2015

Что сработало для меня:

1) Добавление android:descendantFocusability="blocksDescendants" в тег Relative Layout. Результат показан ниже:

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

2) Добавление android:focusable="false" к каждому элементу в примере list_item.xml:

<TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"     
        android:text="TextView"
        android:focusable="false" />
person newbie    schedule 16.02.2013
comment
добавление android:descendantFocusability=blocksDescendants к родителю макета ячейки сработало для меня - person MbaiMburu; 19.01.2018

Когда-то у меня была похожая проблема. У каждого элемента списка было текстовое представление и флажок, и только из-за этого флажка весь элемент списка не был «включен» для запуска события. Я решил это, сделав небольшой трюк внутри адаптера, когда я получал вид.

Непосредственно перед возвращением представления я поставил:

v.setOnClickListener(listener);

(Объект listener — это onItemClickListener, который я передал конструктору Adapter).

Но я должен сказать вам, проблема в том, что платформа, это ошибка.

person Francisco Javier Fernández    schedule 13.04.2011

У меня была такая же проблема, и я попытался решить ее, добавив

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

в мой item.xml, но он все равно не работает!!! На самом деле я обнаружил проблему в относительном макете, который содержит ведьма.

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

И когда я удалил его, все в порядке

person HoNzO    schedule 11.07.2014

person    schedule
comment
Метод getListView() не определен для типа Schema.loadSchema — не будет ли lv в любом случае таким же, как lstLessons (lstLessons — это ListView)? - person cvaldemar; 03.04.2011
comment
Я думаю, это может быть потому, что Schema не расширяет ListActivity. - person cvaldemar; 03.04.2011