Firebase + RecyclerView: RecyclerView не отображается при запуске приложения

Я использую класс, предоставленный Android Studio, для активности с вкладками, которая использует вкладки панели действий с ViewPager. Внутри этого действия я пытаюсь инициализировать RecyclerView данными из базы данных Firebase.

Проблема: при первом запуске приложения RecyclerView пуст, как показано ниже.

Первый запуск приложения.

Если я закрою и снова открою приложение из эмулятора, мой RecyclerView будет заполнен, как и должно быть, как показано ниже.

После закрытия и повторного открытия приложения.

Любые идеи относительно того, почему это может происходить? У меня есть теория, но я не смог найти решение. После попытки прочитать FragmentPagerAdapter страницы, у меня сложилось впечатление, что фрагменты должны быть статичными (я не знаю, каковы могут быть последствия этого, поэтому, если кто-нибудь может пролить свет на это, я был бы признателен). При первом запуске приложения оно инициализирует RecyclerView. Затем он добавляет данные из базы данных Firebase, но, поскольку RecyclerView уже инициализирован, он пуст и никогда не обновляется должным образом. Я пытался вызвать методы уведомления... безрезультатно.

Метод StudentFragment onCreateView:

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);
}

Метод onCreate на рабочем столе:

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 устанавливается в другом приложении, которое запускается, как только начинается активность на главном экране. Любая помощь будет оценена.

Редактировать: я копался на странице FirebaseUI GitHub, где, скорее всего, и заключается проблема, и нашел другого пользователя с точно такой же проблемой. Похоже, что onBindViewHolder не вызывается после notifyItemInserted в классе FirebaseRecyclerAdapter. Теперь, чтобы исправить это ...


person kevinivan05    schedule 25.04.2016    source источник
comment
Я пытаюсь сделать то же, что и вы, но не могу заставить это работать, вот моя проблема, объясненная на случай, если у вас есть время взглянуть на нее. Спасибо! stackoverflow.com/questions/38263758/   -  person raphh    schedule 08.07.2016


Ответы (4)


В моем случае это было вызвано mRecyclerView.setHasFixedSize(true);. Если вы закомментируете эту строку кода, список загрузится правильно. Я получил свое решение из этого обсуждения: https://github.com/firebase/FirebaseUI-Android/issues/204

person CodeSlave    schedule 18.01.2017
comment
Спасибо! Это была и моя проблема! - person Anatolii Bivol; 23.01.2017
comment
Отлично, что и моя проблема. - person dsharew; 14.06.2017

Позвольте мне попробовать, как вы говорите в заголовке вопроса,

RecyclerView не отображается при запуске приложения

Итак

Инициализирует Recycler View и Layout Manager.

должен быть объявлен на onStart

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

Надеюсь, поможет!

person Asep Hikmat Fatahillah    schedule 27.04.2016

 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);

** Просто добавьте Recyclerview.AdapterDataObserver() . работал на меня! Надеюсь, поможет :)**

person Shubham Sardar    schedule 17.08.2016

у меня была такая же проблема, проверьте документацию:

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

исправил это, добавив наблюдателя данных:

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);
      }
   }
});
person IslemKms    schedule 25.12.2016