У меня возникла проблема с обновлением ListView в моем приложении для Android. Я искал решение и читал несколько ответов, но никто не решил мою проблему:
У меня есть список с двумя элементами, отображаемыми следующим образом:
После перезагрузки данных из источника я получаю те же 2 элемента, но в списке это отображается так:
Однако, когда я нажимаю на позицию 0 в новом списке, отображаются правильные данные элемента 1 (нажатие на позицию 1 также показывает правильные данные элемента 2).
Проблема в том, что он отображает Item 2 в позиции 0 и в позиции 1 (дважды).
Вот код, в котором обновляется список и настраивается адаптер:
public class FishTankFragment extends DeviceFragment {
...
private final List<FishTankStatus.Schedule> schedulesList = new ArrayList<>();
private ScheduleAdapter scheduleAdapter;
...
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
scheduleAdapter = new ScheduleAdapter(view.getContext(), schedulesList);
screenBinding.lvSchedules.setAdapter(scheduleAdapter);
screenBinding.lvSchedules.setOnItemClickListener((parent, view1, position, id) -> {
new ScheduleItemClickListener(this.getContext(), schedulesList.get(position), position);
});
...
}
@Override
public <T> void onResponse(T responseObject) {
...
schedulesList.clear();
schedulesList.addAll(data.getSchedules());
scheduleAdapter.notifyDataSetChanged();
...
}
Вот код адаптера:
public class ScheduleAdapter extends BaseAdapter {
private ScheduleItemBinding itemBinding;
private final List<FishTankStatus.Schedule> schedules;
private final Context context;
public ScheduleAdapter(@NonNull Context context, @NonNull List<FishTankStatus.Schedule> objects) {
this.context = context;
schedules = objects;
}
@Override
public int getCount() {
return schedules.size();
}
@Override
public FishTankStatus.Schedule getItem(int position) {
return schedules.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
itemBinding = ScheduleItemBinding.inflate(LayoutInflater.from(context));
view = itemBinding.getRoot();
}
if (!schedules.isEmpty()) {
String start = StringUtils.printTime(schedules.get(position).getStart());
String end = StringUtils.printTime(schedules.get(position).getEnd());
itemBinding.tvScheduleStart.setText(start);
itemBinding.tvScheduleEnd.setText(end);
FishTankStatus.Schedule schedule = schedules.get(position);
for (String device : schedule.getDevices()) {
switch (device) {
case "something":
itemBinding.ivYellowlightIcon.setVisibility(View.VISIBLE);
break;
case "something 1":
itemBinding.ivBluelightIcon.setVisibility(View.VISIBLE);
break;
case "something 2":
itemBinding.ivAirIcon.setVisibility(View.VISIBLE);
}
}
if (schedules.get(position).getActive()) {
ColorStateList white = ColorStateList.valueOf(
view.getResources().getColor(R.color.white, view.getContext().getTheme()));
itemBinding.lySchedule.setBackground(ResourcesCompat.getDrawable(view.getResources(),
R.drawable.rectangle_p_light_8,
view.getContext().getTheme()));
...
}
}
return view;
}
}
ListView имеет ширину и высоту, установленные как match_parent в родительском ConstraintLayout, где ширина = 0dp (имеет родителя) и высота = match_parent
Смотрите видео: запись экрана
Спасибо за помощь.
Я отладил приложение. После очистки schedulesList.clear()
он содержал 0 элементов во фрагменте, а также в BaseAdapter. После добавления всех элементов из источника он содержал правильные элементы в списках расписаний как во фрагменте, так и в BaseAdapter.
Я попытался заполнить данные в адаптере как отдельный объект списка, используя clear и addAll.
Отвечу на свой вопрос будущим посетителям...
Просто используйте RecyclerView
Это решило все мои проблемы. Но я до сих пор не знаю, почему возникла вышеуказанная проблема.