Я использую RecyclerView ('androidx.recyclerview: recyclerview: 1.1.0') и Glide ('com.github.bumptech.glide: glide: 4.10.0').
Я хотел создать список изображений с RecyclerView
. И каждый держатель представления загружает изображение по Glide.
После загрузки всех изображений я хочу прокрутить вниз, вызвав scrollToPosition()
Но в моем случае это не сработало.
Это остается в позиции первого ряда.
Проблема:
Если я использовал override()
метод для Glide, он работает после того, как я его запустил один раз.
Я догадался, что это был кеш.
Но он не работал при первом запуске.
Работает:
И если бы я использовал абсолютная высота для ImageView
, scolling
сработало.
Ниже приведена сводка для успешного сценария.
- wrap_content (ImageView) + override (x, y) ( Glide): работает после попытки
- фиксированная высота (ImageView): работает, но я хочу фиксированную ширину и динамическую c высоту с сохранением правильного соотношения
Для простоты я создал новый упрощенный проект.
Мои коды приведены ниже.
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_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
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_vi ew. 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_width="match_parent"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/imageView"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#FF3636"
android:adjustViewBounds="true"/>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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);
}
}