Android ListAdapter.getItemCount() 始终返回 0

问题描述

如果 TextView 为空,我会尝试显示 RecyclerView。 但是 getItemCount() of 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());
        }
    }
}

任何帮助将不胜感激。

解决方法

数据只会在 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 设置为观察者 lambda。

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

您还可以使用提交列表变体 submitList(@Nullable List<String> list,@Nullable Runnable commitCallback),它将为您提供回调,您可以在 Runnable 中执行相同的操作。在这种情况下,这几乎是一样的。