【问题标题】:How to keep UI unlocked while initializing recyclerview adapter?如何在初始化 recyclerview 适配器时保持 UI 解锁?
【发布时间】:2018-11-17 13:41:01
【问题描述】:

如何在不锁定 UI 的情况下初始化 RecyclerView 适配器? 我要做的就是在创建适配器视图时显示进度条,完成该操作后隐藏进度条并显示完成的 recyclerview 适配器。

问题是当 i .setAdapter() 时,UI 会冻结一小会儿,并且进度条会在那一刻冻结。

我不知道如何解决这个问题,因为视图相关的操作必须在 UI 线程中完成。

有什么想法吗?

代码: 从 db 加载数据:

dataLoader = Observable
                .just(getApplication().getDbHelper())
                .map(this::doInBackground)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(this::onPostExecute);

onPostExecute 方法:

entriesAdapter = new EntriesAdapter(getApplication(), loadedData.entries);
this.loadedData = loadedData;
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
        viewHolder.entries.setHasFixedSize(true);
        viewHolder.entries.setLayoutManager(layoutManager);
        viewHolder.entries.setItemAnimator(new DefaultItemAnimator());
        viewHolder.entries.setAdapter(entriesAdapter);

适配器代码:

public class EntriesAdapter extends RecyclerView.Adapter<EntriesAdapter.ViewHolder> {
    private BudgeterApplication app;
    private List<Expense> entries;
    private CompositeDisposable compositeDisposable;

    public EntriesAdapter(BudgeterApplication app, List<Expense> entries) {
        this.app = app;
        this.entries = entries;
    }

    public void setEntries(List<Expense> entries) {
        this.entries = entries;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new ViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.expense_list_row, viewGroup, false));
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        Expense expense = entries.get(i);

        viewHolder.getSumText().setText(BigDecimalUtils.convertToCurrencyString(expense.getSum()));
        viewHolder.getCommentText().setText(expense.getComment() == null ? "" : expense.getComment());
        viewHolder.getDateText().setText(DateUtils.convertToString(expense.getTimeStamp(), "MM-dd HH:mm"));
    }

    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        compositeDisposable = new CompositeDisposable();
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
            compositeDisposable.dispose();
        }
        super.onDetachedFromRecyclerView(recyclerView);
    }

    @Override
    public int getItemCount() {
        return entries.size();
    }


    @Getter
    class ViewHolder extends RecyclerView.ViewHolder {

        private View parent;
        private TextView sumText;
        private TextView commentText;
        private TextView dateText;

        ViewHolder(@NonNull View itemView) {
            super(itemView);
            this.parent = itemView;
            init();
        }

        private void init() {
            sumText = parent.findViewById(R.id.sum_text);
            commentText = parent.findViewById(R.id.comment_text);
            dateText = parent.findViewById(R.id.date_text);
        }
    }
}

【问题讨论】:

标签: android performance asynchronous android-recyclerview


【解决方案1】:

看起来您在构建 RecycerView 项目时可能进行了太多繁重的处理。

另外,请务必设置回收站视图recyclerView.setHasFixedSize(true)的此属性

如果这没有帮助,我建议在这里查看最简单的示例https://developer.android.com/guide/topics/ui/layout/recyclerview

这可以正常工作,因此您可以将其与您的代码进行比较

【讨论】:

  • 看起来不管recyclerview多么简单,在初始化适配器视图时,UI仍然会冻结一会儿。有什么方法可以在单独的线程中进行初始化,以免动画卡顿?
猜你喜欢
  • 2022-01-14
  • 2022-01-13
  • 2016-12-18
  • 1970-01-01
  • 2020-04-12
  • 2017-08-28
  • 2012-11-25
  • 2020-06-08
  • 2018-02-17
相关资源
最近更新 更多