WeeX跨平台框架,自定义安卓平台MarkDown文本渲染组件高度跟随内容自适应实现思路探索

需求描述

应用要求能够加载markdown文本,以及常规html标签。

组件高度自适应问题

JS端只设置组件宽度,不设置组件高度,我们期待组件高度跟随内容调整,使得内容能够完全显示出来。 但是JS端组件不设置高度和原生组件不调用setContentBoxMeasurement方法,那么组件高度就是默认0,组件将无法显示。其次由于是富文本,常规使用

java 复制代码
setContentBoxMeasurement(new TextContentBoxMeasurement())

将出现内容显示不全被裁减的问题,因为TextContentBoxMeasurement是通过给TextPaint画笔设置字体大小和行高来测量文本显示的Layout。MarkDown中有很多格式转义符(标签、*号、#号)等,这些仅用于配置文本的样式,如果将它们也纳入普通文本通过TextContentBoxMeasurement测量,那么必然测量出来的高度是有问题,尤其是插入了图片、标题等。

解决思路

原生组件使用ScrollerView包裹TextView,这样即便ScrollerView和其父层容器高度为0,Text View将也可以自由伸展,等TextView渲染完成后,我们拿到最新的TextView高度,将高度数据返回通知JS端去重新设置组件高度,这样就解决了高度自适应问题。

java 复制代码
@Override
    protected FrameLayout initComponentHostView(@NonNull Context context) {
        // 外层侦布局
        FrameLayout layout = new FrameLayout(context);
        // 可滚动布局【用于让文本组件可自由伸展】
        ScrollView scrollView = new ScrollView(context);
        // 设置滚动布局高度撑满,即JS设置多高,它便有多高
        ViewGroup.LayoutParams params =
                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        scrollView.setLayoutParams(params);
        // 隐藏可滚动条,禁止滚动,拦截滚动事件
        scrollView.setVerticalScrollBarEnabled(false);
        scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER);
        scrollView.setOnTouchListener((v, event) -> true);
        // 创建文本显示组件
        this.mTextView = new TextView(context);
        ViewGroup.LayoutParams textParams =
                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        this.mTextView.setLayoutParams(textParams);
        // 添加文本组件布局变化监听
        this.mTextView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                int actualHeight = bottom - top;
                if (actualHeight > 0 && lastLayoutHeight != actualHeight) {
                    // fireEvent 通知Weex JS或者native,让上层刷新使用最新测量的实际高度
                    // JS端接收后,请重新设置高度
                    Map<String, Object> params = new HashMap<>();
                    params.put("height", WXViewUtils.getWebPxByWidth(actualHeight));
                    fireEvent("onRealHeight", params);
                }
            }
        });
        scrollView.addView(this.mTextView);
        layout.addView(scrollView);
        return layout;
    }

JS端:

html 复制代码
<Markdown
  class="richtext"
  :style="{height: maxValue || 'auto'}"
  :content="content"
  @onRealHeight="handleOnRealHeight"
/>
css 复制代码
.richtext {
  font-size: 26px;
  color: #666666;
  line-height: 40px;
}
javascript 复制代码
handleOnRealHeight (params) {
  const newHeight = params.height
  if (newHeight > this.maxValue) {
    this.maxValue = newHeight
  }
}
相关推荐
千里马学框架4 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone4 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo4 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077004 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼4 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone4 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen4 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone4 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui