首页 > 解决方案 > RecyclerView 不会将从 Firestore 检索到的数据加载到 ItemView

问题描述

所以,基本上我想做的是在我的 Android 应用程序的提要(HomeFragment)上显示一堆 Post 类型的对象。这些帖子已从 Firestore 成功检索(我确实检查了调试器),但不知何故,并非所有帖子都加载到了 recyclerView 中。itemViewHolder 仅加载了我将其定义为 XML 的方式,字段填充了 lore Ipsum。

这将是我的代码:

首页片段:


public class HomeFragment extends Fragment {

    private RecyclerView recyclerView;
    private RecyclerViewAdapter recyclerViewAdapter;
    private boolean isLoading = false;
    private ArrayList<String> rowsArrayList = new ArrayList<>();
    public static ArrayList<Post> appliedToList = new ArrayList<>();
    private User currentUser = new User();
    private View root;
    private TextView userState;

    private FirebaseFirestore db = FirebaseFirestore.getInstance();
    private String userId = FirebaseAuth.getInstance().getCurrentUser() != null ? FirebaseAuth.getInstance().getCurrentUser().getUid() : null;


    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        root = inflater.inflate(R.layout.fragment_home, container, false);

        setState();
        appliedToPostsRetrieverFromHomePage(getContext());
        checkForPostFragment();
        recyclerView = root.findViewById(R.id.recyclerView);
        initAdapter();
        initScrollListener();

        return root;
    }

    private void initAdapter() {
        recyclerViewAdapter = new RecyclerViewAdapter(getActivity(), 2);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView.setAdapter(recyclerViewAdapter);
    }

    private void initScrollListener() {
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
                if (!isLoading) {
                    if (linearLayoutManager != null && linearLayoutManager.findLastCompletelyVisibleItemPosition() == rowsArrayList.size() - 1) {
                        //bottom of list!
                        loadMore();
                        isLoading = true;
                    }
                }
            }
        });
    }

    private void loadMore() {
        rowsArrayList.add(null);
        recyclerViewAdapter.notifyItemInserted(rowsArrayList.size() - 1);

        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                rowsArrayList.remove(rowsArrayList.size() - 1);
                int scrollPosition = rowsArrayList.size();
                recyclerViewAdapter.notifyItemRemoved(scrollPosition);
                int currentSize = scrollPosition;
                int nextLimit = currentSize + 10;
                while (currentSize - 1 < nextLimit) {
                    rowsArrayList.add("Item " + currentSize);
                    currentSize++;
                }
                recyclerViewAdapter.notifyDataSetChanged();
                isLoading = false;
            }
        }, 2000);
    }

    @Override
    public void onAttachFragment(@NonNull Fragment fragment) {
        super.onAttachFragment(fragment);
    }

回收器视图适配器:

所有视图类型都代表一种相同的布局,它们之间的唯一区别是写在某个按钮上的内容。请记住,某些帖子已成功加载!


public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private final int VIEW_TYPE_APPLY = 0;
    private final int VIEW_TYPE_MORE = 1;
    private final int VIEW_TYPE_BEGIN = 2;
    private final int VIEW_TYPE_PENDING = 3;
    private final int VIEW_TYPE_END = 4;
    private final int VIEW_TYPE_ON_GOING = 5;
    private final int VIEW_TYPE_LOADING = 6;
    private ArrayList<Post> list = new ArrayList();
    private static final String TAG = RecyclerViewAdapter.class.getSimpleName();
    private Context context;
    private User currentUser;
    private int recyclerType;
    static ArrayList<User> applicantsList = new ArrayList<>();

    private String userId = FirebaseAuth.getInstance().getCurrentUser() != null ? FirebaseAuth.getInstance().getCurrentUser().getUid() : null;
    private FirebaseFirestore db = FirebaseFirestore.getInstance();

    public RecyclerViewAdapter(Context context, int recyclerType) {
        this.context = context;
        this.recyclerType = recyclerType;
        if (recyclerType == 0) {
            myPostsRetriever(context);
        } else if (recyclerType == 1) {
            appliedToPostsRetriever(context);
        } else if (recyclerType == 2) {
            homePostsRetriever(context);
        }
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == VIEW_TYPE_APPLY) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_apply, parent, false);
            return new ItemViewHolder(view);
        } else if (viewType == VIEW_TYPE_MORE) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_more, parent, false);
            return new LoadingViewHolder(view);
        } else if (viewType == VIEW_TYPE_BEGIN) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_begin, parent, false);
            return new LoadingViewHolder(view);
        } else if (viewType == VIEW_TYPE_PENDING) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_pending, parent, false);
            return new LoadingViewHolder(view);
        } else if (viewType == VIEW_TYPE_END) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_end, parent, false);
            return new LoadingViewHolder(view);
        } else if (viewType == VIEW_TYPE_ON_GOING) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_on_going, parent, false);
            return new LoadingViewHolder(view);
        } else {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_loading, parent, false);
            return new LoadingViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
        if (viewHolder instanceof ItemViewHolder) {
            populateItemRows((ItemViewHolder) viewHolder, position);
        } else if (viewHolder instanceof LoadingViewHolder) {
            showLoadingView((LoadingViewHolder) viewHolder, position);
        }
    }

    @Override
    public int getItemCount() {
        return list == null ? 0 : list.size();
    }

    @Override
    public int getItemViewType(int position) {
        if (list.get(position) != null) {
            if (!list.get(position).getOwner().equals(userId) &&
                    !checkIfAlreadyAppliedToPost(position) &&
                    list.get(position).getMinNeededPersons() >= list.get(position).getApplicants()) {
                return VIEW_TYPE_APPLY;
            } else if (recyclerType == 1) {
                return VIEW_TYPE_MORE;
            } else if (list.get(position).getOwner().equals(userId) && timeCheck(list.get(position))) {
                return VIEW_TYPE_BEGIN;
            } else if (list.get(position).getOwner().equals(userId) && checkIfStarted(position)
                    || !list.get(position).getOwner().equals(userId) && checkIfAlreadyAppliedToPost(position) && !checkIfStarted(position)) {
                return VIEW_TYPE_PENDING;
            } else if (list.get(position).getOwner().equals(userId) && checkIfStarted(position)) {
                return VIEW_TYPE_END;
            } else if (!list.get(position).getOwner().equals(userId) && checkIfStarted(position)){
                return VIEW_TYPE_ON_GOING;
            }else if (list.get(position).getOwner().equals(userId))
                return VIEW_TYPE_MORE;
        }
        return VIEW_TYPE_LOADING;
    }

    private class ItemViewHolder extends RecyclerView.ViewHolder {

        TextView title;
        TextView description;
        TextView location;
        TextView minNeededPersons;
        TextView maxNeededPersons;
        TextView reward;
        TextView time;
        CheckBox physical;
        Button button;

        ItemViewHolder(@NonNull View itemView) {
            super(itemView);
            title = itemView.findViewById(R.id.postTitle);
            description = itemView.findViewById(R.id.postDescription);
            location = itemView.findViewById(R.id.postLocationText);
            time = itemView.findViewById((R.id.postDateAndTime));
            minNeededPersons = itemView.findViewById(R.id.people);
            maxNeededPersons = itemView.findViewById(R.id.people);
            reward = itemView.findViewById(R.id.reward);
            physical = itemView.findViewById(R.id.checkBox2);
            button = itemView.findViewById(R.id.applyButton);
        }
    }

    private class LoadingViewHolder extends RecyclerView.ViewHolder {
        ProgressBar progressBar;

        LoadingViewHolder(@NonNull View itemView) {
            super(itemView);
            progressBar = itemView.findViewById(R.id.progressBar);
        }
    }

    private void showLoadingView(LoadingViewHolder viewHolder, int position) {
    }

    private void populateItemRows(ItemViewHolder viewHolder, int position) {

        Post item = list.get(position);
        viewHolder.title.setText(item.getTheTitle());
        viewHolder.description.setText(item.getDescription());
        viewHolder.location.setText(item.getLocation());
        viewHolder.location.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent showLocation = new Intent(context, MapsActivity.class);
                context.startActivity(showLocation);
            }
        });
        viewHolder.minNeededPersons.setText(String.valueOf(item.getMinNeededPersons()));
        viewHolder.maxNeededPersons.setText(String.valueOf(item.getMaxPersonsNeeded()));
        viewHolder.reward.setText(String.valueOf(item.getReward()));
        viewHolder.physical.setChecked(item.isPhysical());
        Date timeAndDate = item.getTime().toDate();
        viewHolder.time.setText(new SimpleDateFormat("HH:mm   dd.MM.yyyy").format(timeAndDate));

        viewHolder.button.setOnClickListener(new View.OnClickListener() {
            @SuppressLint("SetTextI18n")
            @Override
            public void onClick(View v) {
                if (viewHolder.button.getText().equals(context.getResources().getString(R.string.apply))) {
                    onApplyTapped(position);
                    viewHolder.button.setText(R.string.pending);
                    viewHolder.button.setBackgroundColor(Color.parseColor("#F2CF59"));
                    viewHolder.button.setClickable(false);
                } else if (viewHolder.button.getText().equals(context.getResources().getString(R.string.begin_job))) {
                    onBeginTapped(position);
                    viewHolder.button.setText(R.string.end_job);
                    viewHolder.button.setBackgroundColor(Color.parseColor("#F8CA9D"));
                } else if (viewHolder.button.getText().equals(context.getResources().getString(R.string.end_job))) {
                    onEndTapped(position);
                    viewHolder.button.setBackgroundColor(Color.parseColor("#FB8E7E"));
                    viewHolder.button.setClickable(false);
                    viewHolder.button.setText(R.string.finished);
                }
            }
        });

        viewHolder.itemView.findViewById(R.id.seePostButton).setOnClickListener(new View.OnClickListener() 
{ not relevant }


    private void homePostsRetriever(Context context) {

        FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
        rootRef.collectionGroup("posts").limit(10).get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
            @Override
            public void onSuccess(QuerySnapshot documentSnapshots) {
                for (DocumentSnapshot documentSnapshot : documentSnapshots.getDocuments()) {
                    Post post = new Post();
                    post.setAvailability(documentSnapshot.getBoolean("available"));
                    post.setTitle(documentSnapshot.getString("title"));
                    post.setDescription(documentSnapshot.getString("description"));
                    post.setLocation(documentSnapshot.getString("location"));
                    post.setApplicants(documentSnapshot.getLong("applicants").intValue());
                    post.setOwner(documentSnapshot.getString("owner"));
                    post.setMinNeededPersons(documentSnapshot.getLong("minNrOfPeople").intValue());
                    post.setMaxPersonsNeeded(documentSnapshot.getLong("maxNrOfPeople").intValue());
                    post.setReward(Objects.requireNonNull(documentSnapshot.getLong("reward")).floatValue());
                    post.setPhysical(documentSnapshot.getBoolean("physicalExcertion"));
                    post.setTime(documentSnapshot.getTimestamp("time"));
                    post.setId(documentSnapshot.getId());
                    post.setStarted(documentSnapshot.getBoolean("started"));

                    list.add(post);
                }
                notifyDataSetChanged();
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(context, "No document found", Toast.LENGTH_SHORT).show();
            }
        });
    }

标签: androidfirebaseandroid-fragmentsandroid-recyclerviewgoogle-cloud-firestore

解决方案


我认为您没有正确调用绑定方法,请尝试:

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {

    if (viewHolder instanceof ItemViewHolder) {

        ItemViewHolder holder = (ItemViewHolder)viewHolder;
        holder.populateItemRows(holder, position);

    } else if (viewHolder instanceof LoadingViewHolder) {

        LoadingViewHolder holder = (LoadingViewHolder)viewHolder;
        holder.showLoadingView(holder , position);
    }
}

还有这个方法:

private void populateItemRows(ItemViewHolder viewHolder, int position) {
.....
....
....
}

ItemViewHolder在您的班级中找不到


推荐阅读