zoukankan      html  css  js  c++  java
  • VLayoutDemo【VLayout的简单使用demo(基于V1.2.8版本)】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处!

    前言

    VirtualLayout是一个针对RecyclerView的LayoutManager扩展, 主要提供一整套布局方案和布局间的组件复用的问题。

    设计思路

    通过定制化的LayoutManager,接管整个RecyclerView的布局逻辑;LayoutManager管理了一系列LayoutHelper,LayoutHelper负责具体布局逻辑实现的地方;每一个LayoutHelper负责页面某一个范围内的组件布局;不同的LayoutHelper可以做不同的布局逻辑,因此可以在一个RecyclerView页面里提供异构的布局结构,这就能比系统自带的LinearLayoutManager、GridLayoutManager等提供更加丰富的能力。同时支持扩展LayoutHelper来提供更多的布局能力。

    主要功能

    • 默认通用布局实现,解耦所有的View和布局之间的关系: Linear, Grid, 吸顶, 浮动, 固定位置等。
      • LinearLayoutHelper: 线性布局
      • GridLayoutHelper: Grid布局, 支持横向的colspan
      • FixLayoutHelper: 固定布局,始终在屏幕固定位置显示
      • ScrollFixLayoutHelper: 固定布局,但之后当页面滑动到该图片区域才显示, 可以用来做返回顶部或其他书签等
      • FloatLayoutHelper: 浮动布局,可以固定显示在屏幕上,但用户可以拖拽其位置
      • ColumnLayoutHelper: 栏格布局,都布局在一排,可以配置不同列之间的宽度比值
      • SingleLayoutHelper: 通栏布局,只会显示一个组件View
      • OnePlusNLayoutHelper: 一拖N布局,可以配置1-5个子元素
      • StickyLayoutHelper: stikcy布局, 可以配置吸顶或者吸底
      • StaggeredGridLayoutHelper: 瀑布流布局,可配置间隔高度/宽度
    • 上述默认实现里可以大致分为两类:一是非fix类型布局,像线性、Grid、栏格等,它们的特点是布局在整个页面流里,随页面滚动而滚动;另一类就是fix类型的布局,它们的子节点往往不随页面滚动而滚动。
    • 所有除布局外的组件复用,VirtualLayout将用来管理大的模块布局组合,扩展了RecyclerView,使得同一RecyclerView内的组件可以复用,减少View的创建和销毁过程。

    使用

    这个demo只是简单记录下上面黄色标记的几种布局的实现。

    注意

    vlayout1.2.8版本中使用的recyclerview是23.1.1版本,v4是23.1.1,这个需要注意。如果项目中用到recyclerview和v4包的话,建议依赖新版本的recyclerview和v4。

    下面是vlayout的build.gradle文件的部分源码:

    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        // compile project(':extension')
        if (project.hasProperty('useNewSupportLibrary')) {
            compile 'com.android.support:recyclerview-v7:25.2.0@aar'
            compile('com.android.support:support-v4:25.2.0@aar')
            compile 'com.android.support:support-annotations:25.2.0'
            compile 'com.android.support:support-compat:25.2.0'
            compile 'com.android.support:support-core-ui:25.2.0'
        } else {
            compile 'com.android.support:recyclerview-v7:23.1.1@aar'
            compile('com.android.support:support-v4:23.1.1@aar') {
                exclude group: 'com.android.support', module: 'support-annotations'
            }
            compile 'com.android.support:support-annotations:23.1.1'
        }
    
        androidTestCompile "org.robolectric:robolectric:3.0"
    }

    所以在项目中app目录的build.gradle中依赖vlayout时,会有这样的提醒:

    效果图

     

    使用步骤

    一、项目组织结构图

    注意事项:

    1、  导入类文件后需要change包名以及重新import R文件路径

    2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

    二、导入步骤

    1、在build.gradle文件中依赖vlayout

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 28
        defaultConfig {
            applicationId "com.why.project.vlayoutdemo"
            minSdkVersion 16
            targetSdkVersion 28
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation 'com.android.support:appcompat-v7:28.0.0'
        implementation 'com.android.support.constraint:constraint-layout:1.1.3'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    
        //Vlayout
        implementation ('com.alibaba.android:vlayout:1.2.8@aar') {
            transitive = true
        }
        //下面的代码,根据实际情况添加,如果项目中用到了下面的库,则需要根据项目依赖高版本库,否则就会使用vlayout中的低版本库
        //RecyclerView【因为vlayout中的recyclerview版本低,所以需要重新依赖高版本,否则app中使用recyclerview的话会直接使用vlayout中的低版本recyclerview】
        implementation "com.android.support:recyclerview-v7:28.0.0"
        //v4
        implementation 'com.android.support:support-v4:28.0.0'
    }

    这样就将vlayout集成到项目中了。

    三、使用方法

    1、先在demo中添加测试数据文件

    {
        "data": [
            {
                "modelname": "推送新闻",
                "data": [
                    {
                        "image": "https://imgsa.baidu.com/news/q%3D100/sign=06d12a2732dbb6fd235be1263925aba6/b151f8198618367a8dbfe10125738bd4b31ce53c.jpg",
                        "url": "http://news.ifeng.com/a/20180120/55302258_0.shtml?_zbs_baidu_news",
                        "title": "安徽合肥:“非遗”进校园",
                        "id": "whyidzhi",
                        "order": "1"
                    }
                ]
            },
            {
                "modelname": "焦点新闻",
                "data": [
                    {
                        "image": "https://b.bdstatic.com/boxlib/20180120/2018012017100383423448679.jpg",
                        "url": "http://pic.chinadaily.com.cn/2018-01/20/content_35544757.htm",
                        "title": "西昌铁路警方用表情包宣传爱路小知识",
                        "id": "whyidzhi",
                        "order": "1"
                    },
                    {
                        "image": "https://b.bdstatic.com/boxlib/20180120/2018012017100311270281486.jpg",
                        "url": "http://pic.chinadaily.com.cn/2018-01/20/content_35544758.htm",
                        "title": "成都熊猫基地太阳产房全新升级",
                        "id": "whyidzhi",
                        "order": "2"
                    },
                    {
                        "image": "https://b.bdstatic.com/boxlib/20180120/2018012017100392134086973.jpg",
                        "url": "http://pic.chinadaily.com.cn/2018-01/20/content_35544759.htm",
                        "title": "长沙“90后”交警用手绘记录交警故事",
                        "id": "whyidzhi",
                        "order": "3"
                    }
                ]
            },
            {
                "modelname": "国际人物",
                "data": [
                    {
                        "image": "http://t12.baidu.com/it/u=264843290,870648681&fm=173&s=29C043870E531CDC082897A003006015&w=218&h=146&img.JPEG",
                        "url": "http://news.163.com/18/0120/15/D8JS570V00018AOQ_all_mobile.html",
                        "title": "法总统马克龙会见默克尔 强调欧洲改革需要德国(全文..",
                        "id": "whyidzhi",
                        "order": "1"
                    },
                    {
                        "image": "",
                        "url": "http://www.yidianzixun.com/article/0IBPUBcu",
                        "title": "默克尔组阁能否成功?全等这场党代会",
                        "id": "whyidzhi",
                        "order": "2"
                    },
                    {
                        "image": "",
                        "url": "http://www.yidianzixun.com/article/0IBMT9yr",
                        "title": "马克龙向默克尔表支持 强调推动欧洲改革需要德国",
                        "id": "whyidzhi",
                        "order": "3"
                    },
                    {
                        "image": "",
                        "url": "http://news.sina.com.cn/w/2018-01-20/doc-ifyquixe4989529.shtml",
                        "title": "德法首脑在巴黎会晤 默克尔:欧洲需要稳定的德国政府",
                        "id": "whyidzhi",
                        "order": "4"
                    },
                    {
                        "image": "",
                        "url": "http://news.sina.com.cn/o/2018-01-20/doc-ifyqtycx0664636.shtml",
                        "title": "德国社民党民众支持率创新低",
                        "id": "whyidzhi",
                        "order": "5"
                    }
                ]
            },
            {
                "modelname": "图片新闻",
                "data": [
                    {
                        "image": "https://t10.baidu.com/it/u=44207055,3448633405&fm=173&s=CFF20CC150452CEC9F9C491103005092&w=218&h=146&img.JPEG",
                        "url": "http://war.163.com/18/0120/11/D8JEFM5D000181KT_mobile.html",
                        "title": "外媒称朝鲜先遣队取消访韩",
                        "id": "whyidzhi",
                        "order": "1"
                    },
                    {
                        "image": "https://t10.baidu.com/it/u=1625316837,2876937793&fm=173&s=F507703317115D6644753AE80300E036&w=218&h=146&img.JPEG",
                        "url": "http://news.china.com/internationalgd/10000166/20180120/31985304.html",
                        "title": "狂风横扫欧洲多国,致10人",
                        "id": "whyidzhi",
                        "order": "2"
                    },
                    {
                        "image": "https://t10.baidu.com/it/u=2946973968,4057971581&fm=173&s=2D216D93C2F00B9219A825E703009060&w=218&h=146&img.JPEG",
                        "url": "http://news.sina.com.cn/w/2018-01-20/doc-ifyqtycx0654102.shtml",
                        "title": "津巴布韦反对党要人在美坠",
                        "id": "whyidzhi",
                        "order": "3"
                    },
                    {
                        "image": "https://t12.baidu.com/it/u=3788697896,2880168169&fm=173&s=D31A38C4D664D55FC29281010300309B&w=218&h=146&img.JPEG",
                        "url": "http://finance.ifeng.com/a/20180120/15937975_0.shtml",
                        "title": "美国政府关门 比特币闻讯",
                        "id": "whyidzhi",
                        "order": "4"
                    },
                    {
                        "image": "https://t10.baidu.com/it/u=1499851317,895362806&fm=173&s=BD04DF104871339C53A88C870100E0E3&w=218&h=146&img.JPEG",
                        "url": "http://news.sina.com.cn/o/2018-01-20/doc-ifyquixe5136803.shtml",
                        "title": "刚刚,美国政府正式宣告",
                        "id": "whyidzhi",
                        "order": "5"
                    },
                    {
                        "image": "https://t12.baidu.com/it/u=4229963978,641890755&fm=173&s=74B218D646A08B491AAF3E9903001088&w=218&h=146&img.JPEG",
                        "url": "http://www.chinanews.com/gj/2018/01-20/8428898.shtml",
                        "title": "超三成受访者称中国是“新",
                        "id": "whyidzhi",
                        "order": "6"
                    }
                ]
            },
            {
                "modelname": "视频新闻",
                "data": [
                    {
                        "image": "http://pic.rmb.bdstatic.com/1f01839d477aa7a3ffa36f07542f8d5b.jpg@h_660,w_370",
                        "url": "http://v.qq.com/x/page/h0527p90e2b.html",
                        "title": "杭州餐馆爆炸,路过公交车20余人受伤",
                        "id": "whyidzhi",
                        "order": "1"
                    },
                    {
                        "image": "http://pic.rmb.bdstatic.com/1f541422405ab18797795c0adc3318eb.jpg@h_660,w_370",
                        "url": "http://www.iqiyi.com/v_19rr7omigs.html",
                        "title": "中央措辞严厉批祁连山生态问题 8责任人被问责",
                        "id": "whyidzhi",
                        "order": "2"
                    },
                    {
                        "image": "http://pic.rmb.bdstatic.com/d46f662c1900de051da6de2eef2c485f.jpg@h_660,w_370",
                        "url": "http://v.qq.com/x/page/a0024q7bkg0.html",
                        "title": "吉林永吉 吉林市多地遭暴雨袭击 县城灾后清理正在进行",
                        "id": "whyidzhi",
                        "order": "3"
                    },
                    {
                        "image": "http://pic.rmb.bdstatic.com/b9cdfca4adeb36ac1a0730f70b9d63f9.jpg@h_660,w_370",
                        "url": "http://www.iqiyi.com/v_19rr7oosfs.html",
                        "title": "40 高温下一出租车行驶中自燃",
                        "id": "whyidzhi",
                        "order": "4"
                    },
                    {
                        "image": "http://pic.rmb.bdstatic.com/660e5152b144e48bbdffdad5d9fdc088.jpg@h_660,w_370",
                        "url": "http://v.qq.com/x/page/v0527bhjwh3.html",
                        "title": "徐光裕:印度航母只是二流航母",
                        "id": "whyidzhi",
                        "order": "5"
                    }
                ]
            }
        ]
    }
    vlayout.txt

    2、因为Demo中使用到了banner和图片展现,所以还需要依赖banner和glide

    参考《BannerDemo【图片轮播图控件】》、《GlideNewDemo【Glide4.7.1版本的简单使用以及圆角功能】

    3、在布局文件声明Recyclerview控件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/vlayout_rv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none"
            android:clipToPadding="true"
            android:paddingLeft="0dp"
            android:paddingRight="0dp"
            android:requiresFadingEdge="none"/>
    
    </LinearLayout>

    4、在Acitivity中参考下面的代码编写基本框架(也就是逻辑处理)

    package com.why.project.vlayoutdemo;
    
    import android.content.Context;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.RecyclerView;
    import android.util.Log;
    import android.widget.Toast;
    
    import com.alibaba.android.vlayout.DelegateAdapter;
    import com.alibaba.android.vlayout.VirtualLayoutManager;
    import com.alibaba.android.vlayout.layout.GridLayoutHelper;
    import com.alibaba.android.vlayout.layout.LinearLayoutHelper;
    import com.alibaba.android.vlayout.layout.SingleLayoutHelper;
    import com.alibaba.android.vlayout.layout.StickyLayoutHelper;
    import com.why.project.vlayoutdemo.adapter.BannerLayoutAdapter;
    import com.why.project.vlayoutdemo.adapter.GridLayoutAdapter;
    import com.why.project.vlayoutdemo.adapter.HorizontalListLayoutAdapter;
    import com.why.project.vlayoutdemo.adapter.ListLayoutAdapter;
    import com.why.project.vlayoutdemo.adapter.StickyTitleAdapter;
    import com.why.project.vlayoutdemo.bean.ItemBean;
    import com.why.project.vlayoutdemo.bean.ModelBean;
    
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    import java.io.ByteArrayOutputStream;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
        private static final String TAG = MainActivity.class.getSimpleName();
    
        private List<ModelBean> mModelBeanList;//列表数据集合
    
        private RecyclerView mVLayoutRV;
    
        private VirtualLayoutManager layoutManager;
        private DelegateAdapter delegateAdapter;
        private List<DelegateAdapter.Adapter> adapters;
    
        private RecyclerView.RecycledViewPool viewPool;//设置复用池的大小
        private int itemType;//一个Adapter对应一个类型,这里通过自增加1实现唯一性
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            initViews();
            initDatas();
        }
    
        private void initViews() {
            mVLayoutRV = findViewById(R.id.vlayout_rv);
        }
    
        private void initDatas() {
            //初始化列表数据集合
            mModelBeanList = new ArrayList<ModelBean>();
            getTestDatas();
            Log.e(TAG,"mModelBeanList.size()=" + mModelBeanList.size());
    
    
            //初始化LayoutManager
            layoutManager = new VirtualLayoutManager(this);
            layoutManager.setRecycleOffset(300);
            mVLayoutRV.setLayoutManager(layoutManager);
    
            //设置回收复用池大小,(如果一屏内相同类型的 View 个数比较多,需要设置一个合适的大小,防止来回滚动时重新创建 View)
            //针对type=0的item设置了复用池的大小,如果你的页面有多种type,需要为每一种类型的分别调整复用池大小参数。
            viewPool = new RecyclerView.RecycledViewPool();
            mVLayoutRV.setRecycledViewPool(viewPool);
    
            //加载数据,通过创建adapter集合实现布局
            delegateAdapter = new DelegateAdapter(layoutManager, false);//必须使用false,实现每一个分组的类型不同
            mVLayoutRV.setAdapter(delegateAdapter);
    
            setVLayoutAdapter();
        }
    
        /**设置适配器*/
        private void setVLayoutAdapter() {
    
            itemType = 0;//自增加1
            if (adapters != null) {
                adapters.clear();
            } else {
                adapters = new LinkedList<>();
            }
    
            //根据类型不同,采用不同的adapter并添加到集合中
            for(int i=0; i<mModelBeanList.size(); i++){
                String modelName = mModelBeanList.get(i).getModelName();
                String type = mModelBeanList.get(i).getType();
                ArrayList<ItemBean> itemBeanArrayList = (ArrayList<ItemBean>) mModelBeanList.get(i).getItemDataList();
    
                boolean showModelName = true;//控制是否显示model,也就是吸顶布局
                if(showModelName){
                    //stikcy布局, 可以配置吸顶或者吸底
                    //设置各个区域的复用池的大小,因为只有一个元素,所以复用池大小就设置为1
                    viewPool.setMaxRecycledViews(itemType++, 1);
                    StickyLayoutHelper stickyLayoutHelper = new StickyLayoutHelper();
                    StickyTitleAdapter stickyTitleAdapter = new StickyTitleAdapter(this,stickyLayoutHelper,modelName);
                    adapters.add(stickyTitleAdapter);
                }
    
                //========用来判断分组,展现不同的样式========
                //每一个item对应一种样式
                switch(type) {
                    case "banner":
                        //通栏布局——轮播图
                        //设置各个区域的复用池的大小,设置子集合的总个数为复用池大小
                        viewPool.setMaxRecycledViews(itemType++, itemBeanArrayList.size());
                        SingleLayoutHelper singleLayoutHelper = new SingleLayoutHelper();//通栏布局,只会显示一个组件View
                        singleLayoutHelper.setMargin(0, 0, 0, dip2px(this, 10));//设置外边距,实现分割效果
                        BannerLayoutAdapter bannerLayoutAdapter = new BannerLayoutAdapter(this, singleLayoutHelper, itemBeanArrayList);
                        bannerLayoutAdapter.setBannerCallback(new BannerLayoutAdapter.BannerCallback() {
                            @Override
                            public void clickBanner(ItemBean itemBean) {
                                Toast.makeText(MainActivity.this,itemBean.getTitle(),Toast.LENGTH_SHORT).show();
                            }
                        });//设置自定义回调,用于点击事件监听
                        adapters.add(bannerLayoutAdapter);
                        break;
                    case "hori":
                        //通栏布局——横向列表
                        //设置各个区域的复用池的大小,设置子集合的总个数为复用池大小
                        viewPool.setMaxRecycledViews(itemType++, itemBeanArrayList.size());
                        SingleLayoutHelper horizontalListLayoutHelper = new SingleLayoutHelper();//不使用LinearLayoutHelper
                        horizontalListLayoutHelper.setMargin(0,0,0,dip2px(this, 10));//设置外边距,实现分割效果
                        HorizontalListLayoutAdapter horizontalListLayoutAdapter = new HorizontalListLayoutAdapter(this,horizontalListLayoutHelper,itemBeanArrayList);
                        horizontalListLayoutAdapter.setHorizontalListCallback(new HorizontalListLayoutAdapter.HorizontalListCallback() {
                            @Override
                            public void clickHorizontalItem(ItemBean itemBean) {
                                Toast.makeText(MainActivity.this,itemBean.getTitle(),Toast.LENGTH_SHORT).show();
                            }
                        });//设置自定义回调,用于点击事件监听
                        adapters.add(horizontalListLayoutAdapter);
                        break;
                    case "grid":
                        //九宫格布局
                        //设置各个区域的复用池的大小,设置子集合的总个数为复用池大小
                        viewPool.setMaxRecycledViews(itemType++, itemBeanArrayList.size());
                        GridLayoutHelper gridlayoutHelper = new GridLayoutHelper(2);//Grid布局, 支持横向的colspan
                        gridlayoutHelper.setAutoExpand(false);//解决单数的时候,最后一张居中显示的问题
                        gridlayoutHelper.setMargin(0, 0, 0, dip2px(this, 10));//设置外边距,实现分割效果
                        GridLayoutAdapter gridLayoutAdapter = new GridLayoutAdapter(this, gridlayoutHelper, itemBeanArrayList, itemBeanArrayList.size());
                        //设置自定义回调,用于点击事件监听
                        gridLayoutAdapter.setGridCallback(new GridLayoutAdapter.GridCallback() {
                            @Override
                            public void clickGrid(ItemBean itemBean) {
                                Toast.makeText(MainActivity.this,itemBean.getTitle(),Toast.LENGTH_SHORT).show();
                            }
                        });
                        adapters.add(gridLayoutAdapter);
                        break;
                    case "list":
                        //列表布局(默认布局)
                        //设置各个区域的复用池的大小,设置子集合的总个数为复用池大小
                        viewPool.setMaxRecycledViews(itemType++, itemBeanArrayList.size());
                        LinearLayoutHelper linearLayoutHelper = new LinearLayoutHelper();//线性布局
                        linearLayoutHelper.setMargin(0, 0, 0, dip2px(this, 10));//设置外边距,实现分割效果
                        ListLayoutAdapter listLayoutAdapter = new ListLayoutAdapter(this, linearLayoutHelper, itemBeanArrayList, itemBeanArrayList.size());
                        //设置自定义回调,用于点击事件监听
                        listLayoutAdapter.setListCallback(new ListLayoutAdapter.ListCallback() {
                            @Override
                            public void clickList(ItemBean itemBean) {
                                Toast.makeText(MainActivity.this,itemBean.getTitle(),Toast.LENGTH_SHORT).show();
                            }
                        });
                        adapters.add(listLayoutAdapter);
                        break;
                    default:
                }
    
            }
    
            delegateAdapter.setAdapters(adapters);
        }
    
        /**
         * dp转px
         * 16dp - 48px
         * 17dp - 51px*/
        public static int dip2px(Context context, float dpValue) {
            float scale = context.getResources().getDisplayMetrics().density;
            return (int)((dpValue * scale) + 0.5f);
        }
    
    
        /*=======================================获取测试数据==============================================*/
        private void getTestDatas(){
            String listdata = getStringFromAssert(MainActivity.this,"vlayout.txt");
            try {
                JSONObject listObj = new JSONObject(listdata);
                JSONArray listArray = listObj.getJSONArray("data");
                for(int i=0; i< listArray.length(); i++){
                    JSONObject itemObj = listArray.getJSONObject(i);
    
                    ModelBean modelBean = new ModelBean();
                    modelBean.setModelName(itemObj.getString("modelname"));
                    modelBean.setType(itemObj.getString("type"));
    
                    JSONArray childArray = itemObj.getJSONArray("data");
                    List<ItemBean> itemBeanList = new ArrayList<ItemBean>();
                    for(int j=0; j<childArray.length(); j++){
                        JSONObject childObj = childArray.getJSONObject(j);
    
                        ItemBean itemBean = new ItemBean();
                        itemBean.setId(childObj.getString("id"));
                        itemBean.setImageUrl(childObj.getString("image"));
                        itemBean.setOrder(childObj.getString("order"));
                        itemBean.setTitle(childObj.getString("title"));
                        itemBean.setUrlPath(childObj.getString("url"));
    
                        itemBeanList.add(itemBean);
                    }
    
                    modelBean.setItemDataList(itemBeanList);
    
                    mModelBeanList.add(modelBean);
                }
    
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 访问assets目录下的资源文件,获取文件中的字符串
         * @param assetsFilePath - 文件的相对路径,例如:"listitemdata.txt或者"/why/listdata.txt"
         * @return 内容字符串
         * */
        public static String getStringFromAssert(Context mContext, String assetsFilePath) {
    
            String content = ""; // 结果字符串
            try {
                InputStream is = mContext.getResources().getAssets().open(assetsFilePath);// 打开文件
                int ch = 0;
                ByteArrayOutputStream out = new ByteArrayOutputStream(); // 实现了一个输出流
                while ((ch = is.read()) != -1) {
                    out.write(ch); // 将指定的字节写入此 byte 数组输出流
                }
                byte[] buff = out.toByteArray();// 以 byte 数组的形式返回此输出流的当前内容
                out.close(); // 关闭流
                is.close(); // 关闭流
                content = new String(buff, "UTF-8"); // 设置字符串编码
            } catch (Exception e) {
                Toast.makeText(mContext, "对不起,没有找到指定文件!", Toast.LENGTH_SHORT)
                        .show();
            }
            return content;
        }
    
    }

    5、添加各种adapter和布局文件

    混淆配置

    #Vlayout
    -keepattributes InnerClasses
    -keep class com.alibaba.android.vlayout.ExposeLinearLayoutManagerEx { *; }
    -keep class android.support.v7.widget.RecyclerView$LayoutParams { *; }
    -keep class android.support.v7.widget.RecyclerView$ViewHolder { *; }
    -keep class android.support.v7.widget.ChildHelper { *; }
    -keep class android.support.v7.widget.ChildHelper$Bucket { *; }
    -keep class android.support.v7.widget.RecyclerView$LayoutManager { *; }

    参考资料

    alibaba/vlayout

    中文文档

    布局属性

    FAQ

    项目demo下载地址

    https://github.com/haiyuKing/VLayoutDemo

  • 相关阅读:
    积水路面Wet Road Materials 2.3
    门控时钟问题
    饮料机问题
    Codeforces Round #340 (Div. 2) E. XOR and Favorite Number (莫队)
    Educational Codeforces Round 82 (Rated for Div. 2)部分题解
    Educational Codeforces Round 86 (Rated for Div. 2)部分题解
    Grakn Forces 2020部分题解
    2020 年百度之星·程序设计大赛
    POJ Nearest Common Ancestors (RMQ+树上dfs序求LCA)
    算法竞赛进阶指南 聚会 (LCA)
  • 原文地址:https://www.cnblogs.com/whycxb/p/9748752.html
Copyright © 2011-2022 走看看