Google 是如何让他们的 Gallery App Recyclerview 滚动拇指和图像加载如此之快的?

问题描述

我想创建一个图库应用。我试图复制一些谷歌的设计,但我的图像加载速度要慢得多,而且我的滚动也不是很流畅。可能是因为我的布局文件,但我不知道如何改进。

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground">

<View
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintDimensionRatio="1:1"/>

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    android:id="@+id/wrapper"
    app:layout_constraintDimensionRatio="1:1">

        <androidx.appcompat.widget.AppCompatimageView
            android:id="@+id/image_item"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintDimensionRatio="1:1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"/>

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/videobg"
            android:layout_marginTop="4dp"
            android:layout_marginEnd="4dp"
            android:padding="5dp"
            android:id="@+id/videooverlay"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <androidx.appcompat.widget.AppCompatimageView
                android:id="@+id/imageView2"
                android:layout_width="0dp"
                android:layout_height="15sp"
                app:layout_constraintDimensionRatio="1:1"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toEndOf="@id/texttime"
                android:layout_marginStart="2dp"
                app:srcCompat="@drawable/play" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="0:05"
                android:textColor="#fff"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                android:id="@+id/texttime"
                android:textSize="10sp" />

        </androidx.constraintlayout.widget.ConstraintLayout>

        <org.kruemelopment.de.gallerie.ui.AnimatedCheckBox
            android:id="@+id/animatedCheckBox"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_gravity="center"
            android:layout_margin="2dp"
            android:background="@android:color/transparent"
            app:border_stroke_width="2dp"
            app:color_checked="?colorPrimary"
            app:color_tick="?colorPrimary"
            app:color_unchecked_stroke="@android:color/white"
            app:layout_constraintDimensionRatio="1:1"
            app:layout_constraintHeight_percent="0.15"
            app:layout_constraintStart_toStartOf="@id/image_item"
            app:layout_constraintTop_toTopOf="@id/image_item"
            app:small_tick="true"
            app:tick_stroke_width="2dp" />

        <org.kruemelopment.de.gallerie.ui.ImageLabelView
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintWidth_percent="0.125"
            android:layout_margin="4dp"
            android:id="@+id/labelcountview"
            app:layout_constraintDimensionRatio="1:1"/>

</androidx.constraintlayout.widget.ConstraintLayout</androidx.constraintlayout.widget.ConstraintLayout>

这是我的适配器:

public class ImageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements SectionTitle,SharedPreferences.OnSharedPreferencechangelistener {
private final Context mContext;
private final List<BaseList> imageList;
private final int width;
private boolean selected=false;
private final List<Boolean> selectList=new ArrayList<>();
private SelectionListener selectionListener;
private boolean showLabel;

public ImageAdapter(Context c,List<BaseList> imageList){
    mContext = c;
    this.imageList = imageList;
    displayMetrics displayMetrics = new displayMetrics();
    ((Activity)(c)).getwindowManager().getDefaultdisplay().getMetrics(displayMetrics);
    width = displayMetrics.widthPixels/3;
    int i=0;
    while (i<imageList.size()){
        selectList.add(false);
        i++;
    }
    SharedPreferences lol = PreferenceManager.getDefaultSharedPreferences(c);
    showLabel=lol.getBoolean("showlabelcount",true);
    lol.registerOnSharedPreferencechangelistener(this);
}

@Override
public String getSectionTitle(int position) {
    while (!(imageList.get(position) instanceof Listemonat)){
        position--;
    }
    return ((Listemonat) imageList.get(position)).getMonat();
}

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key) {
    if (key.equals("showlabelcount")){
        showLabel=sharedPreferences.getBoolean(key,true);
        notifyDataSetChanged();
    }
}

public static class ViewHolderMedia extends RecyclerView.ViewHolder {
    ImageView icon;
    ConstraintLayout video;
    View view;
    AnimatedCheckBox animatedCheckBox;
    ImageLabelView imageLabelView;
    ConstraintLayout wrapper;
    TextView videoduration;

    ViewHolderMedia(View itemView) {
        super(itemView);
        view=itemView;
        icon = itemView.findViewById(R.id.image_item);
        video = itemView.findViewById(R.id.videooverlay);
        animatedCheckBox=itemView.findViewById(R.id.animatedCheckBox);
        imageLabelView=itemView.findViewById(R.id.labelcountview);
        wrapper=itemView.findViewById(R.id.wrapper);
        videoduration=itemView.findViewById(R.id.texttime);
    }
}

public static class ViewHolderLabel extends RecyclerView.ViewHolder {
    TextView label;
    View view;

    ViewHolderLabel(View itemView) {
        super(itemView);
        view=itemView;
        label = itemView.findViewById(R.id.textView);
    }
}


@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType) {
    if (viewType==TYPE_LABEL){
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.monatitem,parent,false);
        ViewHolderLabel viewHolder= new ViewHolderLabel(v);
        viewHolder.setIsRecyclable(true);
        return viewHolder;
    }
    else{
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_item,false);
        ViewHolderMedia viewHolder= new ViewHolderMedia(v);
        viewHolder.setIsRecyclable(true);
        return viewHolder;
    }
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder,int position) {
    BaseList item=imageList.get(position);
    if (item.getType()==TYPE_LABEL){
        ViewHolderLabel viewHolderLabel= (ViewHolderLabel) holder;
        Listemonat item2= (Listemonat) item;
        viewHolderLabel.label.setText(item2.getMonat());
    }
    else {
        ViewHolderMedia viewHolderMedia= (ViewHolderMedia) holder;
        if (item.getType() != TYPE_VIDEO) {
            viewHolderMedia.video.setVisibility(View.GONE);
        } else {
            viewHolderMedia.video.setVisibility(View.VISIBLE);
        }
        if (item.getType() == TYPE_IMAGE) {
            Picasso.get()
                    .load(Uri.withAppendedpath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,String.valueOf(item.getMediaID())))
                    .centerCrop()
                    .fit()
                    .into(viewHolderMedia.icon);
        }
        else if (item.getType() == TYPE_VIDEO) {
            Picasso.get()
                    .load(Uri.withAppendedpath(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,String.valueOf(item.getMediaID())))
                    .centerCrop()
                    .fit()
                    .into(viewHolderMedia.icon);
            ListVideo item2=(ListVideo) item;
            viewHolderMedia.videoduration.setText(item2.getDuration());
        }
        viewHolderMedia.view.setonLongClickListener(v -> {
            if (!selected){
                selected=true;
                viewHolderMedia.animatedCheckBox.setChecked(true,true);
                selectList.set(position,true);
                notifyDataSetChanged();
                selectionListener.startSelection();
            }
            return false;
        });
        viewHolderMedia.view.setonClickListener(v -> {
            if (selected){
                boolean val=selectList.get(position);
                viewHolderMedia.animatedCheckBox.setChecked(!val,!val);
                if (!selectList.contains(true)){
                    resetSelected();
                }
            }
            else{
                Intent intent;
                if (item.getType()==TYPE_IMAGE) {
                    intent = new Intent(mContext,ShowImage.class);
                    intent.putExtra("imageid",item.getMediaID());
                }
                else{
                    intent = new Intent(mContext,ShowVideo.class);
                    intent.putExtra("videoid",item.getMediaID());
                }
                mContext.startActivity(intent);
            }
        });
        if (selected){
            viewHolderMedia.wrapper.getLayoutParams().width= (int) (width*0.9);
            viewHolderMedia.animatedCheckBox.setVisibility(View.VISIBLE);
            viewHolderMedia.animatedCheckBox.setChecked(selectList.get(position),false);
        }
        else{
            viewHolderMedia.wrapper.getLayoutParams().width= 0;
            viewHolderMedia.animatedCheckBox.setVisibility(View.GONE);
        }
        if (showLabel){
            viewHolderMedia.imageLabelView.setVisibility(View.VISIBLE);
            viewHolderMedia.imageLabelView.setLabelcount(item.getKeywords().size());
        }
        else viewHolderMedia.imageLabelView.setVisibility(View.GONE);
    }
}

@Override
public long getItemId(int position)
{
    return imageList.get(position).getMediaID();
}

@Override
public int getItemCount()
{
    return imageList.size();
}
@Override
public int getItemViewType(int position) {
    return imageList.get(position).getType();
}

public boolean resetSelected() {
    if (!selected) return false;
    int i = 0;
    while (i < selectList.size()) {
        selectList.set(i,false);
        i++;
    }
    selected=false;
    notifyDataSetChanged();
    selectionListener.endSelection();
    return true;
}

public void setSelectionListener(SelectionListener selectionListener) {
    this.selectionListener = selectionListener;
}

@Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
    super.onViewRecycled(holder);
    if (holder instanceof ViewHolderMedia){
        ((ViewHolderMedia) holder).icon.setimageResource(0);
    }
}}

也许你可以帮助我或找到导致它变慢的东西。 我的两个自定义视图速度非常快,我很确定它们不是问题。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)