https://blog.csdn.net/qq_20949825/article/details/52103395
Utilice RecyclerView y Glide para lograr un flujo de cascada de imágenes (para evitar la dislocación)
Recientemente estoy aprendiendo el nuevo control RecyclerView de Android. Siento que este es un control con un alto grado de libertad. Además de las funciones más básicas de ListView y GridView, también puede lograr el efecto de flujo en cascada. Android RecyclerView utiliza un control artístico y totalmente analítico , que explica en detalle cómo usar y personalizar RecyclerView. Este blog trata sobre los problemas que encontré al usar RecyclerView y Glide para implementar la función de cascada.
Primero publique la actividad, código de diseño
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<String> mDatas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
}
private void initData() {
mDatas = new ArrayList<String>();
for (int i = 0 ; i < Images.imageUrls.length ; i++){
String data = Images.imageUrls[i];
mDatas.add(data);
}
}
private void initView() {
recyclerView = (RecyclerView) findViewById(R.id.rv);
//添加布局管理
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(manager);
//设置适配器
recyclerView.setAdapter(new RecycleAdapter(this,mDatas));
//设置item添加和删除的动画
// recyclerView.setItemAnimator();
//设置分隔线
// recyclerView.addItemDecoration(new DividerGridItemDecoration(this));
}
}
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.syf.recyclerview.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
El diseño de la actividad es muy simple, solo hay una vista de reciclaje, el código en actividad también es el código más básico para cargar la vista de reciclaje.
Entonces el código del adaptador
public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.MyViewHolder> {
private List<String> mDatas;
private Context context;
private LayoutInflater inflater;
private SparseArray<Integer> heightArray;
public RecycleAdapter(Context context , List<String> mDatas){
this.context = context;
this.mDatas = mDatas;
this.inflater = LayoutInflater.from(context);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
heightArray = new SparseArray<Integer>();
View itemView = inflater.inflate(R.layout.item_recycle,parent,false);
MyViewHolder viewHolder = new MyViewHolder(itemView);
return viewHolder;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
Glide.with(context)
.load(mDatas.get(position))
.into(holder.iv);
}
@Override
public int getItemCount() {
return mDatas.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
ImageView iv;
public MyViewHolder(View itemView) {
super(itemView);
iv = (ImageView) itemView.findViewById(R.id.iv);
}
}
}
El marco de imagen deslizante se utiliza en el onBindViewHolder del adaptador para cargar imágenes. De esta manera, se realiza una imagen básica de carga de flujo en cascada. Pero la corriente en cascada cargada de esta manera tendrá la imagen dislocada al deslizarse. Para resolver este problema, se requieren los siguientes pasos:
1. Agregue manager.setGapStrategy (StaggeredGridLayoutManager.GAP_HANDLING_NONE) en la actividad; este código puede evitar que el elemento de la vista de reciclaje se pierda durante el proceso de carga. Sin embargo, después de agregar este código, el problema de carga de imágenes de la vista de reciclaje es aún mayor, a veces incluso aparecen grandes espacios en blanco, como se muestra en la siguiente figura:
Maldita sea, ¿por qué no agregas este código? No se preocupe, este código es para evitar la desalineación del elemento y los cambios de posición, pero la altura de la imagen se establece al comienzo de wrap_content, algunas imágenes se cargan rápidamente, la posición ya está ocupada y luego, cuando el dedo del usuario se desliza, algunas imágenes No se ha cargado todavía, pero la interfaz se ha deslizado hacia abajo Estas imágenes no se han cargado, lo que conduce a este resultado. Resolver este problema es realmente simple, siempre que la altura de la imagen se obtenga antes de que se cargue la imagen y se establezca la altura de ImageView, este problema se puede resolver.
2 Obtenga la altura de la imagen en el onBindViewHolder en el adaptador y configúrelo, y el código de marcador de posición es el siguiente
Glide.with(context)
.load(mDatas.get(position))
.asBitmap()
.placeholder(R.mipmap.ic_launcher)
.into(new SimpleTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) {
@Override
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
// Do something with bitmap here.
int height = bitmap.getHeight(); //获取bitmap信息,可赋值给外部变量操作,也可在此时行操作。
bitmap.getWidth();
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) holder.iv.getLayoutParams();
layoutParams.height = height;
holder.iv.setLayoutParams(layoutParams);
}
});
Aquí, se utiliza SimpleTarget en deslizamiento Cuando el recurso está listo, se puede obtener la altura de la imagen y establecer la altura de ImgaeView. Sin embargo, si tiene que volver a adquirir cada vez que desliza, esto consume muchos recursos. Por lo tanto, durante la obtención, almacene el valor de altura de la imagen en SpareArray, de modo que el valor de altura de la imagen almacenada en SpareArray se pueda utilizar la próxima vez que se cargue. Entonces, el código en onBindViewHolder debe escribirse así:
if (heightArray.get(position) == null){
Glide.with(context)
.load(mDatas.get(position))
.asBitmap()
.placeholder(R.mipmap.ic_launcher)
.into(new SimpleTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) {
@Override
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
// Do something with bitmap here.
int height = bitmap.getHeight(); //获取bitmap信息,可赋值给外部变量操作,也可在此时行操作。
bitmap.getWidth();
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) holder.iv.getLayoutParams();
layoutParams.height = height;
holder.iv.setLayoutParams(layoutParams);
heightArray.put(position,height);
}
});
}else {
int height = heightArray.get(position);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) holder.iv.getLayoutParams();
layoutParams.height = height;
holder.iv.setLayoutParams(layoutParams);
}
Glide.with(context)
.load(mDatas.get(position))
.into(holder.iv);
Esto puede resolver el problema de la dislocación de las imágenes en las imágenes de carga deslizante de la vista del reciclador.