android - 如何使用 firestore 在回收站 View 中加载批量数据?

标签 android firebase android-recyclerview google-cloud-firestore

我想知道如何使用 firestore 在 recylcer View 中加载更多数据。

 Query query = FirebaseFirestore.getInstance()
            .collection("ie").limit(5);  
adapter=new InterviewAdapter(this,query);    
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

适配器类如下所示:

public class InterviewAdapter extends FireStoreAdapter<InterviewAdapter.ViewHolder> {

public interface OnInterviewSelectedListener {

    void onInterviewSelected(DocumentSnapshot interview);

}

private InterviewAdapter.OnInterviewSelectedListener mListener;

public InterviewAdapter(Query query, OnInterviewSelectedListener listener) {
    super(query);
    mListener = listener;
}

@Override
public InterviewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    return new InterviewAdapter.ViewHolder(inflater.inflate(R.layout.ie, parent, false));
}

@Override
public void onBindViewHolder(InterviewAdapter.ViewHolder holder, int position) {
    holder.bind(getSnapshot(position), mListener);
}

static class ViewHolder extends RecyclerView.ViewHolder {

    TextView title,companyName,username,views,isHired;

    public ViewHolder(View itemView) {
        super(itemView);
        title= (TextView) itemView.findViewById(R.id.title);
        companyName= (TextView) itemView.findViewById(R.id.companyName);
        username= (TextView) itemView.findViewById(R.id.username);
        views= (TextView) itemView.findViewById(R.id.views);
        isHired= (TextView) itemView.findViewById(R.id.isHired);
    }

    public void bind(final DocumentSnapshot snapshot,
                     final OnInterviewSelectedListener listener) {


        InterviewExperience experience;
        String companyName=snapshot.getString("companyName");
        boolean isHired=Boolean.valueOf(snapshot.getBoolean("isHired"));
        String username=snapshot.getString("username");
        long views=new Double(Double.valueOf(snapshot.getDouble("views"))).longValue();

        String id=snapshot.getId();


        String title=snapshot.getString("title");
        experience=new InterviewExperience(id,title,companyName,username,isHired,views,null,null);


        this.title.setText(experience.getTitle());
        this.companyName.setText("Company Name: "+experience.getCompanyName());
        this.isHired.setText("Hired: "+experience.isHired());
        this.views.setText("Views: "+experience.getViews()+"");
        this.username.setText("Created By: "+experience.getUsername());



        // Click listener
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (listener != null) {
                    listener.onInterviewSelected(snapshot);
                }
            }
        });
    }

}
}

public abstract class FireStoreAdapter<VH extends RecyclerView.ViewHolder>
    extends RecyclerView.Adapter<VH>
    implements EventListener<QuerySnapshot> {

private static final String TAG = "FirestoreAdapter";

private Query mQuery;
private ListenerRegistration mRegistration;

private ArrayList<DocumentSnapshot> mSnapshots = new ArrayList<>();

public FireStoreAdapter(Query query) {
    mQuery = query;
}

@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
    if (e != null) {
        Log.w(TAG, "onEvent:error", e);
        onError(e);
        return;
    }

    // Dispatch the event
    Log.d(TAG, "onEvent:numChanges:" + documentSnapshots.getDocumentChanges().size());
    for (DocumentChange change : documentSnapshots.getDocumentChanges()) {
        switch (change.getType()) {
            case ADDED:
                onDocumentAdded(change);
                break;
            case MODIFIED:
                onDocumentModified(change);
                break;
            case REMOVED:
                onDocumentRemoved(change);
                break;
        }
    }

    onDataChanged();
}

public void startListening() {
    if (mQuery != null && mRegistration == null) {
        mRegistration = mQuery.addSnapshotListener(this);
    }
}

public void stopListening() {
    if (mRegistration != null) {
        mRegistration.remove();
        mRegistration = null;
    }

    mSnapshots.clear();
    notifyDataSetChanged();
}

public void setQuery(Query query) {
    // Stop listening
    stopListening();

    // Clear existing data
    mSnapshots.clear();
    notifyDataSetChanged();

    // Listen to new query
    mQuery = query;
    startListening();
}

@Override
public int getItemCount() {
    return mSnapshots.size();
}

protected DocumentSnapshot getSnapshot(int index) {
    return mSnapshots.get(index);
}

protected void onDocumentAdded(DocumentChange change) {
    mSnapshots.add(change.getNewIndex(), change.getDocument());
    notifyItemInserted(change.getNewIndex());
}

protected void onDocumentModified(DocumentChange change) {
    if (change.getOldIndex() == change.getNewIndex()) {
        // Item changed but remained in same position
        mSnapshots.set(change.getOldIndex(), change.getDocument());
        notifyItemChanged(change.getOldIndex());
    } else {
        // Item changed and changed position
        mSnapshots.remove(change.getOldIndex());
        mSnapshots.add(change.getNewIndex(), change.getDocument());
        notifyItemMoved(change.getOldIndex(), change.getNewIndex());
    }
}

protected void onDocumentRemoved(DocumentChange change) {
    mSnapshots.remove(change.getOldIndex());
    notifyItemRemoved(change.getOldIndex());
}

protected void onError(FirebaseFirestoreException e) {};

protected void onDataChanged() {}
}

我使用了 Firestore 文档示例中提供的 Firestore 适配器代码。谁能告诉我如何使用查询对象加载更多数据?

当用户滚动到列表末尾时,如何在回收站 View 中加载接下来的 5 个项目?

最佳答案

您可以使用Query 的方法对Query 的结果进行分页,例如startAt()。 , startAfter() , endAt() , endBefore()使用指定的 DocumentSnapshot

如果我认为您的集合称为“采访”,您可以像这样向您的 FireStoreAdapter 添加一个方法:

private void paginate(final DocumentSnapshot last, final int limit) {
    final Query subset;
    if (last == null) {
        subset = db.collection("interviews")
                .limit(limit);
    } else {
        subset = db.collection("interviews")
                .startAfter(last)
                .limit(limit);
    }
    setQuery(subset);
}

您可以在 onEvent() 中保留最后一个 DocumentSnapshot:

final List<DocumentChange> changes = documentSnapshots.getDocumentChanges();
final DocumentSnapshot lastDocument = changes.get(changes.size() - 1).getDocument();

最后,当用户滚动到列表末尾时:

paginate(lastDocument, 5);

onDocumentAdded() 会处理它。小心不要使用startAt(),因为它不会排除最后一个(已经在列表末尾,并且会重复它)。

关于android - 如何使用 firestore 在回收站 View 中加载批量数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46795445/

相关文章:

java - Android - 复制文件后关闭电源导致文件损坏

firebase - Flutter Firebase 远程配置类中没有虚拟方法 isDeveloperModeEnabled()Z .../FirebaseRemoteConfigSettings

java - 如何使用 Spring Rest 模板从 Firebase 接收随机生成的 json 值?

java - RecylerView 项目未显示

java - 如何将 double 转换为小数点后两位?

不支持 Android Linkify 电子邮件

android - 任务 generateJsonModelArmDebug 执行失败

Firebase 数据结构 - 保持重复数据最新

android - 安全声明 RecyclerView 对象 : as a field of the activity or as a local variable of the onCreate() method?

android - 单击 AlertDialog 项目列表时在 RecyclerView 布局之间切换