Firebase+RecyclerView: RecyclerView not displaying on application start

百般思念 提交于 2019-12-06 09:26:09

问题


I'm using the Android Studio provided class for a tabbed activity that uses Action Bar Tabs with ViewPager. Inside this activity, I'm trying to initialize a RecyclerView with data from a Firebase database.

Problem: On the app's first run, the RecyclerView is empty as shown below.

If I close and reopen the application from within the emulator, my RecyclerView gets populated as it should, as shown below.

Any ideas as to why this might be happening? I have a theory but I haven't been able to find a solution. After trying to read the FragmentPagerAdapter page, I got the impression that the fragments must be static (I don't know what the implications of this might be, so if anyone can shed some light on this it would be appreciated). On the app's first run, it initializes the RecyclerView. It then adds the data from the Firebase database but since the RecyclerView has already been initialized it is empty and is never properly updated. I tried calling the notify... methods to no avail.

StudentFragment's onCreateView method:

private View view;
private Context c;
private RecyclerView mRecyclerView;
private LinearLayoutManager manager;
private Firebase mFirebaseRef;
private FirebaseRecyclerAdapter<Student, ViewHolder> firebaseRecyclerAdapter;


public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment_students, container, false);
    mFirebaseRef = new Firebase("<your Firebase link here>");
    c = getContext();

    //Initializes Recycler View and Layout Manager.
    mRecyclerView = (RecyclerView) view.findViewById(R.id.studentRecyclerView);
    manager = new LinearLayoutManager(c);
    mRecyclerView.setHasFixedSize(true);
    firebaseRecyclerAdapter =
            new FirebaseRecyclerAdapter<Student, ViewHolder>(
                    Student.class,
                    R.layout.single_student_recycler,
                    ViewHolder.class,
                    mFirebaseRef
            ) {
                @Override
                protected void populateViewHolder(ViewHolder viewHolder, Student student, int i) {
                    viewHolder.vFirst.setText(student.getFirst());
                    viewHolder.vLast.setText(student.getLast());
                    viewHolder.vDue.setText(Double.toString(student.getCurrentlyDue()));
                    viewHolder.vRadio.setButtonTintList(ColorStateList.valueOf(Color.parseColor(student.getColor())));
                    Log.d(TAG, "populateViewHolder called");
                }
            };

    mRecyclerView.setAdapter(firebaseRecyclerAdapter);
    mRecyclerView.setLayoutManager(manager);


    return view;
}

ViewHolder:

public static class ViewHolder extends RecyclerView.ViewHolder {
    public final TextView vFirst;
    public final TextView vLast;
    public final TextView vDue;
    public final RadioButton vRadio;

    public ViewHolder(View itemView) {
        super(itemView);
        vFirst = (TextView) itemView.findViewById(R.id.recycler_main_text);
        vLast = (TextView) itemView.findViewById(R.id.recycler_sub_text);
        vRadio = (RadioButton) itemView.findViewById(R.id.recycler_radio_button);
        vDue = (TextView) itemView.findViewById(R.id.recycler_due_text);
}

Homescreen's onCreate method:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_homescreen);

    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(mViewPager);

}

Firebase context is set on another application that starts as soon as the Homescreen activity starts. Any help will be appreciated.

Edit: I was digging through the FirebaseUI GitHub page, which is where the problem most likely lies, and found another user with the exact same problem. It seems that onBindViewHolder isn't called after notifyItemInserted in the FirebaseRecyclerAdapter class. Now to fix it...


回答1:


In my case this was caused by mRecyclerView.setHasFixedSize(true); If you comment out this line of code the list loads properly. I got my solution from this discussion: https://github.com/firebase/FirebaseUI-Android/issues/204




回答2:


Let me try, as you say on the question title,

RecyclerView not displaying on application start

so, the

Initializes Recycler View and Layout Manager.

should be declared on the onStart

@Override
   public void onStart() {
       super.onStart();
       mFirebaseRef = new Firebase("<your Firebase link here>");
       firebaseRecyclerAdapter = ...
       //and so on

Hope it helps!




回答3:


 firebaseRecyclerAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            super.onItemRangeInserted(positionStart, itemCount);
            int friendlyMessageCount = firebaseRecyclerAdapter.getItemCount();
            int lastVisiblePosition =
                    linearLayoutManager.findLastCompletelyVisibleItemPosition();
            // If the recycler view is initially being loaded or the
            // user is at the bottom of the list, scroll to the bottom
            // of the list to show the newly added message.
            if (lastVisiblePosition == -1 ||
                    (positionStart >= (friendlyMessageCount - 1) &&
                            lastVisiblePosition == (positionStart - 1))) {
                linearLayoutManager.scrollToPosition(positionStart);
            }
        }
    });
    recyclerListIdeas.setAdapter(firebaseRecyclerAdapter);

** Just add Recyclerview.AdapterDataObserver() . worked for me ! hope it helps :)**




回答4:


i had the same issue, check the documentation:

https://codelabs.developers.google.com/codelabs/firebase-android/#6

fixed it by adding a data observer:

mFirebaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
   @Override
   public void onItemRangeInserted(int positionStart, int itemCount) {
   super.onItemRangeInserted(positionStart, itemCount);
   int friendlyMessageCount = mFirebaseAdapter.getItemCount();
   int lastVisiblePosition =
          mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
   // If the recycler view is initially being loaded or the 
   // user is at the bottom of the list, scroll to the bottom 
   // of the list to show the newly added message.
   if (lastVisiblePosition == -1 ||
           (positionStart >= (friendlyMessageCount - 1) &&
                   lastVisiblePosition == (positionStart - 1))) {
       mMessageRecyclerView.scrollToPosition(positionStart);
      }
   }
});


来源:https://stackoverflow.com/questions/36850105/firebaserecyclerview-recyclerview-not-displaying-on-application-start

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!