Skip to content Skip to sidebar Skip to footer

Create A Recyclerview With Multiple View From Layouts

I am trying to have 2 layout in one RecyclerView I have a recycler view list which is called Bookmark and it is parsed from an xml and this is all working , but I wanna in this rec

Solution 1:

Here is the answer

Follow this steps

First Create a two layout for your Multiple viewType

SAMPLE CODE

layout.layout_one

<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardViewxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"app:cardCornerRadius="15dp"app:cardElevation="5dp"app:cardUseCompatPadding="true"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="Name  : " /><TextViewandroid:id="@+id/tvName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="Icon  : " /><ImageViewandroid:id="@+id/tvIcon"android:layout_width="20dp"android:layout_height="20dp"android:padding="10dp"android:text="" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="Id  : " /><TextViewandroid:id="@+id/tvId"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="SearchUrl  : " /><TextViewandroid:id="@+id/tvSearchUrl"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="NativeUrl  : " /><TextViewandroid:id="@+id/tvNativeUrl"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="" /></LinearLayout></LinearLayout></android.support.v7.widget.CardView>

layout.button_two

<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:id="@+id/imgButton"android:layout_width="50dp"android:layout_height="50dp" /></LinearLayout>

Now you need to create two RecyclerView.ViewHolder for your both viewType

Now you need to Override getItemViewType()

  • it Return the viewType of the item at position for the purposes of view recycling.

Now in your onCreateViewHolder() method you need to return your instance of your ViewHolder based on your viewType which you will get using getItemViewType() method

Than in your onBindViewHolder() method based your viewType set your view property

here is the sample code of RecyclerView.Adapter with multiple view types

DataAdapter

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;

publicclassDataAdapterextendsRecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context context;
    ArrayList<Bookmark> arrayList = newArrayList<>();
    publicstaticfinalintITEM_TYPE_ONE=0;
    publicstaticfinalintITEM_TYPE_TWO=1;

    publicDataAdapter(Context context, ArrayList<Bookmark> arrayList) {
        this.context = context;
        this.arrayList = arrayList;
    }

    @NonNull@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        Viewview=null;
        // check here the viewType and return RecyclerView.ViewHolder based on view typeif (viewType == ITEM_TYPE_ONE) {
            view = LayoutInflater.from(context).inflate(R.layout.layout_one, parent, false);
            returnnewViewHolder(view);
        } elseif (viewType == ITEM_TYPE_TWO) {
            view = LayoutInflater.from(context).inflate(R.layout.button_two, parent, false);
            returnnewButtonViewHolder(view);
        }else {
            returnnull;
        }

    }

    @OverridepublicvoidonBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        finalintitemType= getItemViewType(position);
        // First check here the View Type// than set data based on View Type to your recyclerview itemif (itemType == ITEM_TYPE_ONE) {
            ViewHolderviewHolder= (ViewHolder) holder;
            viewHolder.tvName.setText(arrayList.get(position).getName());
            viewHolder.tvIcon.setImageResource(arrayList.get(position).getIcon());
            viewHolder.tvSearchUrl.setText(arrayList.get(position).getSearchUrl());
            viewHolder.tvNativeUrl.setText(arrayList.get(position).getNativeUrl());
        } elseif (itemType == ITEM_TYPE_TWO) {
            ButtonViewHolderbuttonViewHolder= (ButtonViewHolder) holder;
            buttonViewHolder.imgButton.setImageResource(arrayList.get(position).getIcon());
        }

    }

    @OverridepublicintgetItemViewType(int position) {
        // based on you list you will return the ViewType if (arrayList.get(position).getViewType() == 0) {
            return ITEM_TYPE_ONE;
        } else {
            return ITEM_TYPE_TWO;
        }
    }

    @OverridepublicintgetItemCount() {
        return arrayList.size();
    }

    publicclassViewHolderextendsRecyclerView.ViewHolder {

        TextView tvName, tvId, tvSearchUrl, tvNativeUrl;

        ImageView tvIcon;

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

            tvName = itemView.findViewById(R.id.tvName);
            tvIcon = itemView.findViewById(R.id.tvIcon);
            tvId = itemView.findViewById(R.id.tvId);
            tvSearchUrl = itemView.findViewById(R.id.tvSearchUrl);
            tvNativeUrl = itemView.findViewById(R.id.tvNativeUrl);
        }
    }

    publicclassButtonViewHolderextendsRecyclerView.ViewHolder {


        ImageView imgButton;

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

            imgButton = itemView.findViewById(R.id.imgButton);

        }
    }
}

When you adding data in your list you need to provide the viewtype in list

Make some changes in your Bookmark POJO class

Bookmark POJO class

publicclassBookmark
{
    String name,id,nativeUrl,searchUrl;
    int icon;

    int viewType;

    publicStringgetName() {
        return name;
    }

    publicvoidsetName(String name) {
        this.name = name;
    }

    publicStringgetId() {
        return id;
    }

    publicvoidsetId(String id) {
        this.id = id;
    }

    public int getIcon() {
        return icon;
    }

    publicvoidsetIcon(int icon) {
        this.icon = icon;
    }

    publicStringgetNativeUrl() {
        return nativeUrl;
    }

    publicvoidsetNativeUrl(String nativeUrl) {
        this.nativeUrl = nativeUrl;
    }

    publicStringgetSearchUrl() {
        return searchUrl;
    }

    publicvoidsetSearchUrl(String searchUrl) {
        this.searchUrl = searchUrl;
    }

    public int getViewType() {
        return viewType;
    }

    publicvoidsetViewType(int viewType) {
        this.viewType = viewType;
    }

    @OverridepublicStringtoString() {
        return"Bookmark{" +
                "name='" + name + '\'' +
                ", icon='" + icon + '\'' +
                ", id='" + id + '\'' +
                ", nativeUrl='" + nativeUrl + '\'' +
                ", searchUrl='" + searchUrl + '\'' +
                '}';
    }
}

Sample activity code

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.ArrayList;

publicclassMainActivityextendsAppCompatActivity {

    private Context mContext;
    ArrayList<Bookmark> arrayList = newArrayList<>();

    RecyclerView myRecyclerView;
    DataAdapter dataAdapter;

    @OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        mContext = this;

        myRecyclerView = findViewById(R.id.myRecyclerView);
        myRecyclerView.setLayoutManager(newLinearLayoutManager(mContext));
        myRecyclerView.setHasFixedSize(true);

        dataAdapter = newDataAdapter(mContext, arrayList);
        myRecyclerView.setAdapter(dataAdapter);

        try {

            XmlPullParserxpp= getResources().getXml(R.xml.bookmarks);

            while (xpp.getEventType() != XmlPullParser.END_DOCUMENT) {
                if (xpp.getEventType() == XmlPullParser.START_TAG) {
                    if (xpp.getName().equals("Bookmark")) {

                        Log.e("MY_VALUE", " * " + xpp.getAttributeValue(0) + " * ");
                        Log.e("MY_VALUE", " * " + xpp.getAttributeValue(1) + " * ");
                        Log.e("MY_VALUE", " * " + xpp.getAttributeValue(5) + " * ");
                        Log.e("MY_VALUE", " * " + xpp.getAttributeValue(2) + " * ");
                        Log.e("MY_VALUE", " * " + xpp.getAttributeValue(3) + " * ");
                        Log.e("MY_VALUE", " * " + xpp.getAttributeValue(4) + " * ");


                        Bookmarkbookmark=newBookmark();
                        bookmark.setName(xpp.getAttributeValue(0));

                        intdrawableResourceId=this.getResources().getIdentifier(xpp.getAttributeValue(1), "drawable", mContext.getPackageName());
                        bookmark.setIcon(drawableResourceId);

                        bookmark.setId(xpp.getAttributeValue(2));

                        bookmark.setSearchUrl(xpp.getAttributeValue(3));
                        bookmark.setNativeUrl(xpp.getAttributeValue(4));

                        // here you need to set view type
                        bookmark.setViewType(0);
                        arrayList.add(bookmark);
                    }
                }

                xpp.next();
            }
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // here i have added second viewType// you need to set as per your requirementBookmarkbookmark=newBookmark();
        bookmark.setViewType(1);
        bookmark.setIcon(R.drawable.dishu);
        arrayList.add(bookmark);
        dataAdapter.notifyDataSetChanged();

    }


}

NOTE

In the below code i have set second viewType at the last index of Arraylist you need to set viewType as per your requirement

For more information you can check below articles

Solution 2:

You can use different layouts on the same RecyclerView , just override adapter getItemViewType() method and return a different int value for the button layout, in your example you should return for example 1 for the normal item and 2 for the button item.

The view type is passed as argument to onCreateViewHolder() method and depending of the viewType value you inflate the normal layout or the button layout.

It seems that you need also make getItemCount() to return one more than the array size

Hope it will help

Here an example: How to create RecyclerView with multiple view type?

Solution 3:

Do this operations in your Activity.

        ArrayList<Bookmark>  data = new ArrayList<>();
        //data.addAll(your array list bookmark); uncomment this line add your all array list of bookmark
        Bookmark d = new Bookmark(0);
        data.add(d);
        mList.setAdapter(new BookMarkAdapter(activity, data));

Try This adapter

publicclassBookMarkAdapterextendsRecyclerView.Adapter {

private Context context;
private ArrayList<Bookmark> data;

publicBookMarkAdapter(Context context, ArrayList<Bookmark> data) {
    this.context = context;
    this.data = data;
}

@NonNull@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    if (viewType == 1)
        returnnewViewBookmarkHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.cell_with_normal_image_and_textview, parent, false));
    elsereturnnewAddBookmarkHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.cell_with_image, parent, false));

}


@OverridepublicvoidonBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

    Bookmarkd= data.get(position);

     if (d.getType()==1) {
        ViewBookmarkHolderviewBookmarkHolder=(ViewBookmarkHolder) holder;
        // do your show image and textview operation here
    } else {

        AddBookmarkHolderaddBookmarkHolder=(AddBookmarkHolder) holder;
        // do your on click operation here. Like adding new bookmark and update your arraylist and notify data changed for adapter.
    }
}

@OverridepublicintgetItemViewType(int position) {
    return data.get(position).getType();
}

@OverridepublicintgetItemCount() {
    return data.size();
 }
}

Update this methods and variables in your Bookmark Pojo

publicclassBookmark {

    privateIntegertype;

    publicBookmark(Integertype) {
        this.type = type;
    }

    publicvoidsetType(Integer type) {
        this.type = type;
    }

    publicIntegergetType() {
        if(type==null)
            return1;
        returntype;
    }
  }

Post a Comment for "Create A Recyclerview With Multiple View From Layouts"