我一起使用 Glide 和 RecyclerView 但它没有按我的意愿滚动

Posted

技术标签:

【中文标题】我一起使用 Glide 和 RecyclerView 但它没有按我的意愿滚动【英文标题】:I use Glide and RecyclerView together but it doesn't scroll as I want 【发布时间】:2020-06-15 10:48:36 【问题描述】:

我正在使用 RecyclerView ('androidx.recyclerview:recyclerview:1.1.0') 和 Glide('com.github.bumptech.glide:glide:4.10.0')。

我想用RecyclerView 创建图像列表。 每个视图持有者通过 Glide 加载图像。

加载所有图像后,我想通过调用scrollToPosition()滚动到底部 但就我而言,它不起作用。 它停留在第一行的位置。

问题:

如果我对 Glide 使用 override() 方法,我运行一次后它就可以工作。 我猜是缓存。 但它在第一次发布时不起作用。

工作:

如果我对ImageView 使用绝对高度,scolling 会起作用。

以下是成功场景的总结。

    wrap_content(ImageView) + override(x,y)(Glide) : 试一次就可以了 固定高度(ImageView):它可以工作,但我想要固定宽度和动态高度并保持正确的比例

为了方便提问,我创建了一个新的简化项目。

我的代码如下。

activity_main.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_
        android:layout_
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

my_image_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_
    android:layout_
    >
    <ImageView
        android:id="@+id/imageView"
        android:layout_
        android:layout_
        android:layout_gravity="center"
        android:background="#FF3636"
        android:adjustViewBounds="true"/>
    <TextView
        android:id="@+id/textView"
        android:layout_
        android:layout_
        android:layout_gravity="center"
        android:gravity="center"
        android:text="text"
        android:textSize="24dp"
        />
</LinearLayout>

MyAppGlideModule.java

import android.content.Context;

import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;
import com.firebase.ui.storage.images.FirebaseImageLoader;
import com.google.firebase.storage.StorageReference;
import java.io.InputStream;

@GlideModule
public class MyAppGlideModule extends AppGlideModule 
    @Override
    public void registerComponents(Context context, Glide glide, Registry registry) 
        // Register FirebaseImageLoader to handle StorageReference
        registry.append(StorageReference.class, InputStream.class,
                new FirebaseImageLoader.Factory());
    

MyAdapter.java

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> 
    private String[] mDataset;
    private Context mContext;

    public static class MyViewHolder extends RecyclerView.ViewHolder 
        public ImageView imageView;
        public TextView textView;
        public MyViewHolder(View v) 
            super(v);
            imageView = v.findViewById(R.id.imageView);
            textView = v.findViewById(R.id.textView);
        
    

    public MyAdapter(String[] myDataset) 
        mDataset = myDataset;
    

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                     int viewType) 
        // create a new view
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.my_image_view, parent, false);
        MyViewHolder vh = new MyViewHolder(v);
        mContext = parent.getContext();
        return vh;
    

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(final MyViewHolder holder, int position) 
        holder.textView.setText(mDataset[position]);

        StorageReference mStorageRef;
        mStorageRef = FirebaseStorage.getInstance().getReference();

        StorageReference imageRef = mStorageRef.child("images/" + mDataset[position] +".jpg");

        GlideApp.with(mContext)
                .load(imageRef)
                .into(holder.imageView);

    

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() 
        return mDataset.length;
    

MainActivity.java

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.view.ViewGroup;


public class MainActivity extends AppCompatActivity 
    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager layoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = findViewById(R.id.my_recycler_view);

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        recyclerView.setHasFixedSize(true);

        // use a linear layout manager
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        String[] myDataset = "1","2","3","4","5","6","7";

        // specify an adapter (see also next example)
        mAdapter = new MyAdapter(myDataset);
        recyclerView.setAdapter(mAdapter);

        ViewGroup.LayoutParams layoutParams = recyclerView.getLayoutParams();

        recyclerView.scrollToPosition(myDataset.length - 1);
    

【问题讨论】:

【参考方案1】:

尝试将layout_height="0dp" 放入您的布局文件中

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:layout_
    android:layout_
    android:text="Hello World!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

【讨论】:

以上是关于我一起使用 Glide 和 RecyclerView 但它没有按我的意愿滚动的主要内容,如果未能解决你的问题,请参考以下文章

一起Talk Android吧(第四百回:Glide的基本用法)

一起Talk Android吧(第四百一十七回:解决Glide不能加载网络图片的方法)

使用 Glide 库设置完成图像加载后进度条的可见性

深入解读GLIDE/PITI代码

Glide使用和图片变形问题

Glide使用和图片变形问题