RecyclerView慢速滚动性能和滚动时的滞后/暂停



我使用recyclerview来显示项目,项目大小可以是0-500。

但它的滚动性能非常慢,有时会滞后/暂停视图1~2秒。我想在recyclerView中有一个流畅的滚动体验。

即使我从我用Glide加载的卡片视图布局中删除了图像,它对性能也没有影响。

fragment_home.xml

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="@+id/layoutGames">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerViewGamesToday"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:scrollbarThumbVertical="@android:color/darker_gray"
android:scrollbarSize="5dp"/>
</LinearLayout>

我的卡片视图布局文件

<?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">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content">

<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="35dp">

<ImageView
android:id="@+id/imageTeamLogo"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/transparent" />
<TextView
android:id="@+id/textViewHomeTeam"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_centerInParent="false"
android:layout_centerVertical="true"
android:layout_marginEnd="2dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginStart="2dp"
android:gravity="right"
android:text="TextView"
android:textColor="@color/colorTeamNameListing"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imageViewTeamLogo"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@+id/imageTeamLogo"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageViewTeamLogo"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerInParent="false"
android:layout_centerVertical="true"
android:layout_marginEnd="2dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginStart="2dp"
android:padding="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/textViewMatchStatus"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textViewHomeTeam"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textViewScore"
android:layout_width="0dp"
android:layout_height="15dp"
android:layout_centerInParent="false"
android:layout_marginTop="2dp"
android:gravity="center_vertical|center"
android:text="3-1"
android:textColor="@color/colorScoreListing"
android:textSize="13sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@+id/textViewMatchStatus"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="@+id/textViewMatchStatus"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textViewMatchStatus"
android:layout_width="70dp"
android:layout_height="15dp"
android:layout_below="@+id/textViewStatus"
android:layout_centerInParent="false"
android:layout_marginBottom="2dp"
android:gravity="center_vertical|center"
android:text="Not Started"
android:textColor="@color/colorMatchStatus"
android:textSize="10sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewScore" />
<ImageView
android:id="@+id/imageViewAwayTeamLogo"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerInParent="false"
android:layout_centerVertical="true"
android:layout_marginEnd="2dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginStart="2dp"
android:padding="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/textViewAwayTeam"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textViewMatchStatus"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textViewAwayTeam"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="2dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginStart="2dp"
android:gravity="left"
android:text="TextView"
android:textColor="@color/colorTeamNameListing"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imageViewFav"
app:layout_constraintStart_toEndOf="@+id/imageViewAwayTeamLogo"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageViewFav"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/star" />
</android.support.constraint.ConstraintLayout>
<View
android:layout_width="match_parent"
android:background="#efefef"
android:layout_height="1dp" />
</android.support.v7.widget.CardView>
</LinearLayout>

onBindViewHolder方法

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
final GamesToday games = gamesTodayList.get(position);
switch (holder.getItemViewType()) {
case gamesOnlyRows:
final GamesTodayViewHolder gamesTodayViewHolder = (GamesTodayViewHolder) holder;
Glide.with(mCtx)
.load(games.getHomeTeamLogo())
.apply(options)
.into(gamesTodayViewHolder.imageViewHomeTeamLogo);
Glide.with(mCtx)
.load(games.getAwayTeamLogo())
.apply(options)
.into(gamesTodayViewHolder.imageViewAwayTeamLogo);
gamesTodayViewHolder.textViewHomeTeam.setText(games.getHomeName());
if (games.getHomeScore().equals("null")) {
gamesTodayViewHolder.textViewScore.setText(games.getDate());
} else {
gamesTodayViewHolder.textViewScore.setText(games.getHomeScore() + " - " + games.getAwayScore());
}
gamesTodayViewHolder.imageViewEmptyCircle.setImageResource(R.drawable.transparent);
if (games.getStatus().equals("CLOSED")) {
gamesTodayViewHolder.imageViewEmptyCircle.setImageResource(R.drawable.ft);
}
if (games.getStatus().equals("ACTIVE")) {
gamesTodayViewHolder.imageViewEmptyCircle.setImageResource(R.drawable.active_icon);
}
switch (games.getStatus()) {
case "CLOSED":
gamesTodayViewHolder.textViewMatchStatus.setText("Finished");
break;
case "FINISHED_CONFIRMED_1":
gamesTodayViewHolder.textViewMatchStatus.setText("Finished");
break;
case "FINISHED_CONFIRMED_2":
gamesTodayViewHolder.textViewMatchStatus.setText("Finished");
break;
case "NOT_STARTED":
gamesTodayViewHolder.textViewMatchStatus.setText("Not Started");
break;
case "ACTIVE":
gamesTodayViewHolder.textViewMatchStatus.setText("Active");
break;
case "CANCELLED":
gamesTodayViewHolder.textViewMatchStatus.setText("Cancelled");
break;
case "POSTPONED_UNDECIDED":
gamesTodayViewHolder.textViewMatchStatus.setText("Postponed");
break;
default:
gamesTodayViewHolder.textViewMatchStatus.setText(games.getStatus());
}
gamesTodayViewHolder.textViewAwayTeam.setText(games.getAwayName());
gamesTodayViewHolder.imageViewFav.setImageResource(R.drawable.star);
if (checkFavoriteItem(games.getId())) {
gamesTodayViewHolder.imageViewFav.setImageResource(R.drawable.fav);
}
gamesTodayViewHolder.imageViewFav.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (checkFavoriteItem(games.getId())) {
gamesTodayViewHolder.imageViewFav.setImageResource(R.drawable.star);
sharedPreference.removeFavorite(mCtx, games.getId());
} else {
gamesTodayViewHolder.imageViewFav.setImageResource(R.drawable.fav);
sharedPreference.addFavorite(mCtx, games.getId());
}
}
});
break;
case NotGamesOnlyRows:
final GamesTodayWithLeagueViewHolder gamesTodayWithLeagueViewHolder = (GamesTodayWithLeagueViewHolder) holder;
gamesTodayWithLeagueViewHolder.imageViewFavLeague.setImageResource(R.drawable.transparent);
gamesTodayWithLeagueViewHolder.imageViewFavLeague.setImageResource(R.drawable.star);
if (checkFavoriteLeagueItem(games.getLeagueId())) {
gamesTodayWithLeagueViewHolder.imageViewFavLeague.setImageResource(R.drawable.fav);
} else {
gamesTodayWithLeagueViewHolder.imageViewFavLeague.setImageResource(R.drawable.transparent);
gamesTodayWithLeagueViewHolder.imageViewFavLeague.setImageResource(R.drawable.star);
}
gamesTodayWithLeagueViewHolder.imageViewFavLeague.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (checkFavoriteLeagueItem(games.getLeagueId())) {
gamesTodayWithLeagueViewHolder.imageViewFavLeague.setImageResource(R.drawable.star);
sharedPreference.removeFavoriteLeagues(mCtx, games.getLeagueId());
} else {
gamesTodayWithLeagueViewHolder.imageViewFavLeague.setImageResource(R.drawable.fav);
sharedPreference.addFavoriteLeagues(mCtx, games.getLeagueId());
}
}
});
gamesTodayWithLeagueViewHolder.textViewLeagueName.setText(games.getLeague());
Glide.with(mCtx)
.load(games.getCountryId())
.into(gamesTodayWithLeagueViewHolder.imageViewCountryFlag);
break;
default:
}
}

它将按需加载为我工作的图像

@Override
public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
super.onViewAttachedToWindow(holder);
Glide.with(context)
.load(URL)
.into(holder.imageView);
}

使用这些解决方案来平滑滚动

a) recyclerView.setHasFixedSize(true);
b) recyclerView.setItemViewCacheSize(20);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);

c( 在onBindView()中它将提供内存管理缓存,以减少图像加载时间

Glide.with(mCtx).load(games.getAwayTeamLogo()).
.diskCacheStrategy(DiskCacheStrategy.ALL)
.apply(options)
.into(gamesTodayViewHolder.imageViewAwayTeamLogo);

不要使用ConstraintLayout,使用LinearLayout和/或RelativeLayout

试试看性能的变化。

我认为bindViewHolder中的逻辑使其速度变慢,因为在滚动时,会为即将显示的每个项目调用bindViewHolder。

此外,您可以合并的逻辑

if (games.getStatus().equals("CLOSED")) {
gamesTodayViewHolder.imageViewEmptyCircle.setImageResource(R.drawable.ft);
}
if (games.getStatus().equals("ACTIVE")) {
gamesTodayViewHolder.imageViewEmptyCircle.setImageResource(R.drawable.active_icon);
}

下一个开关箱。。。

另外,不要在bindview中设置click监听器,这不好。。。您可以为该持有者类别设置

最新更新