recyclerView 第一次滚动不流畅
recyclerView won't scroll smoothly for first time
我在片段中有一个 recyclerView,这个片段位于 viewpager2 中。
我从服务器读取数据并将它们转换为我的 ModelClass,它们创建一个 ArrayList 并将该数组列表传递给 recyclerView。
这是我的 recyclerView 项目布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/main_icon_background"
android:elevation="5dp"
android:layoutDirection="rtl"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:id="@+id/image"
android:layout_width="120dp"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@color/black" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/vazir_font"
android:textColor="@color/black" />
<TextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:ellipsize="end"
android:maxLines="3"
android:textAppearance="@style/vazir_font"
android:textColor="@color/gray"
android:textSize="13sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="1.5dp"
android:layout_marginStart="20dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="8dp"
android:alpha="0.5"
android:background="@color/gray" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/source"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_weight="0.8"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/vazir_font"
android:textColor="@color/colorPrimaryDark"
android:textSize="13sp" />
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="end"
android:textAppearance="@style/vazir_font"
android:textColor="@color/colorAccent"
android:textSize="13sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
这是我的 recyclerView 适配器:
class NewsRecyclerViewAdapter : RecyclerView.Adapter<NewsRecyclerViewAdapter.ViewHolder>() {
private val items = ArrayList<NewsAdapterModel>()
lateinit var onClick: NewsTutorialClickListener
fun add(list: ArrayList<NewsAdapterModel>) {
items.clear()
items.addAll(list)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view =
LayoutInflater.from(parent.context).inflate(R.layout.news_recycler_model, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.binding(items[position])
}
override fun getItemId(position: Int): Long {
return items[position].id.hashCode().toLong()
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun binding(model: NewsAdapterModel) {
itemView.setOnClickListener {
onClick.onClick(model.id)
}
itemView.title.text = model.title
itemView.description.text = model.description
itemView.date.text = Arrange().persianConverter(model.date)
itemView.source.text = model.source
Glide.with(itemView.context)
.load(model.image)
.placeholder(R.mipmap.logo)
.into(itemView.image)
}
}
}
我在我的片段中使用了这个回收器视图,就像这样:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
adapter.onClick = this
binding.recyclerView.layoutManager = LinearLayoutManager(context)
binding.recyclerView.adapter = adapter
binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.setItemViewCacheSize(20)
scope.launch {
withContext(Dispatchers.Default) {
fetchNews()
}
}
}
我的问题是:当我第一次滚动 recycler view 时它不流畅,似乎有些帧跳了,但是当我到达 recyclerView 的末尾并向上滚动然后向下滚动时它非常平滑并找到了。我该如何解决这个问题?
还要提一下,recyclerView 的项目并不多,大约有 10 项。
删除
recyclerView.setHasFixedSize(true)
实际上它不会造成任何伤害并且确实会提高性能,因为 recyclerView 不会在 onBindViewHolder
内每次都计算 viewHolders 的大小。但是你所有的 TextViews
和 wrap_content
高度肯定会导致将来一些 UI 损坏。
删除
recyclerView.setItemViewCacheSize(20)
此函数强制 RecyclerView
过早膨胀并绑定 20 个额外的 ViewHolders
,以便它可以直接使用它们而无需调用 OncreateViewHolder
和 OnBindViewHolder
。你不应该玩这个,只使用默认值。虽然 20 额外的 viewholders 应该没什么大不了的,但我想也许 RecyclerView
感到困惑,因为你强迫它创建额外的 20在现有 10 之上,而您列出的仅包含 10 项。创建那些阻塞 ui 线程的额外 viewHolder 需要时间,但在创建它们之后似乎很顺利。
您不需要添加这些行
binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.setItemViewCacheSize(20)
请删除这些行
我在片段中有一个 recyclerView,这个片段位于 viewpager2 中。
我从服务器读取数据并将它们转换为我的 ModelClass,它们创建一个 ArrayList 并将该数组列表传递给 recyclerView。 这是我的 recyclerView 项目布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/main_icon_background"
android:elevation="5dp"
android:layoutDirection="rtl"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:id="@+id/image"
android:layout_width="120dp"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@color/black" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/vazir_font"
android:textColor="@color/black" />
<TextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:ellipsize="end"
android:maxLines="3"
android:textAppearance="@style/vazir_font"
android:textColor="@color/gray"
android:textSize="13sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="1.5dp"
android:layout_marginStart="20dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="8dp"
android:alpha="0.5"
android:background="@color/gray" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/source"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_weight="0.8"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/vazir_font"
android:textColor="@color/colorPrimaryDark"
android:textSize="13sp" />
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="end"
android:textAppearance="@style/vazir_font"
android:textColor="@color/colorAccent"
android:textSize="13sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
这是我的 recyclerView 适配器:
class NewsRecyclerViewAdapter : RecyclerView.Adapter<NewsRecyclerViewAdapter.ViewHolder>() {
private val items = ArrayList<NewsAdapterModel>()
lateinit var onClick: NewsTutorialClickListener
fun add(list: ArrayList<NewsAdapterModel>) {
items.clear()
items.addAll(list)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view =
LayoutInflater.from(parent.context).inflate(R.layout.news_recycler_model, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.binding(items[position])
}
override fun getItemId(position: Int): Long {
return items[position].id.hashCode().toLong()
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun binding(model: NewsAdapterModel) {
itemView.setOnClickListener {
onClick.onClick(model.id)
}
itemView.title.text = model.title
itemView.description.text = model.description
itemView.date.text = Arrange().persianConverter(model.date)
itemView.source.text = model.source
Glide.with(itemView.context)
.load(model.image)
.placeholder(R.mipmap.logo)
.into(itemView.image)
}
}
}
我在我的片段中使用了这个回收器视图,就像这样:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
adapter.onClick = this
binding.recyclerView.layoutManager = LinearLayoutManager(context)
binding.recyclerView.adapter = adapter
binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.setItemViewCacheSize(20)
scope.launch {
withContext(Dispatchers.Default) {
fetchNews()
}
}
}
我的问题是:当我第一次滚动 recycler view 时它不流畅,似乎有些帧跳了,但是当我到达 recyclerView 的末尾并向上滚动然后向下滚动时它非常平滑并找到了。我该如何解决这个问题? 还要提一下,recyclerView 的项目并不多,大约有 10 项。
删除
recyclerView.setHasFixedSize(true)
实际上它不会造成任何伤害并且确实会提高性能,因为 recyclerView 不会在 onBindViewHolder
内每次都计算 viewHolders 的大小。但是你所有的 TextViews
和 wrap_content
高度肯定会导致将来一些 UI 损坏。
删除
recyclerView.setItemViewCacheSize(20)
此函数强制 RecyclerView
过早膨胀并绑定 20 个额外的 ViewHolders
,以便它可以直接使用它们而无需调用 OncreateViewHolder
和 OnBindViewHolder
。你不应该玩这个,只使用默认值。虽然 20 额外的 viewholders 应该没什么大不了的,但我想也许 RecyclerView
感到困惑,因为你强迫它创建额外的 20在现有 10 之上,而您列出的仅包含 10 项。创建那些阻塞 ui 线程的额外 viewHolder 需要时间,但在创建它们之后似乎很顺利。
您不需要添加这些行
binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.setItemViewCacheSize(20)
请删除这些行