Utilice RecyclerView y Glide para lograr un flujo de cascada de imágenes (para evitar la dislocación)

https://blog.csdn.net/qq_20949825/article/details/52103395

https://blog.csdn.net/life90/article/details/78884618?utm_medium=distribute.pc_relevant_t0.none-task-blog-OPENSEARCH-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-ARCH-OPEN 1.control

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:
Escriba la descripción de la imagen aquí

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.

Supongo que te gusta

Origin blog.csdn.net/az44yao/article/details/113112903
Recomendado
Clasificación