【问题标题】:RecyclerView takes time loading Adapter values in a FragmentRecyclerView 需要时间在 Fragment 中加载适配器值
【发布时间】:2020-02-01 22:37:41
【问题描述】:

我有一个带有 RecyclerView 的 Fragment (HealFragment),它的适配器是一个不同的类,它通过 FirestoreRecyclerAdapter 从 Firestore 检索数据,并且运行良好。但是,每当我切换到这个 HealFragment 时,它会有点口吃(减慢速度)将适配器设置为 RecyclerView。发生这种情况是因为我在 onStart() 方法中设置了 RecyclerView 的适配器。

所以我的问题是,当 Fragment 使用 Adapter 类加载 Firestore 数据时,如何避免这种卡顿?

如何仅使用 ProgressBar 打开 Fragment 而不会卡顿,并让应用按照自己的节奏获取 Adapter 数据?

我曾考虑在 HealFragment 类中实现 AsyncTask,但听说 Firestore 已经是异步的了。

您可能在 HealFragment 类的 onStart() 方法中看到我的临时解决方案是在将 Adapter 附加到 RecyclerView 之前添加 0.5 秒延迟(Handler)。但我希望有更完整的方法来解决这个问题。

上下文:

  • 修复片段

    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();
    }
}
  • 修复适配器
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)**
    }

}

【问题讨论】:

    标签: java android android-recyclerview google-cloud-firestore firebaseui


    【解决方案1】:

    不需要 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();
        }
    

    您不需要使用延迟处理程序,这被认为是一种不好的做法,您需要做的是在异步查询中附加一个侦听器,一旦获取数据,您需要隐藏 @987654325 @,更新你的适配器中的数据,并通知数据发生了变化

    【讨论】:

    • “CompleteListener”实际上很有意义,不知道我是怎么忘记的。但是,当我实现您提供的相同代码(使用 QuerySnapshot 而不是 DocumentSnapshot)时,ProgressBar 的可见时间不到一毫秒。然后数据仍然需要时间才能出现在屏幕上,并且片段转换仍然卡顿,除非我使用 Handler 增加几毫秒的延迟。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多