Create a RecyclerView with multiple view from layouts

前端 未结 3 868
傲寒
傲寒 2020-12-06 16:14

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 wa

相关标签:
3条回答
  • 2020-12-06 16:14

    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.CardView xmlns: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">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="Name  : " />
    
                <TextView
                    android:id="@+id/tvName"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="" />
    
            </LinearLayout>
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="Icon  : " />
    
                <ImageView
                    android:id="@+id/tvIcon"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:padding="10dp"
                    android:text="" />
    
            </LinearLayout>
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="Id  : " />
    
                <TextView
                    android:id="@+id/tvId"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="" />
    
            </LinearLayout>
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="SearchUrl  : " />
    
                <TextView
                    android:id="@+id/tvSearchUrl"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="" />
    
            </LinearLayout>
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="NativeUrl  : " />
    
                <TextView
                    android: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"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView
            android: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;
    
    public class DataAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    
        private Context context;
        ArrayList<Bookmark> arrayList = new ArrayList<>();
        public static final int ITEM_TYPE_ONE = 0;
        public static final int ITEM_TYPE_TWO = 1;
    
        public DataAdapter(Context context, ArrayList<Bookmark> arrayList) {
            this.context = context;
            this.arrayList = arrayList;
        }
    
        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    
            View view = null;
            // check here the viewType and return RecyclerView.ViewHolder based on view type
            if (viewType == ITEM_TYPE_ONE) {
                view = LayoutInflater.from(context).inflate(R.layout.layout_one, parent, false);
                return new ViewHolder(view);
            } else if (viewType == ITEM_TYPE_TWO) {
                view = LayoutInflater.from(context).inflate(R.layout.button_two, parent, false);
                return new ButtonViewHolder(view);
            }else {
                return  null;
            }
    
        }
    
        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    
            final int itemType = getItemViewType(position);
            // First check here the View Type
            // than set data based on View Type to your recyclerview item
            if (itemType == ITEM_TYPE_ONE) {
                ViewHolder viewHolder = (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());
            } else if (itemType == ITEM_TYPE_TWO) {
                ButtonViewHolder buttonViewHolder = (ButtonViewHolder) holder;
                buttonViewHolder.imgButton.setImageResource(arrayList.get(position).getIcon());
            }
    
        }
    
        @Override
        public int getItemViewType(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;
            }
        }
    
        @Override
        public int getItemCount() {
            return arrayList.size();
        }
    
        public class ViewHolder extends RecyclerView.ViewHolder {
    
            TextView tvName, tvId, tvSearchUrl, tvNativeUrl;
    
            ImageView tvIcon;
    
            public ViewHolder(@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);
            }
        }
    
        public class ButtonViewHolder extends RecyclerView.ViewHolder {
    
    
            ImageView imgButton;
    
            public ButtonViewHolder(@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

    public class Bookmark
    {
        String name,id,nativeUrl,searchUrl;
        int icon;
    
        int viewType;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public int getIcon() {
            return icon;
        }
    
        public void setIcon(int icon) {
            this.icon = icon;
        }
    
        public String getNativeUrl() {
            return nativeUrl;
        }
    
        public void setNativeUrl(String nativeUrl) {
            this.nativeUrl = nativeUrl;
        }
    
        public String getSearchUrl() {
            return searchUrl;
        }
    
        public void setSearchUrl(String searchUrl) {
            this.searchUrl = searchUrl;
        }
    
        public int getViewType() {
            return viewType;
        }
    
        public void setViewType(int viewType) {
            this.viewType = viewType;
        }
    
        @Override
        public String toString() {
            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;
    
    public class MainActivity extends AppCompatActivity {
    
        private Context mContext;
        ArrayList<Bookmark> arrayList = new ArrayList<>();
    
        RecyclerView myRecyclerView;
        DataAdapter dataAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
    
            mContext = this;
    
            myRecyclerView = findViewById(R.id.myRecyclerView);
            myRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
            myRecyclerView.setHasFixedSize(true);
    
            dataAdapter = new DataAdapter(mContext, arrayList);
            myRecyclerView.setAdapter(dataAdapter);
    
            try {
    
                XmlPullParser xpp = 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) + " * ");
    
    
                            Bookmark bookmark = new Bookmark();
                            bookmark.setName(xpp.getAttributeValue(0));
    
                            int drawableResourceId = 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 requirement
            Bookmark bookmark = new Bookmark();
            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

    • Working with RecyclerView and multiple view types
    • A RecyclerView with multiple item types
    • Android RecyclerView with Different Child Layouts
    • Android Pagination Tutorial—Handling Multiple View Types
    • Heterogenous Layouts inside RecyclerView
    • Android RecyclerView Example – Multiple ViewTypes
    • How to create RecyclerView with multiple view type?
    • Android Multiple row layout using RecyclerView
    0 讨论(0)
  • 2020-12-06 16:35

    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?

    0 讨论(0)
  • 2020-12-06 16:39

    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

    public class BookMarkAdapter extends RecyclerView.Adapter {
    
    private Context context;
    private ArrayList<Bookmark> data;
    
    public BookMarkAdapter(Context context, ArrayList<Bookmark> data) {
        this.context = context;
        this.data = data;
    }
    
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == 1)
            return new ViewBookmarkHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.cell_with_normal_image_and_textview, parent, false));
        else
            return new AddBookmarkHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.cell_with_image, parent, false));
    
    }
    
    
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    
        Bookmark d = data.get(position);
    
         if (d.getType()==1) {
            ViewBookmarkHolder viewBookmarkHolder =(ViewBookmarkHolder) holder;
            // do your show image and textview operation here
        } else {
    
            AddBookmarkHolder addBookmarkHolder =(AddBookmarkHolder) holder;
            // do your on click operation here. Like adding new bookmark and update your arraylist and notify data changed for adapter.
        }
    }
    
    @Override
    public int getItemViewType(int position) {
        return data.get(position).getType();
    }
    
    @Override
    public int getItemCount() {
        return data.size();
     }
    }
    

    Update this methods and variables in your Bookmark Pojo

    public class Bookmark {
    
        private Integer type;
    
        public Bookmark(Integer type) {
            this.type = type;
        }
    
        public void setType(Integer type) {
            this.type = type;
        }
    
        public Integer getType() {
            if(type==null)
                return 1;
            return type;
        }
      }
    
    0 讨论(0)
提交回复
热议问题