android - RecyclerView onBindViewHolder 方法增加启动时间?
问题描述
我是 android 应用程序开发的新手,我最近制作了我的第一个应用程序,其中包含一个基本的 tablayout,在我的 MainActivity 中有两个片段。
在我的第二个选项卡中,它仅包含一个 RecyclerView 作为根布局。我所做的是用我自己的数据模型的数组列表填充 RecyclerView。
我的 RecyclerView 有 13 个项目。这些项目的视图是来自https://github.com/florent37/ExpansionPanel的扩展布局,我完全按照他为 RecyclerView 所做的方式进行了操作,并且效果很好。
但是,我的应用程序的启动时间已显着增加到1s++。我发现我的 RecyclerViewAdapter 中的 onBindViewHolder 方法是罪魁祸首。我尝试注释掉onBindViewHolder方法的内容,启动时间减少了一半到600ms,这对我来说还可以。
所以我的问题是如何解决这个问题?我应该以不同的方式绑定我的数据吗?
我不想有一个缓慢的启动时间。我看到了一些关于使用数据绑定 API、在不同的线程和异步上运行的帖子,但我不知道该怎么做。
请帮忙~先谢谢了!
这是我的适配器:
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private ArrayList<DataModel> list;
private final ExpansionLayoutCollection expansionsCollection = new ExpansionLayoutCollection();
MyAdapter(ArrayList<DataModel> list, Context context) {
this.list = list;
this.context = context;
expansionsCollection.openOnlyOne(true);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView == LayoutInflater.from(parent.getContext()).inflate(R.layout.expansion_panel, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
DataModel currentData = list.get(position);
switch (currentData.getType()) {
case DataModel.NO_FORMULA:
holder.titleText.setText(currentData.getTitle());
holder.contentText.setText(currentData.getContent());
holder.formulaView.removeAllViews();
expansionsCollection.add(holder.expansionLayout);
break;
case DataModel.WITH_FORMULA:
View formulaLayout = ((Activity)context).getLayoutInflater().inflate(currentData.getFormulaLayoutId(),null);
holder.titleText.setText(currentData.getTitle());
holder.contentText.setText(currentData.getContent());
holder.formulaView.removeAllViews();
holder.formulaView.addView(formulaLayout);
expansionsCollection.add(holder.expansionLayout);
break;
}
}
@Override
public int getItemCount() {
return list.size();
}
private static class ViewHolder extends RecyclerView.ViewHolder {
TextView titleText, contentText;
ExpansionLayout expansionLayout;
FrameLayout formulaView;
ViewHolder(View itemView) {
super(itemView);
this.titleText = itemView.findViewById(R.id.title_text);
this.contentText = itemView.findViewById(R.id.content_text);
this.expansionLayout = itemView.findViewById(R.id.expansionLayout);
this.formulaView = itemView.findViewById(R.id.formula_view);
}
}
这是我的项目布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="ContentDescription,RtlHardcoded,HardcodedText">
<com.github.florent37.expansionpanel.ExpansionHeader
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
app:expansion_headerIndicator="@id/headerIndicator"
app:expansion_layout="@id/expansionLayout"
app:expansion_toggleOnClick="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:minHeight="50dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:theme="@style/RecyclerViewTheme">
<TextView
android:id="@+id/title_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/headerIndicator"
android:textColor="#000" />
<android.support.v7.widget.AppCompatImageView
android:id="@+id/headerIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="16dp"
android:adjustViewBounds="true"
app:srcCompat="@drawable/ic_expansion_header_indicator_grey_24dp" />
</RelativeLayout>
</com.github.florent37.expansionpanel.ExpansionHeader>
<com.github.florent37.expansionpanel.ExpansionLayout
android:id="@+id/expansionLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:expansion_expanded="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#F5F5F5">
<TextView
android:id="@+id/content_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:textColor="#000" />
<FrameLayout
android:id="@+id/formula_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</com.github.florent37.expansionpanel.ExpansionLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.7dp"
android:background="?android:attr/listDivider" />
</LinearLayout>
这是我的数据模型:
public class DataModel {
public static final int WITH_FORMULA = 0;
public static final int NO_FORMULA = 1;
private String title, content;
private int type, formulaLayoutId;
DataModel(int type, String title, String content) {
this.type = type;
this.title = title;
this.content = content;
}
DataModel(int type, String title, String content, int formulaLayoutId) {
this.type = type;
this.title = title;
this.content = content;
this.formulaLayoutId = formulaLayoutId;
}
public String getTitle() {
return title;
}
public String getContent() {
return content;
}
public int getFormulaLayoutId() {
return formulaLayoutId;
}
public int getType() {
return type;
}
*我创建了 13 个以长标题和长段落为内容的 DataModel 对象,并将它们放在一个数组列表中。当用户单击扩展面板的标题时,扩展布局将展开以显示其内容。
recyclerview 中的 13 个项目中只有 2 个是 WITH_FORMULA 的类型,它必须膨胀 formulaLayout。
解决方案
如果您确定问题的根源onBindViewHolder
是通货膨胀,那么唯一的问题就是通货膨胀。
inflate
是一个非常昂贵的操作,因为它解析 XML 然后创建视图层次结构。不要在onBindViewHolder
. onCreateViewHolder
而是将视图膨胀一次。如果您不想显示它NO_FORMULA
以防万一,只需将其可见性设置为GONE
和以防VISIBLE
万一WITH_FORMULA
。更改可见性是一种更简单的操作。
推荐阅读
- javascript - 我不断收到“未捕获的 ReferenceError:imgArray 未定义”错误
- javascript - 客户更新请求通过 POSTMAN 工作,但不是通过使用 Shopify 私有应用程序的 AJAX
- android - implement the onclick on the search Result using searchview
- sql - 在 SQL Server 中拆分具有不同因素的字符串
- php - 清理 $_POST 和 $_GET 数组输入 OOP
- reactjs - 无法运行 React-Native 入门页面中给出的 AwesomeProject
- java - 设备旋转的 ImageView 可见性问题
- html - 如何关闭盒子类动画
- php - 将数据传递到要发布到 MySQL 数据库的新页面时的未定义索引,但仅用于文件名输入,并且数据不发布到数据库
- php - 如何通过 JSON DECODE 检索括号中的数据