Android ListView с ошибкой пользовательского ArrayAdapter при использовании setOnItemClickListener

#android #android-listview #android-arrayadapter

#Android #android-listview #android-arrayadapter

Вопрос:

Я прикрепил XML-файл для изменения стиля моих объектов, отображаемых в виде списка, создавая пользовательский класс ArrayAdapter. Теперь я хочу установить прослушиватель, который сообщает мне, какой элемент был выбран пользователем. Он не только выдает сообщения об ошибках, но и не выполняет никакого кода внутри метода. Я попытался вернуться к простому ListView без пользовательского адаптера (используя один из адаптеров по умолчанию), и это работает. Я уже посмотрел здесь и погуглил сообщение об ошибке, и, похоже, проблема связана с разрешениями SELinux, но я не изменил ни одно из них также потому, что понятия не имею, как это сделать.

Это сообщение об ошибке:

W / RenderThread: type=1400 аудит (0.0:5784638): avc: отказано в { чтении} для name=»u: object_r: vendor_default_prop:s0″ dev=»tmpfs» ino= 21556 scontext=u: r: ненадежное приложение: s0: c164,c256, c512, c768 tcontext =u:object_r:vendor_default_prop:s0 tclass= разрешение на доступ к файлу=0

Это адаптер:

 public class CustomAdapter extends ArrayAdapter<Schedule> {

public CustomAdapter(Context context, ArrayList<Schedule> items) {
    super(context, R.layout.custom_row, items);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    LayoutInflater myInflater = LayoutInflater.from(getContext());

    View customView = myInflater.inflate(R.layout.custom_row, parent, false);

    Schedule item = getItem(position);

    TextView scheduleName = customView.findViewById(R.id.customRow_scheduleName);
    TextView scheduleStart = customView.findViewById(R.id.customRow_startDate);
    TextView scheduleEnd = customView.findViewById(R.id.customRow_endDate);

    scheduleName.setText(item.getName());
    scheduleStart.setText(item.getStartDate());
    scheduleEnd.setText(item.getEndDate());

    return customView;
}}
  

Это основной класс, который содержит ListView

 public class MainActivity extends AppCompatActivity implements CreateNewScheduleFragment.OnInputListener {

private ArrayList<Schedule> scheduleCollection;

private ListAdapter customAdapter;

ListView scheduleListView;
Button newScheduleBtn;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    newScheduleBtn = findViewById(R.id.addNewSchedule);

    scheduleCollection = new ArrayList<>();

    //String[] array = {"pippo", "pluto"};

    customAdapter = new CustomAdapter(this, scheduleCollection);
    scheduleListView = findViewById(R.id.scheduleListView);
    scheduleListView.setAdapter(customAdapter);//new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, array));

    // #################### DEBUG
    scheduleCollection.add(new Schedule("Scheda 1", "14-3", "21-04", "ciao"));
    scheduleCollection.add(new Schedule("Scheda 2", "22-05", "5-06", "ciao"));
    ((ArrayAdapter<Schedule>)customAdapter).notifyDataSetChanged();
    // #################### DEBUG

    scheduleListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Log.i("info", "I'm item in position "   String.valueOf(position));
        }
    });}
  

Это файл макета

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="120dp"
    android:background="@drawable/fragment_rounded_corners"
    android:padding="8dp"
    android:layout_margin="10dp">

    <TextView
        android:id="@ id/customRow_scheduleName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="8dp"
        android:layout_marginTop="0dp"
        android:maxWidth="200dp"
        android:text="Scheda 1"
        android:textColor="@color/colorTextIcons"
        android:textSize="35dp" />

    <TextView
        android:id="@ id/customRow_startDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginEnd="20dp"
        android:layout_toStartOf="@ id/customRow_endDate"
        android:text="14-03"
        android:textColor="@color/colorTextIcons"
        android:textSize="20dp" />

    <TextView
        android:id="@ id/customRow_endDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentBottom="true"
        android:text="21-05"
        android:textColor="@color/colorTextIcons"
        android:textSize="20dp" />

    <TextView
        android:id="@ id/textView8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@ id/customRow_startDate"
        android:layout_alignStart="@ id/customRow_startDate"
        android:layout_marginBottom="10dp"
        android:text="period:"
        android:textColor="@color/colorTextIcons" />

    <Button
        android:id="@ id/customRow_cancelBtn"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:background="@drawable/ic_cancel_black_24dp"/>

</RelativeLayout>
  

И это пользовательский класс объекта:

 package com.example.fabri.gymine;

import android.util.Log;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class Schedule {

    private ArrayList<Workout> workouts;
    private String name;
    private String startDate, endDate, filePath;

    public Schedule(String name, String startDate, String endDate, String filePath) {
        this.name = name;
        this.startDate = startDate;
        this.endDate = endDate;
        this.filePath = filePath;
        workouts = new ArrayList<>();

        //loadScheduleFromFile();
    }

    public void removeWorkout(Workout w){
        workouts.remove(w);
    }

    public int workoutCount(){
        return workouts.size();
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public String getStartDate() {
        return startDate;
    }

    public String getEndDate() {
        return endDate;
    }

    private String myReadLine(BufferedReader br) throws IOException{
        String tmp = br.readLine();
        Log.i("Letto", tmp);
        return tmp;
    }
}
  

Комментарии:

1. Я попробовал ваш опубликованный код. Это работает, поэтому проблема может быть в вашем макете или пользовательском классе объектов. Вы также можете попробовать очистить и перестроить свой проект. Надеюсь, это поможет!

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

3. Ваша проблема странная. Я перепробовал весь ваш опубликованный код, и у меня это работает. Я тестировал с CreateNewScheduleFragment. OnInputListener как пустой метод, Workout как пустой класс, два фоновых изображения с простыми изображениями PNG. Мое тестируемое устройство работает под управлением Android 7.1 Надеюсь, эта информация полезна!

4. Я пробовал много раз, и, похоже, ничего не работает, поэтому я решил удалить представление списка и вместо этого перейти к RecyclerView. Это работает безупречно. Должен ли я удалить вопрос?

Ответ №1:

 @Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Check if an existing view is being reused, otherwise inflate the view
    View listItemView = convertView;
    if (listItemView == null) {
        listItemView = LayoutInflater.from(getContext()).inflate(
                R.layout.custom_row, parent, false);
    }
}
  

Также используйте

    scheduleListView.setAdapter(customAdapter);
  

после

 scheduleCollection.add(new Schedule("Scheda 1", "14-3", "21-04", "ciao"));
scheduleCollection.add(new Schedule("Scheda 2", "22-05", "5-06", "ciao"));
  

Комментарии:

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