首页 > 解决方案 > 设置空适配器-FirestoreRecyclerAdapter

问题描述

E/RecyclerView: No adapter attached; skipping layout在片段内使用 FirestoreRecylerAdapter 时出现错误。在阅读了类似问题的所有答案后,我无法找到解决方案,因为它们中的大多数都是针对 activiy 中的 recylerAdapter 的,即他们有一个 onCreate 方法,可以在其中首先设置他们的适配器。如您所知,在片段中,onCreate 方法中没有视图,因此我在那里找不到我的 recyclerView。一些答案建议设置一个空适配器,然后通知数据更改。我无法在 onCreateView 中设置一个空适配器。这是我的代码:

我的适配器:

package com.example.XX;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;

public class ProfileRecyclerAdapter extends FirestoreRecyclerAdapter<Profile,ProfileRecyclerAdapter.ProfileViewHolder> {


      public ProfileRecyclerAdapter(@NonNull FirestoreRecyclerOptions<Profile> options) {
        super(options);
    }


    @Override
    protected void onBindViewHolder(@NonNull ProfileViewHolder holder, int position, @NonNull Profile profile) {
        holder.Name_textView.setText(profile.getName());
        holder.Sector_textView.setText(profile.getSector());
        holder.Pincode_textView.setText(profile.getPincode());

    }

    @NonNull
    @Override
    public ProfileViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
        View view=layoutInflater.inflate(R.layout.profile_row_item,parent,false);
        return new ProfileViewHolder(view);

    }


    class ProfileViewHolder extends RecyclerView.ViewHolder{

        TextView Name_textView;
        TextView Sector_textView;
        TextView Pincode_textView;

        public ProfileViewHolder(@NonNull View itemView) {
            super(itemView);

            Name_textView=itemView.findViewById(R.id.Name_textView);
            Sector_textView=itemView.findViewById(R.id.Sector_textView);
            Pincode_textView=itemView.findViewById(R.id.Pincode_textView);
        }
    }
}

我希望显示数据的片段:

package com.example.XX;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;

import java.util.List;


public class MainQueryFragment extends Fragment {

    RecyclerView recyclerView;
    ProfileRecyclerAdapter profileRecyclerAdapter;
    TextView yourSector;
    TextView yourPincode;
    FirebaseFirestore db = FirebaseFirestore.getInstance();
    String tuserID = FirebaseAuth.getInstance().getCurrentUser().getUid();
    String customerPincode;
    String customerSector;
    String sectorText;
    String pincodeText;
    String[] testArray;
    String name;
    String pincode;
    String address;
    String mobileNumber;
    String sector;
    String avgDeliveryTime;
    String avgDeliveryTimeUrg;
    Boolean item1;
    Boolean item2;
    Boolean item3;
    Boolean item4;
    Boolean item5;
    Boolean item6;
    Boolean item7;
    Boolean item8;
    Boolean item9;
    Boolean item10;
    String speciality;
    String avgNumOrders;
    String shopType;
    String userID;
    String avgPriceRange;
    String education;
    Button button;


    public MainQueryFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_main_query, container, false);

        yourSector = view.findViewById(R.id.Sector_tv);
        yourPincode = view.findViewById(R.id.Pincode_tv);

        recyclerView = view.findViewById(R.id.recyclerView_Profile);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setAdapter(profileRecyclerAdapter);


        { DocumentReference docRef = db.collection("customerUsers").document(tuserID);
        docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    if (document.exists()) {
                        customerPincode = document.getString("pincode");
                        customerSector = document.getString("sector");
                        sectorText = "Sector : " + customerSector;
                        pincodeText = "Pincode : " + customerPincode;
                        yourSector.setText(sectorText);
                        yourPincode.setText(pincodeText);
                        Log.d("work", "onComplete: " + customerPincode);
                    } else {
                        Log.d("docref", "No such document");
                    }
                } else {
                    Log.d("docref", "get failed with ", task.getException());
                }
            }
        });
    }//doc for sector,pincode loading

        if (getArguments() != null) {
            MainQueryFragmentArgs args = MainQueryFragmentArgs.fromBundle(getArguments());
            testArray = args.getArrayCheckboxData();
        }
        return view;
    }

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

        button=view.findViewById(R.id.startQuery_button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Query query = FirebaseFirestore.getInstance()
                        .collection("tUsers")
                        .whereEqualTo("pincode", customerPincode)
                        .whereEqualTo("sector", customerSector)
                        .whereEqualTo(testArray[0], true)
                        .whereEqualTo(testArray[1], true)
                        .whereEqualTo(testArray[2], true)
                        .whereEqualTo(testArray[3], true);


                FirestoreRecyclerOptions<Profile> options = new FirestoreRecyclerOptions.Builder<Profile>()
                        .setQuery(query,Profile.class)
                        .build();
                profileRecyclerAdapter = new ProfileRecyclerAdapter(options);
                recyclerView.setAdapter(profileRecyclerAdapter);
                profileRecyclerAdapter.startListening();
            }
        });


    }

}

即使我注释掉我的按钮和 onclicklistener 然后运行应用程序,我应该在技术上运行一个空适配器。我仍然遇到同样的错误。请建议我应该做什么,记住我不能使用 onCreate

编辑这是我编辑的代码。现在我得到空指针异常并且我的应用程序崩溃了:

package com.example.XX;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;

import java.util.List;


public class MainQueryFragment extends Fragment {

    RecyclerView recyclerView;
    ProfileRecyclerAdapter profileRecyclerAdapter;
    TextView yourSector;
    TextView yourPincode;
    FirebaseFirestore db = FirebaseFirestore.getInstance();
    String tuserID = FirebaseAuth.getInstance().getCurrentUser().getUid();
    String customerPincode;
    String customerSector;
    String sectorText;
    String pincodeText;
    String[] testArray;
    String name;
    String pincode;
    String address;
    String mobileNumber;
    String sector;
    String avgDeliveryTime;
    String avgDeliveryTimeUrg;
    Boolean item1;
    Boolean item2;
    Boolean item3;
    Boolean item4;
    Boolean item5;
    Boolean item6;
    Boolean item7;
    Boolean item8;
    Boolean item9;
    Boolean item10;
    String speciality;
    String avgNumOrders;
    String shopType;
    String userID;
    String avgPriceRange;
    String education;
    Button button;


    public MainQueryFragment() {
        // Required empty public constructor
    }

     @Override
    public void onStart() {
        super.onStart();
        profileRecyclerAdapter.startListening();
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_main_query, container, false);

        yourSector = view.findViewById(R.id.Sector_tv);
        yourPincode = view.findViewById(R.id.Pincode_tv);


        { DocumentReference docRef = db.collection("customerUsers").document(tuserID);
        docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    if (document.exists()) {
                        customerPincode = document.getString("pincode");
                        customerSector = document.getString("sector");
                        sectorText = "Sector : " + customerSector;
                        pincodeText = "Pincode : " + customerPincode;
                        yourSector.setText(sectorText);
                        yourPincode.setText(pincodeText);
                        Log.d("work", "onComplete: " + customerPincode);
                    } else {
                        Log.d("docref", "No such document");
                    }
                } else {
                    Log.d("docref", "get failed with ", task.getException());
                }
            }
        });
    }//doc for sector,pincode loading

        if (getArguments() != null) {
            MainQueryFragmentArgs args = MainQueryFragmentArgs.fromBundle(getArguments());
            testArray = args.getArrayCheckboxData();
        }
        return view;
    }

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

        button=view.findViewById(R.id.startQuery_button);
         recyclerView = view.findViewById(R.id.recyclerView_Profile);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Query query = FirebaseFirestore.getInstance()
                        .collection("tUsers")
                        .whereEqualTo("pincode", customerPincode)
                        .whereEqualTo("sector", customerSector)
                        .whereEqualTo(testArray[0], true)
                        .whereEqualTo(testArray[1], true)
                        .whereEqualTo(testArray[2], true)
                        .whereEqualTo(testArray[3], true);


                FirestoreRecyclerOptions<Profile> options = new FirestoreRecyclerOptions.Builder<Profile>()
                        .setQuery(query,Profile.class)
                        .build();
                profileRecyclerAdapter = new ProfileRecyclerAdapter(options);
                recyclerView.setAdapter(profileRecyclerAdapter);
                pailorProfileRecyclerAdapter.notifyDataSetChanged();    
                }
        });

    }
    @Override
    public void onStop() {
        super.onStop();
        profileRecyclerAdapter.stopListening();
    }


}


标签: javaandroidfirebaseandroid-recyclerviewgoogle-cloud-firestore

解决方案


当您第一次在 中创建适配器时onCreateView(),您并没有初始化该适配器,而是直接从属性设置适配器:

ProfileRecyclerAdapter profileRecyclerAdapter;
recyclerView.setAdapter(profileRecyclerAdapter);

您需要初始化您的适配器以将该适配器设置为您的 RecyclerView。

其次,你不应该在你的内部有那个异步调用onCreateView(),而是onViewCreated()在你的视图被创建之后用来处理你的异步调用。

然后,您还将在您的适配器中创建适配器实例onViewCreated()

  FirestoreRecyclerOptions<Profile> options = new FirestoreRecyclerOptions.Builder<Profile>()
                        .setQuery(query,Profile.class)
                        .build();
                profileRecyclerAdapter = new ProfileRecyclerAdapter(options);
                recyclerView.setAdapter(profileRecyclerAdapter);
                profileRecyclerAdapter.startListening();

你应该这样做:

profileRecyclerAdapter.startListening();

在你的onStart()profileRecyclerAdapter.stopListening();你的onStop()


推荐阅读