美文网首页
RecyclerView多item实现2

RecyclerView多item实现2

作者: jiluyixia | 来源:发表于2019-10-24 18:21 被阅读0次

    banner实现完后,接下来,是五个图标,带文字。

    如图: Screenshot_2019-10-24-17-59-27-038_com.li.gohome.png

    由于是一排,首先想到的是用LinearLayoutManager并且横向排列。
    但是这5个item是平分整个布局,所以可以直接用GridLayoutManager
    先add数据:

    CommonModelListBean localList = new CommonModelListBean();
    localList.setCommonModelListBean(model.getlocalNavList());
    localList.setViewType(LOCAL_TYPE);
    datas.add(localList);
    

    添加布局:local.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="58dp"
        android:orientation="horizontal"
        android:background="@drawable/shape_radius"
        android:layout_marginLeft="7dp"
        android:layout_marginRight="7dp"
        android:layout_marginTop="4dp">
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/local_recycler"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
    </LinearLayout>
    

    添加item布局:local_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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="match_parent">
    
    <com.li.gohome.util.CircleImageView
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:id="@+id/local_image"
        android:src="@mipmap/ic_launcher"
        android:layout_width="30dp"
        android:layout_height="30dp"/>
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/local_text"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/local_image"
            android:textSize="12dp"
            android:text="ff"
            />
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    item布局记得父布局宽度为match_parent。
    然后就是设置holder

    public class LocalHolder extends RecyclerView.ViewHolder {
            RecyclerView localRecycler;
    
            public LocalHolder(@NonNull View itemView) {
                super(itemView);
                localRecycler = itemView.findViewById(R.id.local_recycler);
            }
    }
    else if (viewType == LOCAL_TYPE) {
                return new LocalHolder(LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.local, parent, false));
    }
    

    接着在onBindViewHolder里绑定数据:

    else if (holder instanceof LocalHolder) {
                CommonModelListBean localBean = (CommonModelListBean) datas.get(position);
                RecyclerView recyclerView = ((LocalHolder) holder).localRecycler;
                recyclerView.setLayoutManager(new GridLayoutManager(context, 5, RecyclerView.VERTICAL, false));
                recyclerView.setAdapter(new LocalAdapter(localBean.getCommonModelListBean(),1));
    }
    

    这里布局设置为VERTICAL,并且spanCount设置为5.
    再看看LocalAdapter实现。
    首先重写一个方法:

    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
            super.onAttachedToRecyclerView(recyclerView);
            RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
            if (layoutManager instanceof GridLayoutManager) {
                GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
                gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                    @Override
                    public int getSpanSize(int position) {
                        return 1;
                    }
                });
            }
    }
    

    这里的SpanSize返回1,和上面的spancount结合,代表着一个iten占1/5的位置。
    接着就是将HomePageAdapter传来的数据,绑定到item上面。

    public class LocalItemHolder extends RecyclerView.ViewHolder {
            CircleImageView image;
            TextView textView;
    
            public LocalItemHolder(@NonNull View itemView) {
                super(itemView);
                image = itemView.findViewById(R.id.local_image);
                textView = itemView.findViewById(R.id.local_text);
            }
        }
    if(itemType == 1) {
                return new LocalItemHolder(LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.local_item, parent, false));
    }
    if (holder instanceof LocalItemHolder) {
                ((LocalItemHolder) holder).image.setImageURL(localList.get(position).getIcon());
                ((LocalItemHolder) holder).textView.setText(localList.get(position).getTitle());
    }
    

    这里为什么有个itemtype呢。。
    是因为在主界面,第4个布局,和这个第2个布局,情况很类似,如上图
    所以和第二个布局,公用了一个adapter.
    这2个布局的区别只有图片不设置圆形,以及有2排。
    sub_item.xml:

    <androidx.constraintlayout.widget.ConstraintLayout 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">
    
        <com.li.gohome.util.MyImageView
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:id="@+id/sub_image"
        android:src="@mipmap/ic_launcher"
        android:layout_width="18dp"
        android:layout_height="18dp"/>
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/sub_text"
            android:layout_marginTop="3dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/sub_image"
            android:textSize="12dp"
            android:text="ff"
            />
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    注意,父布局android:layout_height="wrap_content",因为有2排,不可以设置为match_parent。
    另外自定义了一个imageview用来设置网络图片。
    所以其他的都是一样的,只是在初始化adapter的时候,加一个itemtype.
    还有就是加了一个分割线设置recyclerView.addItemDecoration(new ItemDecoration());
    因为第一排和第二排,中间有一个距离20dp。

    public class ItemDecoration extends RecyclerView.ItemDecoration{
            @Override
            public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
                super.getItemOffsets(outRect, view, parent, state);
                outRect.set(0, 0, 0, 20);
            }
    }
    

    所以将每个item的bottom距离设置为20.
    这样就会导致两排都会距离下面20dp。
    如果想最后一排不要这个距离,可以将父布局sub的总高度设置小一点,让这个最后一排的高度没有空间。

    再来看第三个布局,第三个布局,分3块。所以可以设置一个公用的xml。

    grid_item.xml:
    <?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="88dp"
        android:orientation="horizontal"
        android:layout_marginLeft="7dp"
        android:layout_marginRight="7dp"
        android:layout_marginTop="4dp"
        android:id="@+id/grid_item_layout">
    
        <RelativeLayout
            android:layout_width="121dp"
            android:layout_height="88dp"
            >
    
            <TextView
                android:id="@+id/main_item"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="8dp"
                android:text="kkkk" />
    
            <ImageView
                android:id="@+id/main_image"
                android:layout_width="121dp"
                android:layout_height="50dp"
                android:layout_alignParentBottom="true"/>
    
    
        </RelativeLayout>
    
        <LinearLayout
            android:layout_width="1dp"
            android:layout_height="88dp"
            android:background="@android:color/white"/>
    
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="88dp"
            android:layout_weight="1"
            android:orientation="vertical">
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                >
                <TextView
                    android:id="@+id/item1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:text="jjj" />
            </RelativeLayout>
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="@android:color/white"/>
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1">
                <TextView
                    android:id="@+id/item2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:text="hhh" />
            </RelativeLayout>
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="1dp"
            android:layout_height="88dp"
            android:background="@android:color/white"/>
    
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="88dp"
            android:layout_weight="1"
            android:orientation="vertical">
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                >
                <TextView
                    android:id="@+id/item3"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:text="jjj" />
            </RelativeLayout>
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="@android:color/white"/>
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1">
                <TextView
                    android:id="@+id/item4"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:text="hhh" />
            </RelativeLayout>
        </LinearLayout>
    </LinearLayout>
    

    由于这三个布局的数据,都是GridNav.GridNavItem。
    设置一个通用的bean:

    public class GridItemBean extends ExampleBaseBean {
        private GridNav.GridNavItem gridItemBean;
    
        public GridNav.GridNavItem getGridItemBean() {
            return gridItemBean;
        }
    
        public void setGridItemBean(GridNav.GridNavItem gridItemBean) {
            this.gridItemBean = gridItemBean;
        }
    }
    

    添加数据:

    //grad_hotel
    GridItemBean gradHotel = new GridItemBean();
    gradHotel.setGridItemBean(model.getGridnav().getHotel());
    gradHotel.setViewType(HOTEL_TYPE);
    datas.add(gradHotel);
    //grad_flight
    GridItemBean gradFlight = new GridItemBean();
    gradFlight.setGridItemBean(model.getGridnav().getFlight());
    gradFlight.setViewType(FLIGHT_TYPE);
    datas.add(gradFlight);
    //grad_travel
    GridItemBean gradTravel = new GridItemBean();
    gradTravel.setGridItemBean(model.getGridnav().getTravel());
    gradTravel.setViewType(TRAVEL_TYPE);
    datas.add(gradTravel);
    

    设置一个通用的holder

    public class GridItemHolder extends RecyclerView.ViewHolder {
            private LinearLayout gridLayout;
            private ImageView mainImage;
            private TextView mainText, Item1, Item2, Item3, Item4;
    
            public GridItemHolder(@NonNull View itemView) {
                super(itemView);
                gridLayout = itemView.findViewById(R.id.grid_item_layout);
                mainImage = itemView.findViewById(R.id.main_image);
                mainText = itemView.findViewById(R.id.main_item);
                Item1 = itemView.findViewById(R.id.item1);
                Item2 = itemView.findViewById(R.id.item2);
                Item3 = itemView.findViewById(R.id.item3);
                Item4 = itemView.findViewById(R.id.item4);
            }
    }
    

    三种type下,都用这个holder.

    else if (viewType == HOTEL_TYPE || viewType == FLIGHT_TYPE || viewType == TRAVEL_TYPE) {
                return new GridItemHolder(LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.grid_item, parent, false));
    }
    

    接下来绑定数据,这个要考虑通用性:

    else if (holder instanceof GridItemHolder) {
                GridItemBean gridItemBean = (GridItemBean) datas.get(position);
                setGridLayoutBG(((GridItemHolder) holder).gridLayout, gridItemBean.getGridItemBean());
                mainItem(((GridItemHolder) holder).mainImage, ((GridItemHolder) holder).mainText, gridItemBean.getGridItemBean().getMainItem());
                gridItem(((GridItemHolder) holder).Item1, ((GridItemHolder) holder).Item2, ((GridItemHolder) holder).Item3,
                        ((GridItemHolder) holder).Item4, gridItemBean.getGridItemBean());
    }
    

    这里设置了三个方法,第一个setGridLayoutBG是设置整个item的背景色,

    private void setGridLayoutBG(LinearLayout layout, GridNav.GridNavItem gridNavItem) {
            Log.v("mm", gridNavItem.getStartColor());
            GradientDrawable linearDrawableTop = getGrad(Color.parseColor("#" + gridNavItem.getStartColor()), Color.parseColor("#" + gridNavItem.getEndColor()));
            layout.setBackground(linearDrawableTop);
    }
    public GradientDrawable getGrad(int startColor, int endColor) {
            int[] colors = new int[]{startColor, endColor};
            GradientDrawable linearDrawable = new GradientDrawable();
            linearDrawable.setOrientation(GradientDrawable.Orientation.LEFT_RIGHT);
            linearDrawable.setColors(colors);
            linearDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
            return linearDrawable;
    }
    

    第二个方法,设置左边那个大方块:

    private void mainItem(ImageView imageView, TextView textView, CommonModel model) {
            Glide.with(context).load(model.getIcon()).into(imageView);
            textView.setText(model.getTitle());
    }
    

    第三个方法,设置右边四个小方块:

    private void gridItem(TextView item1, TextView item2, TextView item3, TextView item4, GridNav.GridNavItem gridNavItem) {
            item1.setText(gridNavItem.getItem1().getTitle());
            item2.setText(gridNavItem.getItem2().getTitle());
            item3.setText(gridNavItem.getItem3().getTitle());
            item4.setText(gridNavItem.getItem4().getTitle());
    }
    

    具体代码如下:
    https://github.com/doudousang/recyclerview_items.git

    参考网址:
    RecyclerView添加分割线最易懂解析
    GridLayoutManager setSpanSizeLookup()方法
    Android shape gradient背景渐变

    相关文章

      网友评论

          本文标题:RecyclerView多item实现2

          本文链接:https://www.haomeiwen.com/subject/wsmdvctx.html