Análisis del proceso simplificado del Adaptador de RecyclerView

Prefacio

El artículo anterior introdujo una biblioteca para la extensión y encapsulación de RecyclerView para ayudarnos a agregar rápidamente una lista durante el desarrollo y mejorar la eficiencia del mismo. Los estudiantes que no hayan leído este artículo pueden pasar al artículo anterior RecyclerView para encapsular elegantemente el Adaptador después de leer este artículo para obtener todas las listas . Este artículo trata sobre la idea y el proceso de simplificación del adaptador.

antecedentes

En el desarrollo de Android, la lista que más encontramos es la lista. Hay listas simples en una aplicación y también hay listas complejas que contienen muchos tipos de elementos. La mayoría de las páginas de inicio de las aplicaciones son más complicadas. Por ejemplo, la página de inicio de una aplicación social contiene un área de banner, área de publicidad, contenido de texto, contenido de imagen, contenido de video, etc. RecyclerView puede usar ViewType para distinguir diferentes elementos, que también pueden satisfacer las necesidades, pero todavía hay algunos problemas, como: 1. En la interfaz de la lista de elementos con demasiada lógica y complejidad, la cantidad de código en el adaptador es enorme, la lógica es complicada y difícil de mantener en la etapa posterior. 2. Cada vez que se agrega una lista, es necesario agregar un Adaptador y los ladrillos se mueven repetidamente, lo cual es ineficiente. Así que este artículo trata de simplificar nuestro Adaptador a partir de estas dos dimensiones.

Proceso de análisis y realización de ideas

Se han planteado dos cuestiones anteriormente, echemos un vistazo a cómo podemos resolver estas dos cuestiones. En primer lugar, echemos un vistazo a nuestra redacción habitual de una interfaz de lista compleja que contiene varios elementos (por ejemplo, la página principal que contiene banner, publicidad, contenido de texto, contenido de imagen y contenido de video):

public class HomePageAdapter extends RecyclerView.Adapter {
    
    
    public static final int TYPE_BANNER = 0;
    public static final int TYPE_AD = 1;
public static final int TYPE_TEXT = 2;
    public static final int TYPE_IMAGE = 3;
    public static final int TYPE_VIDEO = 4;
    private List<HomePageEntry> mData;

    public void setData(List<HomePageEntry> data) {
        mData = data;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType){
            case TYPE_BANNER:
                return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_banner_layout,null));
            case TYPE_AD:
                return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_ad_item_layout,null));
            case TYPE_TEXT:
                return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_text_item_layout,null));
            case TYPE_IMAGE:
                return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_image_item_layout,null));
            case TYPE_VIDEO:
                return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_video_item_layout,null));
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        int type = getItemViewType(position);
        switch (type){
            case TYPE_BANNER:
                // banner 逻辑处理
                break;
            case TYPE_AD:
                // 广告逻辑处理
                break;
            case TYPE_TEXT:
                // 文本逻辑处理
                break;
            case TYPE_IMAGE:
               //图片逻辑处理
                break;
            case TYPE_VIDEO:
                //视频逻辑处理
                break;
            // ... 此处省去N行代码
        }
    }

    @Override
    public int getItemViewType(int position) {
        if(position == 0){
            return TYPE_BANNER;//banner在开头
        }else {
            return mData.get(position).type;//type 的值为TYPE_AD,TYPE_IMAGE,TYPE_AD,TYPE_VIDEO其中一个
        }

    }

    @Override
    public int getItemCount() {
        return mData == null ? 0:mData.size();
    }



    public static class BannerViewHolder extends RecyclerView.ViewHolder{
    
    

        public BannerViewHolder(View itemView) {
            super(itemView);
            //绑定控件
        }
    }

    public static class VideoViewHolder extends RecyclerView.ViewHolder{
    
    

        public VideoViewHolder(View itemView) {
            super(itemView);
            //绑定控件
        }
    }
    public static class AdViewHolder extends RecyclerView.ViewHolder{
    
    

        public AdViewHolder(View itemView) {
            super(itemView);
            //绑定控件
        }
    }
    public static class TextViewHolder extends RecyclerView.ViewHolder{
    
    

        public TextViewHolder(View itemView) {
            super(itemView);
            //绑定控件
        }
    }
    public static class ImageViewHolder extends RecyclerView.ViewHolder{
    
    

        public ImageViewHolder(View itemView) {
            super(itemView);
            //绑定控件
        }
    }
}

Lo anterior es la forma en que normalmente escribimos una lista de varios elementos y procesamos diferentes elementos de acuerdo con diferentes ViewTypes. Si la lógica es complicada, la cantidad de código para esta clase es muy grande. Si la versión agrega nuevos requisitos de manera iterativa, es problemático modificar el código y difícil de mantener más adelante.

De hecho, se puede ver que la cantidad de código radica en la vinculación de la vista, vinculación de datos y procesamiento lógico de cada elemento, y estas operaciones son operaciones comunes del Elemento. Como son comunes, entonces podemos extraerlas. Por lo tanto, podemos abstraer el elemento en un componente independiente (a este componente lo llamamos celda), que es responsable del enlace de la vista, el enlace de datos y el procesamiento lógico de cada elemento. Ahora podemos poner el código en el adaptador en la celda. El adaptador vincula la vista y vincula los datos para llamar al método de la celda correspondiente.

Echemos un vistazo a Cell. Como componente independiente, Cell tiene las siguientes funciones:
1, enlace de vista
2, enlace de datos
3, liberación de recurso
4, ID independiente (deje que el adaptador distinga qué tipo de celda)

1. Primero, definimos una celda de interfaz de nivel superior, correspondiente a las 4 funciones anteriores, hay 4 métodos


public interface Cell {
    
    
    /**
     * 回收资源
     *
     */
    public void releaseResource();

    /**
     * 获取viewType
     * @return
     */
    public  int getItemType();

    /**
     * 创建ViewHolder
     * @param parent
     * @param viewType
     * @return
     */
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType);

    /**
     * 数据绑定
     * @param holder
     * @param position
     */
    public  void onBindViewHolder(RecyclerView.ViewHolder holder, int position);
}

2. Dado que los datos se pueden vincular, debemos darle una fuente de datos, por lo que definimos una clase base RVBaseCell para guardar una entidad de datos paradigmática

public  abstract class RVBaseCell<T> implements Cell {
    
    

    public RVBaseCell(T t){
        mData = t;
    }
    public T mData;

    @Override
    public void releaseResource() {
        // do nothing
        // 如果有需要回收的资源,子类自己实现
    }
}

3, en vista del enlace del adaptador original, los datos de enlace, las operaciones de procesamiento lógico, en el
ejemplo de celda correspondiente , creamos una celda es Banner, llamada BannerCell. el código se muestra a continuación:


public class BannerCell extends RVBaseCell<HomePageEntry>{
    
    
    public static final int TYPE_BANNER = 0;
    public BannerCell(HomePageEntry homePageEntry) {
        super(homePageEntry);
    }

    @Override
    public int getItemType() {
        return TYPE_BANNER;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_banner_layout,null));
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        //处理banner 逻辑
    }

    public static class BannerViewHolder extends RecyclerView.ViewHolder{
    
    

        public BannerViewHolder(View itemView) {
            super(itemView);
            //绑定控件
        }
    }
}

4. Transformar el Adaptador. Lo que se almacena en el Adaptador ya no son los datos de la entidad, sino una lista de Celdas. El método de devolución de llamada del Adaptador se transforma y el método en la Celda en la posición correspondiente es llamado.
el código se muestra a continuación:

public  class HomePageAdapter<C extends RVBaseCell> extends RecyclerView.Adapter {
    
    
    private List<C> mData;

    public void setData(List<C> data) {
        mData = data;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        for(int i=0;i<getItemCount();i++){
            if(viewType == mData.get(i).getItemType()){
                return mData.get(i).onCreateViewHolder(parent,viewType);
            }
        }

        throw new RuntimeException("wrong viewType");
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    }

    @Override
    public int getItemViewType(int position) {
        return mData.get(position).getItemType();

    }

    @Override
    public int getItemCount() {
        return mData == null ? 0:mData.size();
    }

}

Ahora eche un vistazo al código de este HomePageAdapter y el código de HomePageAdapter escrito anteriormente. Puede reducir un adaptador con miles de líneas de código a solo unas pocas docenas de líneas de código y, lo que es más importante, este adaptador es universal. Todos solo nuestras listas Está bien si necesita un adaptador de este tipo, solo agregue Cell. De esta forma se solucionan los dos problemas mencionados al principio de nuestro artículo.

Podemos usar dos imágenes para comparar. Antes de agregar una lista, escribiríamos un Adaptador:

Escriba la descripción de la imagen aquí

Ahora se ve así:

new_adapter.png

Como se muestra en la figura anterior, solo se necesita un adaptador, al igual que hay muchas ranuras en el adaptador, conectamos cada celda al adaptador, plug and play. Completamente desacoplado.En el futuro, agregando requisitos y reduciendo requisitos, solo es necesario agregar o reducir un tipo de celda, no es necesario mover el código anterior antes, fácil de mantener.
Al final

Lo anterior es el proceso de empaquetado simplificado y el análisis de pensamiento de RecyclerView Adapter.

Supongo que te gusta

Origin blog.csdn.net/hai_jian/article/details/73801088
Recomendado
Clasificación