Recyclerview 多布局多数据类型的处理

开场白给:醉乡民谣

需求假定:有三个不同的数据请求源,每个数据源的布局方式不同,利用recyclerview的方式展示在界面上

效果如下图: 


本次效果采用rxjava+retrofit请求数据,将所有数据合并入一个List中,在recyclerview adapter中根据类型,进行布局的创建,并且使用了recylerview的一个setSpanSizeLookup方法,来生成不同的排列方式

先看一下Multiadpter

public class MultiTypeAdapter extends RecyclerView.Adapter<BaseViewHolder> {
    private List<Vistable> modules;
    private TypeFactory factory;
    protected Context mContext;
    public MultiTypeAdapter(List<Vistable> modules,Context context){
        mContext = context;
        this.modules = modules;
        factory = new TypeFactoryList();
    }
    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(viewType, parent, false);
        return factory.createViewHolder(viewType, view);
    }

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        holder.bindViewData(modules.get(position),position,mContext,this);
    }

    @Override
    public int getItemCount() {
        return modules == null? 0:modules.size();
    }

    @Override
    public int getItemViewType(int position) {
        return modules.get(position).type(factory);
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager == null || !(manager instanceof GridLayoutManager)) return;
        ((GridLayoutManager) manager).setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                if (getItemViewType(position)== R.layout.android_layout_item){
                    return 2;
                }else if (getItemViewType(position) == R.layout.ios_layout_item){
                    return 2;
                }else
                return 1;
            }
        });
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
getItemViewType使用工厂方法进行获取,避免进行类型判断:

首先定义了一个借口,所有的bean类都要实现该接口,从而拿到响应的布局,不再写在adapter中,而是从数据源下手

public interface Vistable {
    int type(TypeFactory factory);

}
1
2
3
4
5
持有一个工厂类,用于根据bean获取响应的布局

//定义了所使用的类型,并且将viewholder的创建加入进来:抽取BaseViewHolder
public interface TypeFactory {
    int type(AndroidBean androidData);
    int type(GirlBean beautifulGirlBean);
    int type(IosBean resultBean);
    BaseViewHolder createViewHolder(int type, View itemView);
}

1
2
3
4
5
6
7
8
9
public abstract class BaseViewHolder extends ViewHolder{ 
private SparseArray sparseArray; 
private View mItemView; 
public BaseViewHolder(View itemView) { 
super(itemView); 
sparseArray = new SparseArray<>(); 
mItemView = itemView; 
}

public <T extends View> T getView(int resId){
    View view = sparseArray.get(resId);
    if (view == null){
        view = mItemView.findViewById(resId);
        sparseArray.put(resId,view);
    }
    return (T) view;
}

public abstract void bindViewData(T data,int position,Context context,MultiTypeAdapter adapter);
1
2
3
4
5
6
7
8
9
10
}

1
//实现类中用于具体的实现

public class TypeFactoryList implements TypeFactory{
    public static final int ANDROID_LAYOUT = R.layout.android_layout_item;
    public static final int GIRL_LAYOUT = R.layout.girl_image_layout;
    public static final int WECHAT_LAYOUT = R.layout.ios_layout_item;
    @Override
    public int type(AndroidBean androidData) {
        return ANDROID_LAYOUT;
    }

    @Override
    public int type(GirlBean beautifulGirlBean) {
        return GIRL_LAYOUT;
    }

    @Override
    public int type(IosBean iosData) {
        return WECHAT_LAYOUT;
    }

    @Override
    public BaseViewHolder createViewHolder(int type, View itemView) {
        switch (type){
            case ANDROID_LAYOUT:
                return new AndroidViewHolder(itemView);
            case GIRL_LAYOUT:
                return new GirlViewHolder(itemView);
            case WECHAT_LAYOUT:
                return new IosViewHolder(itemView);
            default:
                return null;
        }

    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
这样的好处我们再添加新类型的时候不必再去操作adapter,比较清晰,虽然代码比较多,但阅读起来很方便,

看一个具体的viewholer类

public class AndroidViewHolder extends BaseViewHolder<AndroidBean> {
    public AndroidViewHolder(View itemView) {
        super(itemView);
    }

    @Override
    public void bindViewData(final AndroidBean module, int position, final Context context, MultiTypeAdapter adapter) {
        LinearLayout ll = getView(R.id.multi_android_ll);
        ll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                WebActivity.loadUrl(context,module.getUrl());
            }
        });
        ((TextView) getView(R.id.multi_android_tv)).setText(module.getDesc());
        ImageView img = getView(R.id.multi_android_iv);
        GlideApp.with(context).load(R.drawable.home_six_5).into(img);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
在看一个bean类

public  class AndroidBean implements Vistable{
        /**
         * _id : 5990fb20421aa96729c57239
         * createdAt : 2017-08-14T09:21:36.634Z
         * desc : PlayPauseView:让播放、暂停按钮优雅的过渡
         * images : ["http://img.gank.io/8ca1bb97-8d30-4deb-9645-a2c2da1970ab"]
         * publishedAt : 2017-08-14T17:04:50.266Z
         * source : web
         * type : Android
         * url : https://github.com/Lauzy/PlayPauseView
         * used : true
         * who : Lauzy
         */

        private String _id;
        private String createdAt;
        private String desc;
        private String publishedAt;
        private String source;
        private String type;
        private String url;
        private boolean used;
        private String who;
        private List<String> images;

        public String get_id() {
            return _id;
        }

        public void set_id(String _id) {
            this._id = _id;
        }

        public String getCreatedAt() {
            return createdAt;
        }

        public void setCreatedAt(String createdAt) {
            this.createdAt = createdAt;
        }

        public String getDesc() {
            return desc;
        }

        public void setDesc(String desc) {
            this.desc = desc;
        }

        public String getPublishedAt() {
            return publishedAt;
        }

        public void setPublishedAt(String publishedAt) {
            this.publishedAt = publishedAt;
        }

        public String getSource() {
            return source;
        }

        public void setSource(String source) {
            this.source = source;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public boolean isUsed() {
            return used;
        }

        public void setUsed(boolean used) {
            this.used = used;
        }

        public String getWho() {
            return who;
        }

        public void setWho(String who) {
            this.who = who;
        }

        public List<String> getImages() {
            return images;
        }

        public void setImages(List<String> images) {
            this.images = images;
        }

    @Override
    public int type(TypeFactory factory) {
        return factory.type(this);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
使用:

public class WechatActivity extends AppCompatActivity implements CommonImpl {

    @BindView(R.id.toolbar)
    Toolbar toolbar;
    @BindView(R.id.wechat_xry)
    RecyclerView wechatXry;
    private MultiTypeAdapter adapter;
    private List<Vistable> moudles= new ArrayList<>();

    private MultiMoudle recommendMoudle;
    private GridLayoutManager manager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wechat);
        ButterKnife.bind(this);
        initoolbar();
        initView();
        initData();
        initListener();

    }

    private void initListener() {
//        adapter.setmOnItemClickListener(this);
    }

    private void initData() {
        recommendMoudle.getAllData(this);
    }

    private void initView() {
        CustomProgressDialog.show(this,"正在获取数据...",false,null);
        recommendMoudle = new MultiMoudle();
        //设置默认的
        manager = new GridLayoutManager(this,2);
        wechatXry.setLayoutManager(manager);
        wechatXry.setNestedScrollingEnabled(false);
        wechatXry.setHasFixedSize(false);
        wechatXry.setItemAnimator(new DefaultItemAnimator());
        adapter = new MultiTypeAdapter(moudles,this);
        wechatXry.setAdapter(adapter);
    }

    private void initoolbar() {
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        toolbar.setTitle("干货集锦");
        toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

    @Override
    public void loadFailed() {
        CustomProgressDialog.dismisses();
    }

    @Override
    public void addDisaposed(Disposable disposable) {

    }

    @Override
    public void loadMultiSuccess(List<Vistable> vistable) {

        moudles.addAll(vistable);
        CustomProgressDialog.dismisses();
        adapter.notifyDataSetChanged();
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
接下说一下数据获取的处理:因为我们有三个数据源,我们希望等全部数据获取完毕后,再去加载数据,那么用Rxjava怎么实现呢:

这就用到了zip操作符:它可以监视多个Observable,等所有的Observable上游事件处理完毕,再将其按顺序进行合并,这正是我们想要的效果

来看实际运用:相信大家一看就明白了

public void getAllData(final CommonImpl listener){
        ApiService service = ServiceManager.getInstance(Constants.API_GANKIO).creat(ApiService.class);
        Observable<AndroidData> androidDataObservable = service
                .getAndroid()
                .subscribeOn(Schedulers.io());

        Observable<BeautifulGirlBean> beautifulGirlBeanObservable = service
                .getGirls()
                .subscribeOn(Schedulers.io());
        Observable<IosData> iosDataObservable = service

                .getIos()
                .subscribeOn(Schedulers.io());
//        Observable<WeChatListBean> weChatListBeanObservable = ServiceManager.getInstance(Constants.API_MOB).creat(ApiService.class)
//                .weChatSearchListBeanList(cid, page, 20)
//                .subscribeOn(Schedulers.io());

        Observable.zip(androidDataObservable, beautifulGirlBeanObservable, iosDataObservable, new Function3<AndroidData, BeautifulGirlBean, IosData, List<Vistable>>() {
            @Override
            public List<Vistable> apply(@NonNull AndroidData androidData, @NonNull BeautifulGirlBean beautifulGirlBean, @NonNull IosData iosData) throws Exception {
                List<Vistable> list = new ArrayList<Vistable>();
                list.addAll(androidData.getResults());
                list.addAll(beautifulGirlBean.getResults());
                list.addAll(iosData.getResults());
                return list;
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<List<Vistable>>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onNext(@NonNull List<Vistable> vistables) {
                    listener.loadMultiSuccess(vistables);
            }

            @Override
            public void onError(@NonNull Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });

    }
--------------------- 
作者:初心不负 
来源:CSDN 
原文:https://blog.csdn.net/sinat_35670989/article/details/77318395 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值