Recyclerview根据setSpanSizeLookup实现复杂布局(不用嵌套)

  • Post author:
  • Post category:其他


  • 先看效果图:

这里写图片描述

我们知道实现recyclerview复杂布局,可以用recyclerview嵌套可以实现。


  • 注:具体使用嵌套还是本文介绍的这种方法,需要根据项目的需求来确定

本文主要说可以根据布局管理器GridLayoutManager的setSpanSizeLookup方法来动态控制。后面具体介绍。

看下setSpanSizeLookup源码:

   /**  设置源获取适配器中每个item占用的跨度数。 
     * Sets the source to get the number of spans occupied by each item in the adapter.
     *
     *用于查询跨越数的实例 每个item占用
     * @param spanSizeLookup {@link SpanSizeLookup} instance to be used to query number of spans
     *
     * occupied by each item
     */
    public void setSpanSizeLookup(SpanSizeLookup spanSizeLookup) {
        mSpanSizeLookup = spanSizeLookup;
    }

  • 首先我们需要重写两个方法


    getItemViewType(int position)



    onAttachedToRecyclerView(RecyclerView recyclerView)
@Override
    public int getItemViewType(int position) {
        /**
         * 根据position设置我们需要的itemtype
         * */
         //例如:
          if (position==0){
            return TYPE_SLIDER;//轮播图
        }

    }

onAttachedToRecyclerView:

@Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);

        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {

                    /**
                     * 根据GridLayoutManager的getSpanSize方法可以动态的设置item跨列数
                     * 需要设置:4个参数的GridLayoutManager
                     * new GridLayoutManager(getActivity(),6,GridLayoutManager.VERTICAL,false);
                     * 这里的6(自己设置的最好设置成偶数)就相当于分母,6默认显示一整行(1列),下面的3 和2 就相当于分子,返回3就是(1/2)所以此类型对应的是2列,返回2就是(1/3)所以此类型对应的是3列
                     * */
                     //例如:根据getItemViewType返回的itemtype,第一个position显示为轮播图,所以返回的是gridManager.getSpanCount();(即:6)
                     int type = getItemViewType(position);
                    switch (type) {
                        case TYPE_SLIDER:
                            //这里的轮播图类型和head  返回默认的spansize(即是6)
                            return gridManager.getSpanCount();
                        //如果要显示两列就返回3   3除以6  二分之一
                    }
                }
            });
        }
    }


setSpanSizeLookup

:这个方法,在上面的源码中我们可以看到,主要是控制每个item占用的跨度数


  • 奉上适配器完整代码
/**
 * Created by sswl on 2017/5/3.
 */

public class OneAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements BaseSliderView.OnSliderClickListener{

    public static final int TYPE_SLIDER = 0x001;
    public static final int TYPE_TYPE2_HEAD = 0x002;
    public static final int TYPE_TYPE2 = 0x003;
    public static final int TYPE_TYPE3_HEAD = 0x004;
    public static final int TYPE_TYPE3 = 0x005;
    public static final int TYPE_TYPE4 = 0x006;

    private Context mCtx;
    private final LayoutInflater inflater;

    public OneAdapter(Context mCtx){
        this.mCtx=mCtx;
        inflater = LayoutInflater.from(mCtx);

    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType){
            case TYPE_SLIDER://轮播图
                return new SliderViewHolder(inflater.inflate(R.layout.slider_type,parent,false));
            case TYPE_TYPE2_HEAD:
            case TYPE_TYPE3_HEAD://head  头布局
                return new HeadViewHolder(inflater.inflate(R.layout.headtitle_item,parent,false));
            case TYPE_TYPE2:
            case TYPE_TYPE3:
            case TYPE_TYPE4:
                return new TypeViewHolder(inflater.inflate(R.layout.one_item_type_1,parent,false));
            default:
                return null;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof SliderViewHolder){
            bindItemTypeSlider((SliderViewHolder) holder, position);
        }else if (holder instanceof HeadViewHolder){
            bindType1Head((HeadViewHolder) holder, position);
        }else if (holder instanceof TypeViewHolder){
            bindType1((TypeViewHolder) holder, position);
        }

    }

    private void bindType1(TypeViewHolder holder, int position) {

    }

    private void bindType1Head(HeadViewHolder holder, int position) {
    }

    /**
     * 实现轮播图
     * */
    private void bindItemTypeSlider(SliderViewHolder holder, int position) {
        //这里可以进行网络操作
        HashMap<String,String> url_maps = new HashMap<String, String>();
        url_maps.put("轮播图1", "http://static2.hypable.com/wp-content/uploads/2013/12/hannibal-season-2-release-date.jpg");
        url_maps.put("轮播图2", "http://cdn3.nflximg.net/images/3093/2043093.jpg");
        url_maps.put("轮播图3", "http://images.boomsbeat.com/data/images/full/19640/game-of-thrones-season-4-jpg.jpg");
        for(String name : url_maps.keySet()){
            DefaultSliderView sliderView = new DefaultSliderView(mCtx);
//            TextSliderView textSliderView = new TextSliderView(this);
            sliderView
                    .description(name)
                    .image(url_maps.get(name))
                    .setScaleType(BaseSliderView.ScaleType.Fit).setOnSliderClickListener(this);

            //add your extra information 点击图片时可用到
            sliderView.bundle(new Bundle());
            sliderView.getBundle()
                    .putString("extra",name);
            holder.slider.setDuration(4000);
            holder.slider.addSlider(sliderView);
        }
    }

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

    @Override
    public int getItemViewType(int position) {
        /**
         * 指定position显示返回对应的itemType
         * */
        if (position==0){
            return TYPE_SLIDER;
        }else if(position==1){
            return TYPE_TYPE2_HEAD;
        }else if(position>=2 && position<=7){
            return TYPE_TYPE2;
        }else if(position==8){
            return TYPE_TYPE3_HEAD;
        }else if(position>=9 && position<=14){
            return TYPE_TYPE3;
        }else if (15<=position && position <= 18){
            return TYPE_TYPE4;
        }else {
            return TYPE_TYPE2;
        }
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    int type = getItemViewType(position);
                    /**
                     * 根据GridLayoutManager的getSpanSize方法可以动态的设置item跨列数
                     * 需要设置:4个参数的GridLayoutManager
                     * new GridLayoutManager(getActivity(),6,GridLayoutManager.VERTICAL,false);
                     * 这里的6(自己设置的最好设置成偶数)就相当于分母,6默认显示一整行(1列),下面的3 和2 就相当于分子,返回3就是(1/2)所以此类型对应的是2列,返回2就是(1/3)所以此类型对应的是3列
                     * */
                    switch (type) {
                        case TYPE_SLIDER:
                        case TYPE_TYPE2_HEAD:
                        case TYPE_TYPE3_HEAD:
                        case TYPE_TYPE4:
                            //这里的轮播图类型和head  返回默认的spansize(即是6)
                            return gridManager.getSpanCount();
                        case TYPE_TYPE2:
                            return 3;
                        case TYPE_TYPE3:
                            return 2;
                        default:
                            //默认显示2列
                            return 3;
                    }
                }
            });
        }
    }

    /**
     * 轮播图点击事件
     * */
    @Override
    public void onSliderClick(BaseSliderView slider) {
        Toast.makeText(mCtx,slider.getBundle().get("extra") + "", Toast.LENGTH_SHORT).show();
    }

    /*
   * 轮播图
   * */
    class SliderViewHolder extends  RecyclerView.ViewHolder{

        public SliderLayout slider;
        public SliderViewHolder(View itemView) {
            super(itemView);
            slider = (SliderLayout) itemView.findViewById(R.id.slider);
        }
    }
    /**
     * head
     * */
    class HeadViewHolder extends  RecyclerView.ViewHolder{

        public ImageView image;
        public HeadViewHolder(View itemView) {
            super(itemView);
        }
    }
    /**
     * 条目显示占多少列(这里由 setSpanSizeLookup动态控制)
     * */
    class TypeViewHolder extends  RecyclerView.ViewHolder{

        public ImageView image;
        public TypeViewHolder(View itemView) {
            super(itemView);
            image= (ImageView) itemView.findViewById(R.id.item_img_type1);
        }
    }

}

到这里结束了!主要介绍了主要的思路!

本人描述能力有限,欢迎吐槽!



版权声明:本文为qq_34501274原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。