V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
3dwelcome
V2EX  ›  Android

安卓开发小技巧,教你们如何用文本 XML 动态生成界面。

  •  
  •   3dwelcome · 8 天前 · 1692 次点击

    第一步,运行时动态下载 Layout XML 文件,用 binxml 之类的工具函数,转换成 Byte[]类型的二进制 XML (模仿 AndroidStudio 的资源编译流程)

    第二步,把每个按钮的资源 ID 包名赋值一下,因为动态载入 Layout 的 JAVA 函数,会自动去 resources.arsc 资源列表查找对应的 ID,而按钮是动态生成的,根本就没有 ID,需要随便分配一个,只要当前 View 内不重复即可。

    第三步,用 LayoutInflater.inflate 和老外写的 XmlBlock 内部资源解析函数,正式加载二进制 XML 界面,转换成 View 组件。( https://github.com/liudongmiao/preference-fragment-compat/blob/master/src/me/piebridge/android/preference/PreferenceFragment.java#L235 )

    第四步,用 findViewById 查找按钮的 view, 用 setOnClickListener 设置响应事件,setContentView 显示出来,搞定收工。

    24 条回复    2021-07-28 09:34:42 +08:00
    JellyBeanX
        1
    JellyBeanX   8 天前
    有具体的应用场景吗
    3dwelcome
        2
    3dwelcome   8 天前
    至于写个 UI,为什么不用 AndroidStudio 直接写,而要绕那么大一个圈子。

    是因为现在主流开发模式,都是同一套代码去适配各种平台,不可能为了安卓单独写一整套界面和逻辑,而是添加中间转换层。

    比如把跨平台的<div><span>Hello World</span></div>,转换成安卓的<TextView>和<Button>,基于文本 XML 相互转换,要比代码之间的转换方便很多。
    3dwelcome
        3
    3dwelcome   8 天前
    @JellyBeanX “有具体的应用场景吗”

    用纯代码创建界面太抽象,而用 AndroidStudio 界面编辑器又定的太死,每次都要编译后才能使用。

    这方法也算取个中间值,兼顾了 XML 可阅读性和运行期生成界面。
    john6lq
        4
    john6lq   8 天前 via iPhone
    直接用 webview 不是更好?你这玩意前端不会写,移动端不想写,出问题也不知道找谁。
    des
        5
    des   8 天前 via iPhone
    @john6lq 确实,webview 多好用
    3dwelcome
        6
    3dwelcome   8 天前
    @john6lq 用 webview 也太简单粗暴了,很多悬浮层效果不太好弄。同事说,你们开发出来的安卓软件,界面怎么像 PC 软件,套皮 Webview 还是差那么一点感觉。

    前端不用写原始 XML,只要写 HTML 就行了。工具主要用途还是中间层适配,自动转换 HTML->XML,尽可能把 Android 的 XML 界面格式黑盒化。

    稳定性也不用担心,解析 XML 生成 UI 那套核心代码,还是调用安卓自己内部的。外围只是模拟资源预编译流程,负责喂安卓 XML 数据,不太容易出问题。
    yukiww233
        7
    yukiww233   8 天前
    槽点太多, 首先难点就是 html->xml 转换过程中布局层级 /相对约束; 要是真有完美转换的技术, 那直接拿对应的设计稿来生成不同平台的布局文件不是更好?
    另外 ui 用 html->xml,然后操作 ui 的代码还是用原生 java/kotlin 写? 反正我是不知道怎么操作一个代码自动生成的黑箱 xml, 比如隐藏掉一个 view 之后其他控件会跑到什么位置

    另外, 楼主之前没用过 weex/rn 之类的技术么
    pipilu
        8
    pipilu   8 天前
    不错,在现在的 V2 算是硬核了,就是反射调用系统接口,兼容性不一定行吧
    fredli
        9
    fredli   8 天前
    不重要了,jetpack compose 来了
    whyrookie
        10
    whyrookie   8 天前
    Jetpack compose 起来,xml 都不要了
    3dwelcome
        11
    3dwelcome   8 天前
    @yukiww233 就相对简单的 UI 约束而言(对父级的上下左右约束),问题不大的,以前我还专门开过帖子,讨论过 UI 约束布局问题 /t/779153

    你说控制响应的代码,我是全部反射到别的语言来处理。安卓可以通过 webview 调用 JS,也可以调用 C++,这两个语言最适合写跨平台的业务逻辑,网上现成的 runtime 库也不少。

    我其实没搞懂,官方为什么不提供文本 XML 生成界面的函数,又不是每个项目界面都能写死在 apk 里的。
    wjploop
        12
    wjploop   8 天前
    动态加载页面的同时,逻辑代码不需要动态调整了吗?这方面的需求可以用插件化实现吧。
    gtanyin
        13
    gtanyin   8 天前
    HTML->XML ? React Native 表示,写好了给我抄一下!
    araraloren
        14
    araraloren   8 天前
    XML 有啥可读性??
    ParfoisMeng
        15
    ParfoisMeng   8 天前
    喵喵喵???
    zhanlanhuizhang
        16
    zhanlanhuizhang   8 天前
    zhanlanhuizhang
        17
    zhanlanhuizhang   8 天前
    还有一个用 json,生成界面的。但那个需要预先定制。
    3dwelcome
        18
    3dwelcome   8 天前
    @zhanlanhuizhang 这项目怎么感觉有点不靠谱,现在 android api 发展那么快,连个弹性布局都不支持,没法用啊。

    而且 RapidView 写法比较土,既然想用 lua 封装一层,那就不要手写去 Wrap API,直接遍历 java 对象属性和函数多好。
    cjh1095358798
        19
    cjh1095358798   7 天前
    没什么大用,android 都要凉了,整这些有毛用
    3dwelcome
        20
    3dwelcome   7 天前
    @cjh1095358798 对程序员不凉啊,手机市场安卓占比那么多的。

    日常总有随手开发一个给自己用小工具的需求。以前是电脑上发布,现在发布就是手机和平板。

    而安卓不就是国内主流手机平台嘛。
    gam2046
        21
    gam2046   7 天前
    实际应用场景太局限了,相比之下,WebView 是成本更低的选择。
    zhanlanhuizhang
        22
    zhanlanhuizhang   6 天前   ❤️ 1
    现在走这条路的最好的应该是美团吧: https://tech.meituan.com/2019/08/15/mtflexbox-automation-buried-point-exploration.html https://tech.meituan.com/2019/09/19/litho-practice-in-dynamic-program-mtflexbox.html
    就是我昨天说过的用通过下发 json 。里面包含三端统一的 xml 文件。但是现在美团都转向 react,和 Flutter 。主要原因就是:截取美团自我评价( MTFlexbox 基本上支持 Native 上常用的基础控件的展示,对有 UI 定制化的需求支持度很高。但 MTFlexbox 的 XML 布局需要在运行前编写完成,只支持简单的三元表达式,逻辑能力有限。因此,MTFlexbox 特别适合布局样式复杂、变动频繁但交互简单的业务场景。例如美团 App 首页、搜索结果页等。这些业务场景都具备以下两个特点:

    面向多业务方:各业务方有自己的个性化丰富样式,且不同时期可能需要不同的样式。

    交互简单:点击跳转完成流量输送的简单交互。)
    hyb1996
        23
    hyb1996   4 天前 via Android
    直接 aapt 编译后下发给客户端,几行代码拦截下 resources,就直接能和原生的 xml 一样用了
    F1ReKing
        24
    F1ReKing   1 天前
    compose 来了
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1978 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 15:47 · PVG 23:47 · LAX 08:47 · JFK 11:47
    ♥ Do have faith in what you're doing.