5

I have implemented a recyclerview with multiple view types , and i want to add DiffUtil . I managed to do so for one type but when i try to support multiple view types i can't

So my question is : does DiffUtil supports multiple view types and is there a good tutorial for java implementation

My Adapter


public class PostsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {


    private final int VIEW_TYPE_ITEM = 0;
    private final int VIEW_TYPE_AD = 1;
    private final int VIEW_TYPE_CATEGORIES = 2;
    private final int VIEW_TYPE_NULL = 99;

    private Context context;
    private List<Object> postList;

    public PostsAdapter() {
    }

    /*public PostsAdapter() {
        super(Post.DIFF_CALLBACK);
    }*/

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();

        switch (viewType){
            case VIEW_TYPE_ITEM:
                View viewItem = LayoutInflater.from(context).inflate(R.layout.item_post,
                        parent, false);
                return new ItemViewHolder(viewItem);

            case VIEW_TYPE_AD:
                View unifiedNativeLayoutView = LayoutInflater.from(context).inflate(R.layout.item_ads,
                        parent, false);
                return new AdsViewHolder(unifiedNativeLayoutView);

            case VIEW_TYPE_CATEGORIES:
                View viewCategories = LayoutInflater.from(context).inflate(R.layout.item_categories,
                        parent, false);
                return new HorizontalItemViewHolder(viewCategories);
            default:
                View viewLoading = LayoutInflater.from(context).inflate(R.layout.item_loading,
                        parent, false);
                return new LoadingViewHolder(viewLoading);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        int viewType = getItemViewType(position);

        switch (viewType){
            case VIEW_TYPE_ITEM:
                populateItemRows((ItemViewHolder) holder, position);
                break;
            case VIEW_TYPE_AD:
                populateNativeAdModule((AdsViewHolder) holder, position);
                break;
            case VIEW_TYPE_CATEGORIES:
                populateHorizontalItems((HorizontalItemViewHolder) holder, position);

            default:
                showLoadingView();
        }
    }

    @Override
    public int getItemViewType(int position) {
        Object recyclerViewItem = postList.get(position);

        if(recyclerViewItem instanceof UnifiedNativeAd){
            return  VIEW_TYPE_AD;
        }else if(postList.get(position) == null){
            return VIEW_TYPE_NULL;
            // Empty Ad view
        }else{
            return VIEW_TYPE_ITEM;
        }

    }

    @Override
    public int getItemCount() {
        return 0;
    }



    private static class ItemViewHolder extends RecyclerView.ViewHolder {

        private CardView cardView1;

        ItemViewHolder(@NonNull View itemView) {
            super(itemView);
            cardView1 = itemView.findViewById(R.id.cv_post);


        }

        void setName(String text1) {
            TextView name = itemView.findViewById(R.id.name);
            name.setText(text1);
        }

    }



    private static class HorizontalItemViewHolder extends RecyclerView.ViewHolder {

        private RecyclerView RV;

        HorizontalItemViewHolder(@NonNull View itemView) {
            super(itemView);

            // Samedi
            RV = itemView.findViewById(R.id.rv_categories);
        }


    }

    private static class AdsViewHolder extends RecyclerView.ViewHolder {
        TemplateView template ;

        AdsViewHolder(@NonNull View itemView) {
            super(itemView);
            template = itemView.findViewById(R.id.adview_feed);

        }
    }

    private static class LoadingViewHolder extends RecyclerView.ViewHolder {
        LoadingViewHolder(@NonNull View itemView) {
            super(itemView);
            //progressBar = itemView.findViewById(R.id.progressBar);
        }
    }


    private void showLoadingView() {
        //ProgressBar would be displayed

    }

    private void populateItemRows(final ItemViewHolder holder, final int position) {

       // *****  Codes /// 
    }

    private void populateHorizontalItems(final HorizontalItemViewHolder holder, final int position){

        // *****  Codes /// 

    }

    private void populateNativeAdModule(AdsViewHolder nativeAdHolder,
                                        final int position ){

         // *****  ADS Codes /// 

    }

}
    }
AYMEN SOUMER
  • 175
  • 2
  • 8
  • `DiffUtil` is related to model-style data, not views. I suggest that you edit your question and post the entire `PostAdapter` implementation. – CommonsWare May 10 '20 at 21:38
  • Did you get any solution for this case? If yes please share it – RaJ Jun 16 '20 at 08:40
  • You can refer to this solution https://stackoverflow.com/questions/63019699/using-recyclerview-with-diffutil-for-multiple-data-types – Azamat Mahkamov Mar 12 '23 at 19:13

2 Answers2

0

DiffUtil does not interst your views, only models come from adapter. It seems you want make diff on postList that consists different kind of types (item, ad etc.)

You can use DiffUtil.ItemCallback<Object> as you did in getItemViewType for Object type.

blackkara
  • 4,900
  • 4
  • 28
  • 58
0

I saw many people view this, post, but nobody responded that's why I decided to share my solution:

//Methods Submitlist + getItemViewType are very important to create. Therefore,

RecyclerView.ViewHolde extends from "import androidx.recyclerview.widget.RecyclerView" it's a native class from Java

//The interface is important too, to bind with diferent types of view

class MensajeAdapter(val idSender:String?): ListAdapter<MessageOne, RecyclerView.ViewHolder>(DiffCallback) {

// DiffCallback
companion object{
    private lateinit var txtMessageSender       : TextView
    private lateinit var txtFechaSender         : TextView
    private lateinit var imgStateMessage        : ImageView
             private var itemNew                : String = ""
             private var listMessages           = mutableListOf<MessageOne>()


    private val DiffCallback = object : DiffUtil.ItemCallback<MessageOne>()
    {
        //verifica si el objeto (o la fila de la base de datos, en tu caso) es el mismo que verifica el ID
        override fun areItemsTheSame(oldItem: MessageOne, newItem: MessageOne): Boolean {
            return oldItem.dateSort == newItem.dateSort
        }
        //verifica si todas las propiedades, no solo el ID, son iguales.
        override fun areContentsTheSame(oldItem: MessageOne, newItem: MessageOne): Boolean {
            return oldItem == newItem
        }

    }

}

override fun submitList(list: MutableList<MessageOne>?) {
    if (list != null) {
        listMessages = list
    }
    super.submitList(list)
}

override fun getItemViewType(position: Int): Int {

    return when(listMessages[position].idUsuario){
            idSender -> TypeCommunication.SENDER.typeCommunication
            else -> TypeCommunication.RECEIVER.typeCommunication
    }
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {

   return when(viewType)
   {
       TypeCommunication.SENDER.typeCommunication ->{
           println("Es Sender")
           ViewHolderRight(parent.inflate(R.layout.item_mensaje_user))
       }
       else -> {
           println("Es Received")
           println("LA combinacion: itemNew:$itemNew  --- $idSender")
           ViewHolderLeft(parent.inflate(R.layout.item_mensaje_remoto))
       }
   }
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    (holder as ChatViewHolder).bindView(getItem(position), idSender)
}

interface ChatViewHolder {
    fun bindView(item: MessageOne, idSender: String?)
}


class ViewHolderRight(itemView: View) : RecyclerView.ViewHolder(itemView),ChatViewHolder {

    private val binding = ItemMensajeUserBinding.bind(itemView)

    override fun bindView(item: MessageOne, idSender: String?) {
        binding.apply {
            txtFechaSender = lblFechaMensaje
            txtMessageSender = lblTextUser
            imgStateMessage = imgVistoMensajeria
        }

        itemView.apply{
            //Ocultar Notificaciones Y Mensajes Nuevos
             txtFechaSender.text = item.horaRegi
             txtMessageSender.text = item.mensaje
             imgStateMessage.setBackgroundResource(R.drawable.ic_done)

        }
    }


}

class ViewHolderLeft(itemView: View) : RecyclerView.ViewHolder(itemView),ChatViewHolder {

    private val binding = ItemMensajeRemotoBinding.bind(itemView)

    override fun bindView(item: MessageOne, idSender: String?) {
        binding.apply {
            txtFechaSender = lblMfechaRemoto
            txtMessageSender = lblTextMsjRemoto
            imgStateMessage = imgVistoMensajeriaRemoto
        }

        itemView.apply{
            //Ocultar Notificaciones Y Mensajes Nuevos
            txtFechaSender.text = item.horaRegi
            txtMessageSender.text = item.mensaje
            imgStateMessage.setBackgroundResource(R.drawable.ic_done)
        }
    }
}

}