谁能告诉我为什么 recyclerview 在快速滚动时会卡顿(卡顿/滞后)。?

Could anyone tell me why do recyclerview stuttering(janky/laggy) while scrolling fast.?

提问人:ronark 提问时间:11/6/2023 最后编辑:ronark 更新时间:11/6/2023 访问量:67

问:

在这里,我正在从 MediaStore 检索数据并将其填充到 RecyclerView 上。实际问题是,当我滚动 recyclerview 时,它**卡顿,滞后**,同时,即使我不使用 loadArt() 方法。 我定义的 XML 是否有任何问题,或者我需要执行其他操作来优化数据的 RecyclerView 适配器? 这是代码 -> 适配器代码>


public class SongAdapter extends RecyclerView.Adapter<SongAdapter.ViewHolder>
        implements PopupTextProvider {

    List<SongPojo> songPojoList;
    Context context;


    public SongAdapter(){}
    public SongAdapter(Context con, List<SongPojo> list) {
         
            this.context = con;
            this.songPojoList = list;
            this.setHasStableIds(true);
    }

    @NonNull
    @Override
    public SongAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        CustomRowItemBinding customRowItemBinding =
                CustomRowItemBinding.inflate(LayoutInflater.from(parent.getContext()),parent,false);
        return new ViewHolder(customRowItemBinding);
    }

    String TAG = SongAdapter.class.getSimpleName();

    @Override
    public void onBindViewHolder(@NonNull SongAdapter.ViewHolder holder, int position) {
              SongPojo pojo = songPojoList.get(position);

              holder.itemBinding.textSong.setText(pojo.getSong_title());
              holder.itemBinding.textArtist.setText("<unknown>");

             // loadArt(pojo.getArtist_title(), holder.itemBinding.image);

    }

    public void loadArt(String path, ImageView img){

        GlideApp.with(context)
                .load(path)
                .apply(new RequestOptions().override(54))
                .placeholder(R.mipmap.music_note_placeholder)
                .into(img);

    }

    @Override
    public long getItemId(int position){
        return songPojoList.get(position).getId();
    }


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

    @NonNull
    @Override
    public CharSequence getPopupText(@NonNull View view, int position) {
        SongPojo songPojo = songPojoList.get(position);

        if(!TextUtils.isEmpty(songPojo.getSong_title())) {
            return String.valueOf(songPojo.getSong_title().charAt(0));
        }
        return "";
    }

    public static class ViewHolder extends RecyclerView.ViewHolder{
        
        CustomRowItemBinding itemBinding;

        public ViewHolder(@NonNull CustomRowItemBinding binding) {
            super(binding.getRoot());
            this.itemBinding = binding;

            itemBinding.csLy.setOnClickListener(v->{
                
                // Ignore this below code :)
/*

                Toast.makeText(v.getContext(),"You can do it!",
                        Toast.LENGTH_SHORT)
                        .show();

                // Just for testing purpose.!
                Intent perInt = new Intent(v.getContext(), AppBarExp.class);
                v.getContext().startActivity(perInt);
*/

            });

        }
    }
}

custom_row_item > XML 代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:id="@+id/cs_ly">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/image"
        android:layout_width="54dp"
        android:layout_height="54dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="10dp" />

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/text_song"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:maxLines="1"
        android:paddingHorizontal="10dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1"
        android:textColor="?android:attr/textColorPrimary"
        app:layout_constraintStart_toEndOf="@id/image"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed"
        app:layout_constraintEnd_toStartOf="@id/more_option"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp"
        android:layout_marginTop="8dp"
       />

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/text_artist"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:textSize="14sp"
        android:maxLines="1"
        android:paddingHorizontal="10dp"
        android:layout_marginTop="4dp"
        android:textAppearance="@null"
        android:textColor="?android:attr/textColorSecondary"
        app:layout_constraintStart_toEndOf="@id/image"
        app:layout_constraintTop_toBottomOf="@id/text_song"
        app:layout_constraintEnd_toStartOf="@id/more_option"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp"
     />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/more_option"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/baseline_more_vert_24"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:padding="2dp"
        android:layout_marginEnd="10dp" />

</androidx.constraintlayout.widget.ConstraintLayout>


显示>的测试活动

     LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,
                false);

        layoutBinding.recyclerview.setLayoutManager(layoutManager);
        layoutBinding.recyclerview.setHasFixedSize(true);

        viewModel = new ViewModelProvider(this)
                .get(MainAcitvityViewModel.class);

      viewModel.getMediaLiveData(this).observe(this,
                        new Observer<List<SongPojo>>() {
                    @Override
                    public void onChanged(List<SongPojo> songPojos) {
                        songAdapter = new SongAdapter(getApplicationContext(), songPojos);
                        layoutBinding.recyclerview.setAdapter(songAdapter);

                        //Third party fastscrolling api.
                        FastScrollerBuilder fastScrollerBuilder = new FastScrollerBuilder(layoutBinding.recyclerview);
                        fastScrollerBuilder.useMd2Style();
                        fastScrollerBuilder.setPopupStyle(PopupStyles.MD2);  // make your own style for this.
                        fastScrollerBuilder.build();

                    }
                });


只是想知道如何使卷轴流畅而不会出现卡顿或滞后?

活动布局 xml->

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar_container"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:background="@android:color/transparent">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="6dp"
            app:contentScrim="@android:color/transparent"
            app:layout_scrollFlags="scroll|enterAlways">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="6dp"
                app:layout_collapseMode="none">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="10dp"
                    android:text="Music Player"
                    android:textSize="24sp"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

                <ImageView
                    android:id="@+id/search_btn"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="15dp"
                    android:background="?attr/selectableItemBackgroundBorderless"
                    android:clickable="true"
                    android:focusable="true"
                    android:padding="2dp"
                    android:src="@drawable/baseline_search_24"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintRight_toLeftOf="@id/app_settings_btn"
                    app:layout_constraintTop_toTopOf="parent" />


                <ImageView
                    android:id="@+id/app_settings_btn"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="?attr/selectableItemBackgroundBorderless"
                    android:clickable="true"
                    android:focusable="true"
                    android:padding="2dp"
                    android:src="@drawable/baseline_settings_24"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

            </androidx.constraintlayout.widget.ConstraintLayout>

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>


        <androidx.constraintlayout.widget.ConstraintLayout
            app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >

            <HorizontalScrollView
                android:visibility="visible"
                android:id="@+id/chiptab_container"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                android:layout_marginEnd="0dp"

                android:scrollbars="none"
                >


                <com.google.android.material.chip.ChipGroup
                    android:id="@+id/chip_group"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="1dp"
                    android:layout_marginStart="5dp"
                    app:singleSelection="true"
                    style="@null"
                    android:scrollbars="horizontal"
                    >
                    <com.google.android.material.chip.Chip
                        android:id="@+id/for_you_tab"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="For you"
                        app:textStartPadding="15dp"
                        app:textEndPadding="15dp"
                        android:textSize="18sp"
                        app:chipCornerRadius="20dp"
                        style="@null"/>


                    <com.google.android.material.chip.Chip
                        android:id="@+id/song_tab"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Songs"
                        app:textStartPadding="15dp"
                        app:textEndPadding="15dp"
                        android:textSize="18sp"
                        app:chipCornerRadius="20dp"
                        style="@null"
                        />

                    <com.google.android.material.chip.Chip
                        android:id="@+id/album_tab"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Albums"
                        app:textStartPadding="15dp"
                        app:textEndPadding="15dp"
                        android:textSize="18sp"
                        app:chipCornerRadius="20dp"
                        style="@null"
                        />

                    <com.google.android.material.chip.Chip
                        android:id="@+id/artist_tab"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Artists"
                        app:textStartPadding="15dp"
                        app:textEndPadding="15dp"
                        android:textSize="18sp"
                        app:chipCornerRadius="20dp"
                        style="@null"
                        />

                    <com.google.android.material.chip.Chip
                        android:id="@+id/playlist_tab"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Playlist"
                        app:textStartPadding="15dp"
                        app:textEndPadding="15dp"
                        android:textSize="18sp"
                        app:chipCornerRadius="20dp"
                        style="@null"
                        />

                    <com.google.android.material.chip.Chip
                        android:id="@+id/genres_tab"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Genres"
                        app:textStartPadding="15dp"
                        app:textEndPadding="15dp"
                        android:textSize="18sp"
                        app:chipCornerRadius="20dp"
                        style="@null"
                        />

                    <com.google.android.material.chip.Chip
                        android:id="@+id/folders_tab"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Folder"
                        app:textStartPadding="15dp"
                        app:textEndPadding="15dp"
                        android:layout_marginEnd="10dp"
                        android:textSize="18sp"
                        app:chipCornerRadius="20dp"
                        style="@null"
                        />

                </com.google.android.material.chip.ChipGroup>

            </HorizontalScrollView>

            <View
                android:id="@+id/view_divider"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                app:layout_constraintTop_toBottomOf="@id/chiptab_container"
                android:background="@color/chip_bg_color"
                />


            <androidx.recyclerview.widget.RecyclerView
                android:visibility="visible"
                android:id="@+id/recyclerview"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                app:layout_constraintTop_toBottomOf="@id/view_divider"
                app:layout_constraintBottom_toBottomOf="parent"
                android:layout_marginBottom="100dp"
                />


            <include
                android:visibility="gone"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                layout="@layout/home_for_you_fragment_activity_layout"
                app:layout_constraintTop_toBottomOf="@id/view_divider"
                />


        </androidx.constraintlayout.widget.ConstraintLayout>


</androidx.coordinatorlayout.widget.CoordinatorLayout>
java android-recyclerview android-music-player

评论

0赞 Ammar Abdullah 11/6/2023
RecyclerView 的父布局是什么,您也可以发布您的活动 xml 吗?
0赞 ronark 11/6/2023
@AmmarAbdullah,您好,我已经添加了RecyclerView的父布局,您可以检查一下,如果有任何需要改进的地方,请告诉我。
0赞 Harshali 11/6/2023
@ronark 您正在使用第三方快速滚动库并在构建器中传递您的 recyclerView ,它是否对视图执行任何繁重的任务?请在参数中传递后检查有什么用。new FastScrollerBuilder(layoutBinding.recyclerview);RecyclerViewlayoutBinding.recyclerviewFastScrollerBuilder
0赞 ronark 11/6/2023
@Harshali,你好,妈妈,不,它不会在后台执行任何繁重的任务,它只是提供拇指拖动功能,因此我们可以拖动和跳转到 recyclerview 项目的任何位置,我们也可以将此代码放在观察者块之外,它不会影响 recyclerview 的整体功能在性能方面。有什么想法吗?实际问题是什么?
0赞 Harshali 11/7/2023
@ronark我遇到了滞后问题,并通过案例 1 解决了:行项文件高度或宽度应以特定数字定义(例如,100dp、150dp、..) 案例 2:在每行内加载大图像 (ViewHolder) 案例 3:如果在内部使用或其他RecyclerViewRecyclerViewRecyclerViewNestedScrollViewRecyclerView

答: 暂无答案