原生视图嵌入 LynxView

LynxView 本身就是一个客户端视图,轻易的可以作为全屏大小的视图使用,也可以被嵌入一个非全屏的客户端视图中。

LynxView 对应是 Page 元件,只允许客户端对 LynxView 设置大小限制,你一般不能直接修改 Page 的样式来设置其大小。

客户端可以给 LynxView 设置不同的大小约束,也就是给 Page 设置大小约束,Lynx 排版引擎使用这些约束来计算 Page 节点以及所有子节点的大小位置信息。

约束 LynxView 的大小

约束模式

iOS 上需要再创建 LynxView 时,主动设置 LynxView 的大小约束。

有两个方式来给 Lynxview 设置大小约束:

  • 通过 updateViewportWithPreferredLayoutWidth 并配合 setLayoutWidthMode、setLayoutHeightMode 来设置固定或者弹性大小
  • 通过 lynxviewbuilder#frame 来设置固定大小

支持的约束模式:

typedef NS_ENUM(NSInteger, LynxViewSizeMode) {
  LynxViewSizeModeUndefined = 0,
  LynxViewSizeModeExact,
  LynxViewSizeModeMax
};
  • LynxViewSizeModeUndefined

    LynxView 的宽或高完全由其 Page 的内容决定,父容器不给任何约束。

  • LynxViewSizeModeExact

    LynxView 的宽或高为指定的固定值,即 Page 节点的大小固定。

  • LynxViewSizeModeMax

    LynxView 的宽或高的最大值,即 Page 节点大小的最大值。

onMeasure 里得到大小约束

Android 系统有给视图提供 onMeasure 周期,在这个阶段可以得到外层视图给 LynxView 的大小约束,Lynx 会在系统的 onMeasure 函数内完成所有节点的排版,并计算出 LynxView 的大小,以便通过 setMeasuredDimension 设置正确的值。

具体的 View.MeasureSpec 如下:

  • UNSPECIFIED

    LynxView 的宽或高完全由其 Page 的内容决定,父容器不给任何约束。

  • EXACTLY

    LynxView 的宽或高为指定的固定值,即 Page 节点的大小固定。

  • AT_MOST

    LynxView 的宽或高的最大值,即 Page 节点大小的最大值。

在页面的内容需要重新排版时,Lynx 通过调用系统的 requestLayout,触发 onMeasure 重新执行。

预设宽高,提前触发排版

你也可以在创建 LynxView 时,预设通过 LynxViewBuilder#setPresetMeasuredSpec 来预设给 LynxView 的大小约束,参数与 onMeasure 一致。这样可以在渲染周期内就触发排版,而不用等到 onMeasure 的执行。 当检测到 measureSpec 变化后,仍然会重新触发排版,保证 LynxView 的大小是正确的。

比如,通过下面的代码可以预设一个固定 400*200 大小:

LynxViewBuilder viewBuilder = new LynxViewBuilder();
viewBuilder = viewBuilder.setPresetMeasuredSpec(View.MeasureSpec.makeMeasureSpec(400, View.MeasureSpec.EXACTLY),
        View.MeasureSpec.makeMeasureSpec(200, View.MeasureSpec.EXACTLY));

LynxView lynxview = viewBuilder.build(this);;

LynxView 为固定大小

使用LynxViewBuilder#frame 属性

可以在创建 LynxView 的时候,设置 frame 属性大小,这样 LynxView 的大小就是固定的。

比如,你想限制 LynxView 的大小为固定的 400*200,可以按照如下方式:

   LynxView *lynxView = [[LynxView alloc] initWithBuilderBlock:^(LynxViewBuilder *builder) {
       builder.frame =  CGRectMake(0, 0, 400, 200);
         ...
    }];

使用preferredLayoutWidth/preferredLayoutHeightlayoutWidthMode/layoutHeightMode

参考如下代码:

_lynxView.layoutWidthMode = LynxViewSizeModeExact;
_lynxView.layoutHeightMode = LynxViewSizeModeExact;

_lynxView.preferredLayoutWidth = 400;
_lynxView.preferredLayoutHeight = 200;

只要外层容器给 LynxView 的约束是 EXACTLY,那么 LynxView 的大小就是固定的。

比如你想设置 400*200 大小的 LynxView:

//可以直接指定LynxView的大小
parentView.addView(lynxview, new ViewGroup.LayoutParams(400, 200));

//也可以固定父节点的大小,设置 MATCH_PARENT 模式
parentView.addView(lynxview,
   new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));

LynxView 根据内容自适应

如果你想让 LynxView 根据其内容自适应大小,可以不设置 LynxViewBuilder#frame,或通过 setLayoutWidth/HeightMode 设置 LynxViewSizeModeUndefinedLynxViewSizeModeMax 即可。

_lynxView.layoutWidthMode = LynxViewSizeModeUndefined;
_lynxView.layoutHeightMode = LynxViewSizeModeUndefined;

//或者,限制最大的宽度为400,最大高度为750
_lynxView.preferredLayoutWidth = 400;
_lynxView.preferredLayoutHeight = 750;
_lynxView.layoutWidthMode = LynxViewSizeModeMax;
_lynxView.layoutHeightMode = LynxViewSizeModeMax;

这里跟 Android 普通视图的排版约束是一致,比如给 LynxView 的设置排版参数是 WRAP_CONTENT,即可让 LynxView 的大小根据内容自适应:

parentView.addView(lynxview,
    new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT));

除非另有说明,本项目采用知识共享署名 4.0 国际许可协议进行许可,代码示例采用 Apache License 2.0 许可协议进行许可。