看啥推荐读物
专栏名称: 曦瞳
2020届 求实习岗位 三院科协成员
目录
相关文章推荐
今天看啥  ›  专栏  ›  曦瞳

Android技术栈(六)开源:让你用上大厂的首页动态业务容器

曦瞳  · 掘金  ·  · 2019-11-04 12:08
阅读 0

Android技术栈(六)开源:让你用上大厂的首页动态业务容器

1 我们要解决什么问题?

在线上对于某些适用于要求强展示、轻交互、随时上线场景,RN和WebView显得不够灵活,性能表现也不够好。例如首页feed流卡片,一级页面的活动页等,这些页面也往往只是需要局部动态化。

对于这些情况,美团APP团队有自己的一套闭源的动态化容器MTFlexbox来应对这些情况,让布局快速开发上线,之前在美团实习期间有幸学习过MTFlexbox,这里我要感谢一下美团APP终端业务研发组的同学们,感谢我的Leader,没有他们的帮助就没有现在的我。

在实习结束返校之后,一直想个自己的实习做一个学习总结,但又不知道以什么为主题比较合适。自己对MTFlexbox理解得以及其适用的业务特点理解的还算深刻,所以最终我选择了尝试自己去设计实现一个与MTFlexbox功能类似的开源框架Gbox。

Gbox使用apache开源协议,不使用MTFlexbox的任何源代码,也不是MTFlexbox的兼容版本,它是一个完全基于开源软件实现的全新开源软件,并且Gbox使用kotlin编码。

Gbox花了自己很多心血,从设计到技术选型再到编码完成,花了我大半个月的时间,踩了好多litho、Drawable、Canvas的坑之后,现在Gbox已经基本可用了(从版本号0.1.1开始)。

2 实现效果

Gbox有丰富的样式能力,能够实现圆角、高斯模糊、渐变色、文本、网络图片的绘制,并且得益于facebook开源的litho,绝大部分工作可以在异步线程进行,大大减轻了主线程的负担。

同时,得益于强大的apache el(使用在嵌入式tomcat上的版本),使得Gbox样式模板xml中的所有属性均支持表达式解析,包括函数调用、算数运算、三元表达式、java bean访问,同时Gbox还支持for语句。

1.1 对比截图

对比美团首页线上方案MTFlexbox,左为MTFlexbox(美团APP),右为Gbox(Gbox的实时预览APP)。

1.2 样式数据

<?xml version="1.0" encoding="utf-8"?>
<Flex
    background="WHITE"
    borderRadius="12"
    flexDirection="column"
    width="300">
    <Flex
        alignItems="center"
        marginLeft="10"
        marginTop="12"
        flexDirection="row">
        <Text
            textStyle="bold"
            textSize="16"
            text="碧蓝航线电子科大店">
        </Text>
        <Text
            marginTop="2"
            paddingLeft="4"
            paddingRight="4"
            background="${draw:gradient(l2r,'#EE9611','#F7C709')}"
            borderRadius="3"
            marginLeft="12"
            text="外卖"
            textSize="10"/>
    </Flex>
    <Flex
        marginLeft="10"
        marginTop="5"
        flexDirection="row">
        <Text
            textColor="#E6941A"
            textSize="11"
            text="4.1分">
        </Text>
        <Text
            textColor="#808080"
            textSize="11"
            text=" | 月售929">
        </Text>
        <Text
            textColor="#808080"
            textSize="11"
            text=" | 配送¥0">
        </Text>
        <Flex
            flexGrow="1">
        </Flex>
        <Text
            textColor="#808080"
            marginLeft="10"
            marginRight="10"
            textSize="11"
            text="31分钟送达">
        </Text>
    </Flex>
    <Flex
        alignItems="center"
        marginLeft="10"
        marginTop="5">
        <Text
            borderRadius="3"
            paddingLeft="4"
            paddingRight="4"
            textSize="10"
            background="${draw:gradient(l2r,'#F70909','#FF6600')}"
            textColor="WHITE"
            text="优惠">
        </Text>
        <Text
            textColor="#808080"
            marginLeft="5"
            textSize="12"
            text="首单减12">
        </Text>
    </Flex>
    <Flex
        height="100"
        flexGrow="1"
        marginBottom="10"
        marginLeft="7"
        marginRight="7"
        marginTop="8"
        flexDirection="row">
        <Flex
            flexDirection="column"
            justifyContent="center"
            marginLeft="3"
            marginRight="3"
            flexGrow="1">
            <Image
                borderRadius="4"
                scaleType="fitXY"
                flexGrow="1"
                url="${image2}">
            </Image>
            <Text
                marginTop="5"
                textAlign="center"
                textSize="11"
                text="拉菲">
            </Text>
        </Flex>
        <Flex
            flexDirection="column"
            justifyContent="center"
            marginLeft="3"
            marginRight="3"
            flexGrow="1">
            <Image
                borderRadius="4"
                scaleType="fitXY"
                flexGrow="1"
                url="${image1}">
            </Image>
            <Text
                marginTop="5"
                textAlign="center"
                textSize="11"
                text="初音未来">
            </Text>
        </Flex>
        <Flex
            flexDirection="column"
            justifyContent="center"
            marginLeft="3"
            marginRight="3"
            flexGrow="1">
            <Image
                blurSampling="3"
                blurRadius="25"
                borderRadius="4"
                scaleType="fitXY"
                flexGrow="1"
                url="${image2}">
            </Image>
            <Text
                marginTop="5"
                textAlign="center"
                textSize="11"
                text="高斯模糊">
            </Text>
        </Flex>
    </Flex>
</Flex>
复制代码

1.3 数据

{
	"image1": "https://uploadfile.bizhizu.cn/2014/1127/20141127031018144.jpg",
	"isEmpty": 1,
	"name": "tttt",
	"bofang": "100万",
	"bofangSize": 10,
	"danmu": "10万",
	"gengduo": "https://s2.ax1x.com/2019/10/11/uqo5tJ.png",
	"image2": "http://5b0988e595225.cdn.sohucs.com/images/20180606/0a49d21848324503a1e04c4b942a1631.png"
}
复制代码

3 Gbox的特性

Gbox是对业务以及性能友好的

  • 它基于facebook开源的litho,异步计算布局,解放主线程,并且直接使用Drawable进行渲染,消除View层级,与WebView相比有更大的性能优势
  • 使用Glide作为图片加载引擎,所有图片均可以从网络异步加载,异步图片的加载不会触发litho的视图树的状态更新
  • 前后端分离,后端下发布局+数据的json,可集成在数据接口下发,本地自主解析渲染布局
  • 单View接入,基本无入侵性,可用于替换现有的任意一个静态展示型的View,并支持曝光埋点、点击埋点、点击时间处理等事件
  • 提供完整的开发工具链,包括布局实时预览APP(overview),以及mock工具,可通过扫码链接电脑进行实时预览调试
  • 基于flexbox布局模型,并且包含丰富的可配置样式,边框,边框颜色,圆角,图片,文本等
  • 强大的表达式解析功能,包括数学运算,for语句,三元表达式,简单的java方法调用,使用表达式时需使用'${}'包围
  • 布局自适应,布局使用的单位为是设备独立的pt,以设备屏幕宽度为准,1pt=(设备屏幕宽度像素值/360)像素
  • 使用kotlin编码,代码实现非常简洁,很适合阅读学习
  • 支持原生View嵌入Gbox

4 丰富的样式支持

4.1 通用样式

布局支持多种样式,但有一些样式是通用的

  • background 可以是颜色以#开头或是颜色的名字,或者为url,还可以使用渐变色,调用内置函数“fn:gradient”实现渐变色,最后一个参数是可变参数,如下:
<?xml version="1.0" encoding="utf-8"?>
<Flex
    width="360"
    height="600"
    borderWidth="20"
    borderRadius="30"
    borderColor="red"
    background="${fn:gradient(t2b,red,blue)}">
</Flex>
复制代码
  • borderRadius 圆角弧度
  • borderWidth 边框宽度
  • borderColor 边框颜色
  • alignSelf 支持flexStart,flexEnd,center,baseline,stretch
  • height 高
  • width 宽
  • margin 外边距
  • marginBottom 外边距
  • marginTop 外边距
  • marginLeft 外边距
  • marginRight 外边距
  • padding 内边距
  • paddingTop 内边距
  • paddingBottom 内边距
  • paddingLeft 内边距
  • paddingRight 内边距
  • clickUrl 一个url,可触发EventListener的回调
  • reportClick 点击时上报一个json,此json支持数据绑定,可触发EventListener的回调
  • reportView 曝光时上报一个json,此json支持数据绑定,可触发EventListener的回调

4.2 Image

使用Glide作为图片加载引擎,支持异步加载、高斯模糊(使用高效的renderscript)、圆角裁剪

  • url 图片来源,一个url
  • blurRadius 高斯模糊的半径,最大为25
  • blurSampling 高斯模糊的采样率,默认为1
  • borderRadius 有圆角弧度时,会裁剪内部
  • scaleType 缩放类型,有center,fltXY,fitCenter,fitStart,fitEnd,centerInside

4.3 Text

用于显示文本

  • text 显示文本
  • textAlign 文本对齐,支持center,left,right
  • textSize 文本大小
  • textStyle 文本风格,支持normal,bold
  • maxLines 最大行数
  • minLines 最小行数
  • textColor 字体颜色

4.4 Flex

flex风格的布局容器

  • flexDirection 支持row,rowReverse,column,columnReverse
  • flexWrap 容器是否包住内部,支持noWrap,wrap,wrapReverse
  • justifyContent 主轴对齐,支持flexStart,flexEnd,center,spaceBetween,spaceAround
  • alignItems 副轴对齐,支持flexStart,flexEnd,center,baseline,stretch
  • alignContent 支持flexStart,flexEnd,center,baseline,stretch

4.5 Scroller

滑动列表实现,与ScrollerView等价

  • scrollBarEnable 启用或关闭scrollBar
  • orientation 水平或者垂直(vertical,horizontal)

4.6 Frame

与FrameLayout类似,可实现多层级叠加

4.7 Embedded

可在布局中嵌入传统View

  • type 类名

4.8 for

逻辑标签,将内部的标签展开成多组,三个字段都是必填的

  • name 循环中所使用的迭代变量
  • from 开始的下标
  • to 结束的下标
<?xml version="1.0" encoding="utf-8"?>
<Flex
  height="${height}" >
  <for name="index" from="1" to="3">
    <Text
      text="${itemTexts[index]}"
      height="100">
    </Text>
  </for>
</Flex>
复制代码

等价展开

<?xml version="1.0" encoding="utf-8"?>
<Flex
  height="${height}" >
    <Text
      text="${itemTexts[1]}"
      height="100">
    </Text>
    <Text
      text="${itemTexts[2]}"
      height="100">
    </Text>
    <Text
      text="${itemTexts[3]}"
      height="100">
    </Text>
</Flex>
复制代码

4.8 辅助函数

可以在表达式中调用

  • utils:check(o:Any)可以检擦一个变量是否有效,为空或者大小为0的集合或者为空的字符串都会返回false值
  • draw:gradient(o:Orientation,vararg colors: String) 用于实现渐变色,第一个参数为渐变色的方向,有t2b,tr2bl,l2r,br2tl,b2t,r2l,tl2br八种方向可选,第二个参数是可变参,可传入若干个颜色的字符串

5 运行测试用例

  • 在手机上安装overview
  • 确保手机与电脑在同一网络环境下
  • 运行mock模块下test文件夹下的MockTestCase(mac上路径可能会出点问题)
  • 用overview扫描控制台出现的二维码,即可开始测试
  • Ctrl+S保存后会刷新手机上的布局(开启LiveReload时)
  • 您可参照mock模块与overview模块进行快速集成

6 获取Gbox

6.1 在github上clone源码

Gbox的github仓库地址

6.2 利用jitpack集成

//Add it in your root build.gradle at the end of repositories:
	allprojects {
		repositories {
			...
			maven { url 'https://jitpack.io' }
		}
	}
 
//Add the dependency
    dependencies {
	        implementation 'com.github.LukeXeon.flexbox:core:Tag'
	}
复制代码

7 项目中所使用的开源框架

7.1 mock

  • google zxing 二维码
  • google gson json解析

7.2 core

  • apache el 数据绑定
  • facebook litho 渲染

7.3 overview

  • squareup retrofit2 网络请求
  • didi DoraemonKit 辅助工具

8 结语

iOS侧和更多功能已经在开发计划中,敬请关注,也欢迎你来贡献,我们将一起开源共建,做出最好的Gbox。

最后的最后还是惯例啦,如果喜欢我的文章别忘了给我点个赞,拜托了这对我来说真的很重要。如果你觉得东西对你有用GitHub也帮点个star吧。




原文地址:访问原文地址
快照地址: 访问文章快照