MultiTypeView

Introduction: 简化 RecyclerView 的多种 type 的 adapter,Fragment 可以动态添加到 RecyclerView 上,实现复杂的界面分多个模块开发
More: Author   ReportBugs   DemoAPK   
Tags:
RecyclerView-adapter-Fragment-more type-

1.简化 RecyclerView 的多种 type 的 adapter

2.ViewHolder 的创建和绑定被提取出来变成 ItemViewProvider,可以被多个 adapter 复用

3.支持一种数据对应多种 ItemViewProvider

4.Fragment 可以添加到 RecyclerView 上,实现复杂的界面

对于复杂的界面非常有利,一个复杂的界面可以分成多个 Fragment,一个项目组分配给多个人开发.

5.RecyclerView 上的 Fragment 是显示时候才加载

具有懒加载的效果.假设 RecyclerView 上放了 10 个 Fragment,你进去的时候只加载到开始的 1,2 个 Fragment

6.支持全局注册 ItemViewProvider,和局部注册,和局部覆盖注册.

7.列表的数据保存和恢复,以及 fragment 的保存和恢复

Download sample Apk

效果图

image

关系图

image

使用方法

实现 ItemViewProvider

public class MessageLeftProvider extends ItemViewProvider<Message> {

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(LayoutInflater inflater, ViewGroup parent, int providerType) {
        return new ItemViewHolder(inflater.inflate(R.layout.item_message_left, parent, false));
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, Message message) {
        ItemViewHolder vh = (ItemViewHolder) viewHolder;
        vh.textView.setText(message.text);
    }

    private class ItemViewHolder extends RecyclerView.ViewHolder {

        private final TextView textView;

        public ItemViewHolder(View itemView) {
            super(itemView);
            textView = (TextView) itemView.findViewById(R.id.item_message_textView);
        }
    }
}

Activity 代码

public class LongPageActivity extends AppCompatActivity {
    private MultiTypeAdapter<Object> multiTypeAdapter;
    private MultiTypeView multiTypeView;
    private String myUserId = "1";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_long_page);
        multiTypeView = (MultiTypeView) findViewById(R.id.multiTypeView);
        //带有 FragmentManager 的构造函数,默认帮您添加支持 Fragment 数据的 FragmentHolderProvider
        //也就是说你可以把 Fragment 放在 adapter 上使用,这里的 Fragment 只有第一次滑动到对应位置才会 onCreateView 的方法
        ItemBinderFactory itemBinderFactory = new ItemBinderFactory(getSupportFragmentManager());
        //有时候需要根据 TextItem 里面的某个字段,生成不同的布局.比如聊天界面的 message 是一样的,但是有区分左右布局
        //ItemProviderSet 可以通过数据类型区分无数种情况的 Provider
       itemBinderFactory.registerProvider(Message.class, new ItemViewProviderSet<Message>(new MessageProvider(MessageProvider.ALIGN_LEFT), new MessageProvider(MessageProvider.ALIGN_RIGHT)) {
                  @Override
                  protected int selectIndex(Message message) {
                      return myUserId.equals(message.userId) ? 1 : 0;
                  }
        });
        multiTypeAdapter = new MultiTypeAdapter<>(loadData(0), itemBinderFactory);
        multiTypeView.setAdapter(multiTypeAdapter);
    }

    private List<Object> loadData(int page) {
        List<Object> data = new ArrayList<>();
        TextView textView = new TextView(this);
        textView.setText("第" + page + "页");
        textView.setGravity(Gravity.CENTER);
        textView.setBackgroundColor(Color.GRAY);
        textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, DisplayUtils.dipToPix(this, 100)));
        data.add(textView);
        data.add(new Message("1", "今天这个状态有所保留么?"));
        data.add(new Message("2", "没有保留!我已经,我已经用了洪荒之力啦!"));
        data.add(new FragmentData(InfoLazyFragment.class, "InfoLazyFragment" + page));
        data.add(new FragmentData(EditLazyFragment.class, "EditLazyFragment" + page));
        data.add(new FragmentData(HotelLazyFragment.class, "HotelLazyFragment" + page));
        data.add(new FragmentData(AirlineTicketLazyFragment.class, "AirlineTicketLazyFragment" + page));
        data.add(new FragmentData(ShopLazyFragment.class, "ShopLazyFragment" + page));
        data.add(new FragmentData(RecommendLazyFragment.class, "RecommendLazyFragment" + page));
        data.add(new FragmentData(FoodLazyFragment.class, "FoodLazyFragment" + page));
        data.add(new FragmentData(CultureLazyFragment.class, "CultureLazyFragment" + page));
        this.page = page;
        return data;
    }
}  

很简单吧,三个步骤

1.实现 ItemViewProvider 并注册到 ItemBinderFactory 上

2.然后设置 MultiTypeAdapter

3.添加数据

Gradle

compile 'com.shizhefei:MultiTypeView:1.0.1'
由于用到了 v4 和 recyclerview 所以也要导入他们  
compile 'com.android.support:support-v4:23.4.0'  
compile 'com.android.support:recyclerview-v7:23.2.1'  

说明

本项目是根据 https://github.com/drakeet/MultiType 类库的想法
把 ViewHolder 的创建以 ItemViewProvider 的形式分离出来 ,以及参考了部分代码实现.

之后我添加了 Fragment 添加到 RecyclerView 上功能,以及 view 以数据的形式也可以添加上去.还有就是全局注册和局部注册的方案,ItemViewProviderSet 实现了相同数据类型不同的 ItemViewProvider.

非常感谢 @drakeet

主力类库

1.https://github.com/LuckyJayce/ViewPagerIndicator
Indicator 取代 tabhost,实现网易顶部 tab,新浪微博主页底部 tab,引导页,无限轮播 banner 等效果,高度自定义 tab 和特效

2.https://github.com/LuckyJayce/MVCHelper
实现下拉刷新,滚动底部自动加载更多,分页加载,自动切换显示网络失败布局,暂无数据布局,支持任意 view,支持切换主流下拉刷新框架。

3.https://github.com/LuckyJayce/MultiTypeView
简化 RecyclerView 的多种 type 的 adapter,Fragment 可以动态添加到 RecyclerView 上,实现复杂的界面分多个模块开发

4.https://github.com/LuckyJayce/EventBus
事件总线,通过动态代理接口的形式发布,接收事件。定义一个接口把事件发给注册并实现接口的类

5.https://github.com/LuckyJayce/LargeImage
大图加载,可供学习

6.https://github.com/LuckyJayce/GuideHelper
新手引导页,轻松的实现对应的 view 上面的显示提示信息和展示功能给用户

7.https://github.com/LuckyJayce/HVScrollView
可以双向滚动的 ScrollView,支持嵌套 ScrollView 联级滑动,支持设置支持的滚动方向

8.https://github.com/LuckyJayce/CoolRefreshView
下拉刷新 RefreshView,支持任意 View 的刷新 ,支持自定义 Header,支持 NestedScrollingParent,NestedScrollingChild 的事件分发,嵌套 ViewPager 不会有事件冲突

有了这些类库,让你 6 的飞起

联系方式和问题建议

License

Copyright 2016 shizhefei(LuckyJayce)
Copyright 2016 drakeet.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apps
About Me
GitHub: Trinea
Facebook: Dev Tools