RecyclerView требует времени для загрузки значений адаптера во фрагмент - PullRequest
0 голосов
/ 02 февраля 2020

У меня есть фрагмент (HealFragment) с RecyclerView, адаптер которого представляет собой другой класс, извлекающий данные из Firestore благодаря FirestoreRecyclerAdapter, и он работает хорошо. Но всякий раз, когда я переключаюсь на этот HealFragment, он немного заикается (замедляется), пытаясь установить адаптер на RecyclerView . Это происходит потому, что я установил адаптер RecyclerView в методе onStart () .

Итак, мой вопрос: как избежать этого заикания, когда фрагмент загружает Firestore? данные с классом Adapter?

или

Как открыть фрагмент без заиканий только с помощью ProgressBar и позволить приложению получать данные адаптера в своем собственном темпе?

Я думал о реализации AsyncTask для класса HealFragment, но слышал, что Firestore уже асинхронен.

Мое временное решение, как вы можете видеть в методе onStart () класса HealFragment добавляет задержку 0,5 секунды (обработчик) перед подключением адаптера к RecyclerView. Но я был бы признателен за более полный подход к этому.

Контекст:

  • HealFragment

    public class HealFragment extends Fragment {
      private View mView;
      private ProgressBar heFrProgressBar;
      private RecyclerView heFrRecyclerView;

      private HealAdapter healAdapter;

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

        initializeViews();

        return mView;
    }

    //<--- Method to initialize and assign the views | Called in: onCreateView() --->
    private void initializeViews() {

        //Loading Firestore Data Process
        final String mCurrentUser = mAuth.getCurrentUser().getUid();
        Query query = db.collection("User").document(currentUser).collection("Heals").orderBy("healColor");
        FirestoreRecyclerOptions options = new FirestoreRecyclerOptions.Builder<NewHeal>()
                .setQuery(query, NewHeal.class)
                .build();

        healAdapter = new HealAdapter(options);
        heFrRecyclerView.setHasFixedSize(true);
        heFrRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        heFrRecyclerView.setAdapter(healAdapter);

    }

    @Override
    public void onStart() {
        super.onStart();

        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            public void run() {
                //** Actions to do after 0.5 second **
                healAdapter.startListening();
                heFrProgressBar.setVisibility(View.INVISIBLE);
            }
        }, 500);
    }

    @Override
    public void onStop() {
        super.onStop();

        healAdapter.stopListening();
    }
}
  • HealAdapter
public class HealAdapter extends FirestoreRecyclerAdapter<NewHeal, HealAdapter.HealHolder> {

    public HealAdapter(@NonNull FirestoreRecyclerOptions<NewHeal> options) {
        super(options);
    }

    @Override
    protected void onBindViewHolder(@NonNull final HealHolder holder, final int position, @NonNull final NewHeal model) {
        holder.setTaskTitle(model.getTaskTitle());
        //**Several setters like the one above**

    }

    @NonNull
    @Override
    public HealHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_heal, parent, false);
        return new HealHolder(v);
    }

    class HealHolder extends RecyclerView.ViewHolder {

        //**Declaring Variables**

        HealHolder(@NonNull View itemView) {
            super(itemView);
            this.mView = itemView;

            //**initializingViews + settingOnClickListeners + loadingSomeMethods**
        }

        private void setTaskTitle(String xTitle) {
            singleHealTitleText.setText(xTitle);
        }

        //**Several setter methods more like the one above(setTaskTitle)**
    }

}

1 Ответ

3 голосов
/ 02 февраля 2020

Нет необходимости в AsyncTask, он устарел, и, как вы сказали, Firebase является асинхронным.

Что вам нужно сделать, это создать интерфейс, который будет уведомлять вас о процессе извлечения, а затем отображать progressBar пока у вас нет данных для отображения.

вы можете присоединить слушателя к запросу, чтобы знать, когда он завершится, и показать progressBar перед извлечением данных.

Вы можете прикрепить слушатель вашего объекта запроса и после получения данных вы можете скрыть progressBar

query.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
         // data has been fetched, hide progress and update adapter data
          heFrProgressBar.setVisibility(View.GONE);
         // set the new data to the adapter
         healAdapter.notifyDataSetChanged();
    }
});





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

Вам не нужно использовать обработчик с задержкой, что считается плохой практикой, что вам нужно Для этого нужно подключить слушатель к вашему асинхронному запросу. После того, как данные получены, вам нужно скрыть progressBar, обновить данные в адаптере и уведомить, что данные изменились

...