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

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

  •  
  •   3dwelcome · 14 天前 · 1774 次点击

    第一步,运行时动态下载 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   14 天前
    有具体的应用场景吗
    3dwelcome
        2
    3dwelcome   14 天前
    至于写个 UI,为什么不用 AndroidStudio 直接写,而要绕那么大一个圈子。

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

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

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

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

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

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

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

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

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

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

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

    而安卓不就是国内主流手机平台嘛。
    gam2046
        21
    gam2046   13 天前
    实际应用场景太局限了,相比之下,WebView 是成本更低的选择。
    zhanlanhuizhang
        22
    zhanlanhuizhang   11 天前   ❤️ 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   9 天前 via Android
    直接 aapt 编译后下发给客户端,几行代码拦截下 resources,就直接能和原生的 xml 一样用了
    F1ReKing
        24
    F1ReKing   7 天前
    compose 来了
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3381 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 08:11 · PVG 16:11 · LAX 01:11 · JFK 04:11
    ♥ Do have faith in what you're doing.