何时/如何在等待从Firebase获取数据库时声明recyclerView适配器

时间:2017-07-10 15:14:19

标签: android firebase firebase-realtime-database

如果有人能帮助我,我将不胜感激。 所以正在发生的是在从Firebase数据库中提取SenderNames数组列表之前声明适配器。那么如何等待从数据库中首先获取SenderNames然后显示它们呢?

标签2代码

public class Tab2 extends Fragment {

private static RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private static RecyclerView recyclerView;
private static ArrayList<String> reminderMessages;
protected static ArrayList<String> senderNames;
String receiverUID;
private DatabaseReference mDatabase;
int i =0;

private Button profile;

//Overriden method onCreateView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    //Returning the layout file after inflating
    //Change R.layout.tab1 in you classes
    View v =inflater.inflate(R.layout.tab2, container, false);
    final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    reminderMessages = new ArrayList<>();

    receiverUID = user.getUid();
    mDatabase = FirebaseDatabase.getInstance().getReference();
    Query query = mDatabase.child("reminders").orderByChild("receiverUID").equalTo(receiverUID);

    //Setting size of recycler view as constant
    recyclerView = (RecyclerView) v.findViewById(R.id.my_recycler_view2);
    recyclerView.setHasFixedSize(true);

    //Setting Linear Layout
    layoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setItemAnimator(new DefaultItemAnimator());

    query.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            senderNames = new ArrayList<>();


            for (DataSnapshot ds : dataSnapshot.getChildren()) {
                //Getting corresponding username of the ReceiverUID
                //Getting senderUID
                String sUID = ds.child("senderUID").getValue(String.class);
                //Getting senders Name
                GetSenderName getName = new GetSenderName();
                getName.GetSenderssName(sUID);

                //Getting message from database
                String message = ds.child("reminderMessage").getValue(String.class);
                //Adding database to ArrayList
                reminderMessages.add(message);

                //Getting corresponding username of the ReceiverUID


                // Log.d("String names", receiverNames.toString());
            }



            adapter = new DataAdapter(reminderMessages,senderNames);
            recyclerView.setAdapter(adapter);

        }


        @Override
        public void onCancelled(DatabaseError databaseError) {
            //Error in Reaching Database
            Toast.makeText(getContext(), "Something went Wrong!", Toast.LENGTH_SHORT).show();
        }


    });
     return v;
    }

GetSenderName类

import static com.example.admin.import2.Tab2.senderNames;




   public class GetSenderName {private FirebaseAuth auth;
   ListView listView;
   private DatabaseReference mDatabase;
   private String senderName;



public void GetSenderssName(String UID){
    mDatabase = FirebaseDatabase.getInstance().getReference().child("users");
    //Running a query to find matching UID
    Query query = mDatabase.orderByKey().equalTo(UID);
    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot2) {

            // Getting user name with matching UID
            for (DataSnapshot users : dataSnapshot2.getChildren()) {
                senderName = users.child("username").getValue(String.class);

                senderNames.add(senderName);
                Log.d("sendername retrieved",senderNames.toString());
            }


        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });




       }
    }

DataAdapter类

public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private ArrayList<String> reminderMessage;
private ArrayList<String> receiverName;

public DataAdapter(ArrayList<String> reminderMessage,ArrayList<String> receiverName) {

    this.reminderMessage = reminderMessage;
    this.receiverName = receiverName;
}

@Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup,int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cards_layout, viewGroup, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(DataAdapter.ViewHolder viewHolder, int i) {

    viewHolder.reminderText.setText(reminderMessage.get(i));
    viewHolder.receiverName.setText(receiverName.get(i));
}

@Override
public int getItemCount() {

    return reminderMessage.size();
}

public class ViewHolder extends RecyclerView.ViewHolder{
    private TextView reminderText;
    private TextView receiverName;
    public ViewHolder(View view) {
        super(view);

        reminderText = (TextView)view.findViewById(R.id.remindertext);
        receiverName = (TextView)view.findViewById(R.id.receiverName);
    }
}
}

2 个答案:

答案 0 :(得分:0)

To avoid problems like populate a list before the databases values are fetched, you should use a FirebaseRecyclerAdapter available in firebaseUI library.

It work in asynchronously so you dont need to do nothing. Just set up the recyclerview, the adapter and the query.

Take a look at the official repository

FirebaseUI

答案 1 :(得分:0)

Instead of sending the data in constructor you can create some setter method to set the data and update the list,

  1. Remove the arguments in Adapter constructor
  2. Initialize the ArrayList while declaring as a global variable.
  3. Create a setter method to set the data,

If you do your Adapter will be like this,

public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
    private ArrayList<String> reminderMessage = new ArrayList<>();
    private ArrayList<String> receiverName = new ArrayList<>();

    public DataAdapter(ArrayList<String> reminderMessage, ArrayList<String> receiverName) {

        this.reminderMessage = reminderMessage;
        this.receiverName = receiverName;
    }

    public void setData(ArrayList<String> reminderMessage, ArrayList<String> receiverName) {
        if(reminderMessage == null || receiverName != null) {
            return;
        }

        this.reminderMessage.clear();
        this.receiverName.clear();

        this.reminderMessage.addAll(reminderMessage);
        this.receiverName.addAll(receiverName);

        notifyDataSetChanged();
    }

    @Override
    public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cards_layout, viewGroup, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(DataAdapter.ViewHolder viewHolder, int i) {

        viewHolder.reminderText.setText(reminderMessage.get(i));
        viewHolder.receiverName.setText(receiverName.get(i));
    }

    @Override
    public int getItemCount() {

        return reminderMessage.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        private TextView reminderText;
        private TextView receiverName;

        public ViewHolder(View view) {
            super(view);

            reminderText = (TextView) view.findViewById(R.id.remindertext);
            receiverName = (TextView) view.findViewById(R.id.receiverName);
        }
    }
}

so from your activity you can call like this, adapter.setData(reminderMessages,senderNames); so that you can create the adapter and set in Recycle View before get the data from server.