OnItemClickListener не стреляет

Я делаю приложение, которое имеет список упражнений, отображаемых в ListView. Я пытаюсь позволить пользователю выбрать элемент из списка, чтобы начать новое действие, но мой OnItemClickListener не запускается. Вот моя активность (не listActivity, это appCompatActivity):

ArrayList<Exercise> myExercises = new ArrayList<>();
AlertDialog.Builder alertDialogBuilder;
ArrayAdapter<Exercise> arrayAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list);
    refreshList();
    Button newExButton = (Button) findViewById(R.id.newExButton);

    arrayAdapter = new ArrayAdapter<Exercise>(
            this,
            android.R.layout.simple_list_item_1,
            myExercises );

    ListView lv = (ListView) findViewById(R.id.actList);
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            System.out.println("listener heard");
            // selected item
            int selection = position;
            startExercise(selection);
        }
    });

    lv.setAdapter(arrayAdapter);
}

public void refreshList(){
    setContentView(R.layout.activity_list);
    ListView lv = (ListView) findViewById(R.id.actList);

    lv.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
    lv.setAdapter(arrayAdapter);
}

public void startExercise(int selection){

    Intent exIntent = new Intent(this, CommenceExercise.class);
    Exercise chosenEx = myExercises.get(selection);
    Bundle info = new Bundle();
    info.putLong("duration", chosenEx.getTime());
    info.putString("name", chosenEx.getName());
    info.putString("description", chosenEx.getDescription());
    exIntent.putExtras(info);
    startActivity(exIntent);
}

Список изначально пуст, но пользователь добавляет элементы нажатием кнопки. Кнопка создает alertDialog с помощью кода ниже:

public void addNewActivity(View view) {
    //get prompts.xml view
    LayoutInflater li = LayoutInflater.from(context);
    View promptsView = li.inflate(R.layout.custom, null);

    alertDialogBuilder = new AlertDialog.Builder(
            context);

    // set prompts.xml to alertdialog builder
    alertDialogBuilder.setView(promptsView);

    final EditText userInput = (EditText) promptsView
            .findViewById(R.id.exNameInput);
    final EditText durInput = (EditText) promptsView
            .findViewById(R.id.exDurInput);

    // set dialog message
    alertDialogBuilder
            .setCancelable(false)
            .setPositiveButton("OK",
                    new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,int id) {
                                    long duration = 0;
                                    String exName;
                                    exName = userInput.getText().toString();
                                    duration = Integer.valueOf(durInput.getText().toString());
                                    myExercises.add(new Exercise(exName, duration));
                                   // create new exercise with user input
                                    refreshList();
                                }
                            })
                    .setNegativeButton("Cancel",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,int id) {
                                    dialog.cancel();
                                }
                            });
            // create alert dialog
            AlertDialog alertDialog = alertDialogBuilder.create();
            // show it
            alertDialog.show();
}

}

А вот и мой xml:

<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"
android:descendantFocusability="blocksDescendants"
tools:context="com.example.mytimer.ListActivity">

<TextView
    android:id="@+id/textView2"
    android:layout_width="146dp"
    android:layout_height="30dp"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:layout_marginTop="16dp"
    android:text="Activities"
    android:textAlignment="center"
    android:textSize="24sp"
    app:layout_constraintHorizontal_bias="0.502"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:layout_marginStart="16dp"
    android:clickable="false"
    android:layout_marginEnd="16dp" />

<Button
    android:id="@+id/newExButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginEnd="16dp"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:layout_marginStart="16dp"
    android:layout_marginTop="87dp"
    android:onClick="addNewActivity"
    android:text="New Exercise"
    android:textSize="18sp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/textView2" />

<ListView
    android:id="@+id/actList"
    android:layout_width="328dp"
    android:layout_height="301dp"
    android:layout_marginBottom="16dp"
    android:layout_marginEnd="16dp"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:layout_marginStart="16dp"
    android:layout_marginTop="16dp"
    android:descendantFocusability="blocksDescendants"
    android:focusable="false"
    android:clickable="false"
    android:focusableInTouchMode="false"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/newExButton"
    app:layout_constraintVertical_bias="1.0">
<requestFocus/>
</ListView>

<TextView
    android:id="@+id/debugText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="36dp"
    android:text="TextView"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    android:clickable="false"
    app:layout_constraintTop_toBottomOf="@+id/textView2" />

</android.support.constraint.ConstraintLayout>

Когда я нажимаю на элемент, добавленный в список, ничего не происходит. Я могу сказать, что OnItemClickListener не запускается, потому что строка System.out никогда не печатается. Я в недоумении, почему я не могу заставить его работать. Любая помощь будет принята с благодарностью. Заранее спасибо.

4 ответа

Решение

Вам необходимо удалить приведенные ниже атрибуты listview из xml:

    android:descendantFocusability="blocksDescendants"
    android:focusable="true"
    android:clickable="true" 
    android:focusableInTouchMode="true"

Кроме того, нет необходимости в refreshList(), это на самом деле плохой способ сделать что-то, вместо этого в вашей addNewActivity (), когда ваша модель готова (возможно, по нажатию положительной кнопки), добавьте этот элемент в arrayAdapter, а затем выполните arrayAdapter.notifyDataSetChanged. ().

Я надеюсь, это поможет вам!

Измени свой refreshList метод ниже одного

public void refreshList(){
    arrayAdapter.notifyDataSetChanged();
}

Что вы делаете, раздувая ListView снова и установка новых данных, а не обновление старых. И когда вы назначаете новое значение ListView ты забыл установить onClickListener,

Это сработает.

Я думаю, что проблема в XML, пожалуйста, установите ListView кликабельны true

пожалуйста, внесите некоторые изменения в XML

<ListView
    android:id="@+id/actList"
    android:layout_width="328dp"
    android:layout_height="301dp"
    android:layout_marginBottom="16dp"
    android:layout_marginEnd="16dp"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:layout_marginStart="16dp"
    android:layout_marginTop="16dp"
    android:descendantFocusability="blocksDescendants"
    android:focusable="true" // change this
    android:clickable="true" // change this
    android:focusableInTouchMode="true" // change this
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/newExButton"
    app:layout_constraintVertical_bias="1.0">
<requestFocus/>
</ListView>

Это действительно странно... ваш код должен был сработать... Я бы посоветовал вам попытаться реализовать в своей деятельности, чтобы включить lv.setClcickable(true) а также lv.setEnable(true):

 public class MenuActivity extends AppCompatActivity implements 
 AdapterView.OnItemClickListener{    
     ArrayList<Exercise> myExercises = new ArrayList<>();
     AlertDialog.Builder alertDialogBuilder;
     ArrayAdapter<Exercise> arrayAdapter;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_list);
           refreshList();
           Button newExButton = (Button) findViewById(R.id.newExButton);

           arrayAdapter = new ArrayAdapter<Exercise>(
                     this,
                     android.R.layout.simple_list_item_1,
                     myExercises );

           ListView lv = (ListView) findViewById(R.id.actList);
           lv.setClickable(true);
           lv.setEnabled(true);
           lv.setOnItemClickListener(new AdapterView.OnItemClickListener(){
        public void onItemClick(AdapterView<?> parent, View view , int 
           position, long id)
         {
                       startExercise(position);
         }
           lv.setAdapter(arrayAdapter);
     }

     public void refreshList(){
           setContentView(R.layout.activity_list);
           ListView lv = (ListView) findViewById(R.id.actList);

           lv.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
           lv.setAdapter(arrayAdapter);
     }

     public void startExercise(int selection){

         Intent exIntent = new Intent(this, CommenceExercise.class);
         Exercise chosenEx = myExercises.get(selection);
         Bundle info = new Bundle();
         info.putLong("duration", chosenEx.getTime());
         info.putString("name", chosenEx.getName());
         info.putString("description", chosenEx.getDescription());
         exIntent.putExtras(info);
         startActivity(exIntent);
   }     


}

или добавьте эти три строки в ваш XML

 android:focusable="false"
 android:focusableInTouchMode="false"
 android:clickable="true
 android:descendantFocusability="blocksDescendants"

Если есть какие-либо фокусируемые дочерние виды, тогда первый клик всегда будет для фокуса, и я бы предложил вам использовать пользовательский ListView с Viewholder Шаблон для эффективности или Recyclerview библиотеки поддержки это сделает вашу прокрутку плавной и не создаст лишних объектов просмотра... Он создаст только тот объект просмотра, который будет соответствовать экрану

Вот ссылка для RecyclerView https://guides.codepath.com/android/using-the-recyclerview

Другие вопросы по тегам