Android ListAdapter.getItemCount() всегда возвращает 0

#java #android #android-recyclerview #android-listadapter

#java #Android #android-recyclerview #android-listadapter

Вопрос:

Я пытаюсь показать TextView , если RecyclerView пусто. Но getItemCount() ListAdapter всегда возвращает 0, даже если RecyclerView показывает элементы.

Fragment.java

 public class ProjectsFragment extends Fragment {

    private RepoViewModel repoViewModel;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        FloatingActionButton floatingActionButton = ((MainActivity) requireActivity()).getFloatingActionButton();
        floatingActionButton.setVisibility(View.VISIBLE);

        return inflater.inflate(R.layout.fragment_projects, container, false);
    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        TextView textview_no_project = view.findViewById(R.id.textview_no_project);

        RecyclerView recyclerView = view.findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(requireActivity().getApplicationContext()));
        final RepoListAdapter adapter = new RepoListAdapter(new RepoListAdapter.RepoDiff());

        if (adapter.getItemCount() == 0) {
            recyclerView.setVisibility(View.INVISIBLE);
            textview_no_project.setVisibility(View.VISIBLE);
        }
        else {
            recyclerView.setVisibility(View.VISIBLE);
            textview_no_project.setVisibility(View.INVISIBLE);
        }
        recyclerView.setAdapter(adapter);
        repoViewModel = new ViewModelProvider(requireActivity()).get(RepoViewModel.class);
        repoViewModel.getAllRepos().observe(getViewLifecycleOwner(), adapter::submitList);
    }
}
 

RepoListAdapter.java

 public class RepoListAdapter extends ListAdapter<Repo, RepoViewHolder> {

    public RepoListAdapter(@NonNull DiffUtil.ItemCallback<Repo> diffCallback) {
        super(diffCallback);
    }

    @NonNull
    @Override
    public RepoViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        return RepoViewHolder.create(viewGroup);
    }

    @Override
    public void onBindViewHolder(RepoViewHolder holder, int position) {
        Repo current = getItem(position);
        holder.bind(current.getName());
    }

    public static class RepoDiff extends DiffUtil.ItemCallback<Repo> {

        @Override
        public boolean areItemsTheSame(@NonNull Repo oldItem, @NonNull Repo newItem) {
            return oldItem == newItem;
        }

        @Override
        public boolean areContentsTheSame(@NonNull Repo oldItem, @NonNull Repo newItem) {
            return oldItem.getName().equals(newItem.getName());
        }
    }
}
 

Буду признателен за любую помощь.

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

1. Ваш фрагмент пытается вызвать getItemCounts перед отправкой данных в адаптер. Поэтому при запуске он всегда будет равен нулю.

Ответ №1:

Данные будут установлены только после adapter::submitList вызова, т.Е. После вызова наблюдателя данных в реальном времени. Поэтому вам нужно внести изменения после этого. Есть несколько способов, как вы можете это сделать. Ниже приведен один из способов, для которого вам нужно создать адаптер как глобальный или просто получить его из RecyclerView.

 public void onLoaded(List<Repo> list){
    if (list.size() == 0) {
        recyclerView.setVisibility(View.INVISIBLE);
        textview_no_project.setVisibility(View.VISIBLE);
    }
    else {
        recyclerView.setVisibility(View.VISIBLE);
        textview_no_project.setVisibility(View.INVISIBLE);
        adapter.submitList(list);
    }
}
 

Устанавливается onLoaded в качестве наблюдателя лямбда.

 repoViewModel.getAllRepos().observe(getViewLifecycleOwner(), this::onLoaded);
 

Вы также можете использовать вариант отправки списка submitList(@Nullable List<String> list, @Nullable Runnable commitCallback) , который предоставит вам обратный вызов, и вы можете делать то же самое внутри Runnable . в данном случае это почти то же самое.