当前位置:   article > 正文

全网首发:鸿蒙开源第三方组件,跨平台自适应布局yoga组件_yoga布局引擎

yoga布局引擎

Yoga 是 Facebook 打造的一个跨 iOS、Android、Window 平台在内的布局引擎,兼容 Flexbox 布局方式,让界面更加简单。

01如何使用

首先我们在 MainAbility 中定义界面路由:

  1. public class MainAbility extends Ability {
  2.     @Override
  3.     public void onStart(Intent intent) {
  4.         super.onStart(intent);
  5.         super.setMainRoute(MainAbilitySlice.class.getName());
  6.         addActionRoute("action.dydrawnode.slice", DynamicsDrawNodeSlice.class.getName());
  7.         addActionRoute("action.showrow.slice", ShowRowAbilitySlice.class.getName());
  8.         addActionRoute("action.inflate.slice", BenchmarkInflateAbilitySlice.class.getName());
  9.     }
  10. }

然后我们来到 MainAbilitySlice,其实就是做了一个向其他界面跳转的动作,并提前加载 yoga 的 so 库:

  1. public class MainAbilitySlice extends AbilitySlice {
  2.     static {
  3.         System.loadLibrary("yoga");
  4.         System.loadLibrary("yogacore");
  5.         System.loadLibrary("fb");
  6.     }
  7.     @Override
  8.     public void onStart(Intent intent) {
  9.         super.onStart(intent);
  10.         setUIContent(ResourceTable.Layout_main_layout);
  11.         Button btn0= (Button) findComponentById(ResourceTable.Id_btn_1);
  12.         btn0.setClickedListener(component -> {
  13.             Intent intent1 = new Intent();
  14.             Operation operation = new Intent.OperationBuilder()
  15.                     .withAction("action.dydrawnode.slice")
  16.                     .build();
  17.             intent1.setOperation(operation);
  18.             startAbilityForResult(intent11);
  19.         });
  20.         Button btn2= (Button) findComponentById(ResourceTable.Id_btn_2);
  21.         btn2.setClickedListener(component -> {
  22.             Intent intent1 = new Intent();
  23.             Operation operation = new Intent.OperationBuilder()
  24.                     .withAction("action.showrow.slice")
  25.                     .build();
  26.             intent1.setOperation(operation);
  27.             startAbilityForResult(intent11);
  28.         });
  29.         Button btn1= (Button) findComponentById(ResourceTable.Id_btn_3);
  30.         btn1.setClickedListener(component -> {
  31.             Intent intent1 = new Intent();
  32.             Operation operation = new Intent.OperationBuilder()
  33.                     .withAction("action.inflate.slice")
  34.                     .build();
  35.             intent1.setOperation(operation);
  36.             startAbilityForResult(intent11);
  37.         });
  38.     }
  39.     @Override
  40.     public void onActive() {
  41.         super.onActive();
  42.     }
  43.     @Override
  44.     public void onForeground(Intent intent) {
  45.         super.onForeground(intent);
  46.     }
  47. }

第一个演示界面

这里 yoga 向我们展示了动态布局的能力,效果图如下:

图片

实现的代码如下:

  1. public class DynamicsDrawNodeSlice extends AbilitySlice {
  2.     private static final int VIEW_WIDTH = 200;
  3.     private static final int VIEW_HEIGHT = 200;
  4.     private ArrayList<Component> mViewList = new ArrayList<>();
  5.     private ArrayList<YogaNode> mYogaNodeList = new ArrayList<>();
  6.     private int[][] colors = new int[][]{
  7.             new int[]{0xff6200ea, 0xff651fff, 0xff7c4dff, 0xffb388ff},
  8.             new int[]{0xffd500000xffff17440xffff52520xffff8a80},
  9.             new int[]{0xffc511620xfff500570xffff40810xffff80ab},
  10.             new int[]{0xffaa00ff, 0xffd500f90xffe040fb, 0xffea80fc}
  11.     };
  12.     @Override
  13.     protected void onStart(Intent intent) {
  14.         super.onStart(intent);
  15.         PositionLayout container = new PositionLayout(this);
  16.         DisplayAttributes displayAttributes = DisplayManager.getInstance().getDefaultDisplay(this).get().getAttributes();
  17.         float screenWidth = displayAttributes.width;
  18.         float screenHeight = displayAttributes.height;
  19.         YogaNode root = new YogaNodeJNIFinalizer();
  20.         root.setWidth(screenWidth);
  21.         root.setHeight(screenHeight);
  22.         root.setFlexDirection(YogaFlexDirection.COLUMN);
  23.         createRowNodeAndView(root, 0);
  24.         createRowNodeAndView(root, 1);
  25.         createRowNodeAndView(root, 2);
  26.         createRowNodeAndView(root, 3);
  27.         root.calculateLayout(screenWidth, screenHeight);
  28.         for (int i = 0; i < mViewList.size(); i++) {
  29.             Component component = mViewList.get(i);
  30.             YogaNode yogaNode = mYogaNodeList.get(i);
  31.             YogaNode yogaNodeOwner = yogaNode.getOwner();
  32.             component.setTranslationX(yogaNodeOwner.getLayoutX() + yogaNodeOwner.getLayoutX());
  33.             component.setTranslationY(yogaNodeOwner.getLayoutY() + yogaNodeOwner.getLayoutY());
  34.             component.setLeft((int) (yogaNodeOwner.getLayoutX() + yogaNode.getLayoutX()));
  35.             component.setTop((int) (yogaNodeOwner.getLayoutY() + yogaNode.getLayoutY()));
  36.             container.addComponent(component);
  37.         }
  38.         super.setUIContent(container);
  39.     }
  40.     private void createRowNodeAndView(YogaNode root, int index) {
  41.         YogaNode row = new YogaNodeJNIFinalizer();
  42.         row.setHeight(VIEW_HEIGHT);
  43.         row.setWidth(VIEW_WIDTH * 4);
  44.         row.setFlexDirection(YogaFlexDirection.ROW);
  45.         row.setMargin(YogaEdge.ALL20);
  46.         for (int i = 0; i < 4; i++) {
  47.             YogaNode yogaNode = new YogaNodeJNIFinalizer();
  48.             yogaNode.setWidth(VIEW_WIDTH);
  49.             yogaNode.setHeight(VIEW_HEIGHT);
  50.             Component component = createView(colors[index][i]);
  51.             row.addChildAt(yogaNode, i);
  52.             mYogaNodeList.add(yogaNode);
  53.             mViewList.add(component);
  54.         }
  55.         root.addChildAt(row, index);
  56.     }
  57.     private Component createView(int color) {
  58.         Component view = new Component(this);
  59.         ShapeElement background = new ShapeElement();
  60.         background.setRgbColor(convertColor(color));
  61.         view.setBackground(background);
  62.         ComponentContainer.LayoutConfig layoutConfig = new AdaptiveBoxLayout.LayoutConfig(VIEW_WIDTH, VIEW_HEIGHT);
  63.         view.setLayoutConfig(layoutConfig);
  64.         return view;
  65.     }
  66.     /**
  67.      *  转换颜色
  68.      * @param color
  69.      * @return RgbColor
  70.      */
  71.     public RgbColor convertColor(int color) {
  72.         int colorInt = color;
  73.         int red = (colorInt & 0xff0000>> 16;
  74.         int green = (colorInt & 0x00ff00>> 8;
  75.         int blue = (colorInt & 0x0000ff);
  76.         return new RgbColor(red, green, blue);
  77.     }
  78. }

代码中定义了一个 root 根布局,宽高为屏幕的宽高,接着定义了四个行布局,并向每个行布局里添加 4 个子布局。

最重要的是在调用 root.calculateLayout(screenWidth, screenHeight)后,便将每个子布局的位置给确定了下来,然后根据获取到的每个布局的参数,给每个 Component 设置位置。

该演示只是借助 yoga 组件来确定每个 Component 位置,真正使渲染生效的还是基于鸿蒙的原生控件。

第二个演示界面

接下来展示如何使用 yoga 组件在 xml 里通过填写属性来控制 item 位置的能力,效果图如下:

图片

代码如下:

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <com.facebook.yoga.openharmony.YogaLayout
  3.        xmlns:ohos="http://schemas.huawei.com/res/ohos"
  4.        xmlns:yoga="http://schemas.huawei.com/apk/res-auto"
  5.        ohos:height="match_parent"
  6.        ohos:width="match_parent"
  7. >
  8.    <com.facebook.yoga.openharmony.YogaLayout
  9.            ohos:height="60vp"
  10.            ohos:width="match_content"
  11.            yoga:yg_alignItems="center"
  12.            yoga:yg_flexDirection="row"
  13.            yoga:yg_marginHorizontal="15"
  14.            yoga:yg_marginStart="15"
  15.            yoga:yg_marginTop="50"
  16.            ohos:background_element="$graphic:item_element"
  17.    >
  18.        <Text
  19.                ohos:height="50vp"
  20.                ohos:width="50vp"
  21.                ohos:background_element="$media:icon"
  22.                yoga:yg_flex="0"
  23.                yoga:yg_marginStart="15"
  24.        />
  25.        <Text
  26.                ohos:height="50vp"
  27.                ohos:width="220vp"
  28.                ohos:text="Hello.  I am Yoga!"
  29.                ohos:text_color="#000000"
  30.                yoga:yg_flex="1"
  31.                yoga:yg_marginStart="15"
  32.                ohos:text_size="20fp"
  33.        />
  34.    </com.facebook.yoga.openharmony.YogaLayout>
  35.    <com.facebook.yoga.openharmony.YogaLayout
  36.            ohos:background_element="$graphic:item_element"
  37.            ohos:height="60vp"
  38.            ohos:width="match_content"
  39.            yoga:yg_alignItems="center"
  40.            yoga:yg_flexDirection="row"
  41.            yoga:yg_marginHorizontal="15"
  42.            yoga:yg_marginTop="20"
  43.            yoga:yg_marginStart="15"
  44.    >
  45.        <Text
  46.                ohos:height="50vp"
  47.                ohos:width="50vp"
  48.                ohos:background_element="$media:icon"
  49.                yoga:yg_flex="0"
  50.                yoga:yg_marginStart="15"
  51.        />
  52.        <Text
  53.                ohos:height="50vp"
  54.                ohos:width="250vp"
  55.                ohos:text="I am a layout engine!"
  56.                ohos:text_color="#000000"
  57.                yoga:yg_flex="1"
  58.                yoga:yg_marginStart="15"
  59.                ohos:text_size="20fp"
  60.        />
  61.    </com.facebook.yoga.openharmony.YogaLayout>
  62.    <com.facebook.yoga.openharmony.YogaLayout
  63.            ohos:background_element="$graphic:item_element"
  64.            ohos:height="60vp"
  65.            ohos:width="match_content"
  66.            yoga:yg_alignItems="center"
  67.            yoga:yg_flexDirection="row"
  68.            yoga:yg_marginHorizontal="15"
  69.            yoga:yg_marginTop="20"
  70.    >
  71.        <Text
  72.                ohos:height="50vp"
  73.                ohos:width="50vp"
  74.                ohos:background_element="$media:icon"
  75.                yoga:yg_flex="0"
  76.                yoga:yg_marginStart="15"
  77.        />
  78.        <Text
  79.                ohos:height="50vp"
  80.                ohos:width="250vp"
  81.                ohos:text="I run natively."
  82.                ohos:text_color="#000000"
  83.                yoga:yg_flex="1"
  84.                yoga:yg_marginStart="15"
  85.                ohos:text_size="20fp"
  86.        />
  87.    </com.facebook.yoga.openharmony.YogaLayout>
  88.    <com.facebook.yoga.openharmony.YogaLayout
  89.            ohos:background_element="$graphic:item_element"
  90.            ohos:height="60vp"
  91.            ohos:width="match_content"
  92.            yoga:yg_alignItems="center"
  93.            yoga:yg_flexDirection="row"
  94.            yoga:yg_marginHorizontal="15"
  95.            yoga:yg_marginTop="20"
  96.    >
  97.        <Text
  98.                ohos:height="50vp"
  99.                ohos:width="50vp"
  100.                ohos:background_element="$media:icon"
  101.                yoga:yg_flex="0"
  102.        />
  103.        <Text
  104.                ohos:height="50vp"
  105.                ohos:width="200vp"
  106.                ohos:text="So I\'m fast."
  107.                ohos:text_color="#000000"
  108.                yoga:yg_flex="1"
  109.                yoga:yg_marginStart="15"
  110.                ohos:text_size="20fp"
  111.        />
  112.    </com.facebook.yoga.openharmony.YogaLayout>
  113.    <com.facebook.yoga.openharmony.YogaLayout
  114.            ohos:background_element="$graphic:item_element"
  115.            ohos:height="60vp"
  116.            ohos:width="match_content"
  117.            yoga:yg_alignItems="center"
  118.            yoga:yg_flexDirection="row"
  119.            yoga:yg_marginHorizontal="15"
  120.            yoga:yg_marginTop="20"
  121.    >
  122.        <Text
  123.                ohos:height="50vp"
  124.                ohos:width="50vp"
  125.                ohos:background_element="$media:icon"
  126.                yoga:yg_flex="0"
  127.        />
  128.        <Text
  129.                ohos:height="50vp"
  130.                ohos:width="200vp"
  131.                ohos:text="Who are you?"
  132.                ohos:text_color="#000000"
  133.                yoga:yg_flex="1"
  134.                yoga:yg_marginStart="15"
  135.                ohos:text_size="20fp"
  136.        />
  137.    </com.facebook.yoga.openharmony.YogaLayout>
  138. </com.facebook.yoga.openharmony.YogaLayout>

这里 YogaLayout 其实可以看成 FlexBox(详情请参考附录:FlexBox 科普)。

可以通过参数调节子布局位置,我们可以使用 YogaLayout 上的 yoga:yg_alignItems="center" 属性使得 item 居中显示,并通过 yoga:yg_flexDirection="row" 属性使得之 item 横向排列。

子 item 也可以通过设置 yoga:yg_flex="1" 来调整自己的权重。更多属性的使用大家也可以下载项目亲自体验。

02集成方式

自行编译工程 entity、yoga、yoga_layout、fb 生成 libyoga.so、libfb.so、libyogacore.so。

将其添加到要集成的 libs 文件夹内,在 entity 的 gradle 内添加如下代码。

方式一:通过 library 生成 har 包,添加 har 包到 libs 文件夹内。

在 entry 的 gradle 内添加如下代码:

implementation fileTree(dir:'libs', include:['*.jar','*.har'])

方式二:

  1. allprojects{
  2.     repositories{
  3.         mavenCentral()
  4.     }
  5. }
  6. implementation 'io.openharmony.tpc.thirdlib:yoga-layout:1.0.0'
  7. implementation 'io.openharmony.tpc.thirdlib:yoga-yoga:1.0.0'
  8. implementation 'io.openharmony.tpc.thirdlib:yoga-fb:1.0.0'

附录 1:FlexBox 科普

布局的传统解决方案,基于盒状模型,依赖 display 属性,position 属性,float 属性。

它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。2009 年,W3C 提出了一种新的方案:flex。

可以简便、完整、响应式地实现各种界面布局。目前,该方案已经得到了所有浏览器的支持。

采用 Flex 布局的元素,称为 Flex 容器(flex container),简称“容器”。它的所有子元素置动成为容器成员,称为 Flex 项目(flex item),简称“项目”。

图片

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)

主轴的开始位置(与边框的交叉点)叫 main start,结束位置叫 main end;交叉轴的开始位置叫 cross start,结束位置叫 cross end。

项目默认沿主轴排列。单个项目占据的主轴空间叫 main size,占据的交叉轴空间叫 cross size。

最后

如果你想成为一名鸿蒙开发者,以下这些资料将是十分优质且有价值,让你的鸿蒙开发之路事半功倍!相对于网上那些碎片化的知识内容,这份学习资料的知识点更加系统化,更容易理解和记忆。

内容包含了:【OpenHarmony多媒体技术、Stage模型、ArkUI多端部署、分布式应用开发、音频、视频、WebGL、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战】等技术知识点。

鸿蒙Next全套VIP学习资料←点击领取!(安全链接,放心点击

1.鸿蒙核心技术学习路线

2.大厂面试必问面试题

3.鸿蒙南向开发技术

 4.鸿蒙APP开发必备

 5.HarmonyOS Next 最新全套视频教程

 6.鸿蒙生态应用开发白皮书V2.0PDF

这份全套完整版的学习资料已经全部打包好,朋友们如果需要可以点击鸿蒙Next全套VIP学习资料:免费领取(安全链接,放心点击

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/828864
推荐阅读
相关标签
  

闽ICP备14008679号