Адаптеры действуют как мост между данными (в вашем случае массив строк, который вы передаете в адаптер), и ListView
(в вашем случае, myListView
). Любое изменение в ListView
должно быть выполнено в следующем порядке:
- внести необходимые изменения в сами данные
- передать эти новые данные адаптеру
- Адаптер обновляет представление списка
Я написал пример кода:
ItemAdapter
public class ItemAdapter extends BaseAdapter {
LayoutInflater mInflater;
String[] items;
String[] bushido;
String[] description;
// TextView finalscorre; // I commented out this TextView please see the comment below
Integer scr;
public ItemAdapter(Context c,String[] i ,String [] p ,String[] d, Integer scc,TextView sc) {
items = i;
bushido = p;
description = d;
// finalscorre = sc;
scr = scc;
mInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void updateItems(String[] i, String[] p, String[] d, Integer scc) {
items = i;
bushido = p;
description = d;
scr = scc;
// notify the adapter to refresh the list view.
notifyDataSetChanged()
}
@Override
public int getCount() {
return items.length;
}
@Override
public Object getItem(int i) {
return items[i];
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View convertView, ViewGroup parent) {
View v = mInflater.inflate(R.layout.my_listview_detail, null);
TextView nameTextView = v.findViewById(R.id.NameTextView);
TextView bushidoTextView = v.findViewById(R.id.bushidoTextView);
TextView descriptionTextView = v.findViewById(R.id.descriptionTextView);
//finalscorre = v.findViewById(R.id.finalScoreView);
TextView finalscorre = v.findViewById(R.id.finalScoreView);
String name = items[i];
String desc = description[i];
String bush = bushido[i];
// finalscorre.setText("Waat");
finalscorre.setText(scr);
nameTextView.setText(name);
descriptionTextView.setText(desc);
bushidoTextView.setText(bush);
// ItemAdapter.this.notifyDataSetChanged(); Do NOT call this method inside getView
return v;
}
}
Фрагмент
public class ListFrag extends Fragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Create and set adapter just once. Do not create or set new adapter in observer, for loop, etc.
itemAdapter = new ItemAdapter(getActivity(),items,bushido,description,s,finalScore);
myListView.setAdapter(itemAdapter);
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
model.getCurrentScore().observe(getViewLifecycleOwner(), new Observer<Integer>() {
@Override
public void onChanged(@Nullable Integer s) {
itemAdapter.updateItems(items,bushido,description,s);
}
});
}
}
Мне не удалось выяснить, что должно быть finalscorre
, поэтому я предположил, что это текстовое представление, в котором хранится итоговая оценка, которую вы упомянули, и все элементы представления списка должны иметь одинаковое значение. Если это не так, пожалуйста, уточните ваш вопрос.
Также обратите внимание, что хотя этого решения достаточно для решения конкретной проблемы, которую вы упомянули, есть и другие улучшения, которые можно сделать:
- Используйте
RecyclerView
вместо ListView
.
- Вместо того, чтобы поддерживать несколько
String[]
, определите POJO, которые представляют элемент и имеют один массив.
Также поможет проверка реализации этого адаптера в примере Google.