HarmonyOS 鸿蒙Next如何通过相对布局画出图片中的标题

发布于 1周前 作者 gougou168 来自 鸿蒙OS

HarmonyOS 鸿蒙Next如何通过相对布局画出图片中的标题

需求:标题左侧是一个返回按钮(可选、可有可无);标题右侧是两个文本按钮(转发和横竖屏切换两个按钮、可选可有可无)。标题栏中间是标题文本必选。要求,标题文本占剩余标题栏宽度的所有。标题左侧按钮和标题右侧两个按钮宽度不固定。即,先分好左右两侧的按钮,宽度不固定。标题栏文本占剩余所有宽度。自己这边怎么画页画不好。要么不显示,要么重叠。想用低代码开发。realease也不再支持低代码开发了。

import window from ‘@ohos.window’;

import router from ‘@ohos.router’;

import { CommonConstants } from ‘…/constant/CommonConstants’;

import { BusinessError } from ‘@kit.BasicServicesKit’;

/**

*/

@Component

export struct TopDocTitle {

@Prop title: string

@Prop showBack: boolean = true

@State screenStyle: string = ‘横屏’

@State normalSize: number = CommonConstants.NORMAL_TEXT_SIZE

@State smallSize: number = CommonConstants.SMALL_TEXT_SIZE

@State pageSize: number = CommonConstants.PAGE_TITLE_TEXT_SIZE

@StorageLink(‘unFontSize’) unFontSize: number = 1;

build() {

RelativeContainer() {

  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.showBack) {

    Image($r(<span class="hljs-string">'app.media.back_btn'</span>))

      .id(<span class="hljs-string">'doc_back_iv'</span>)

      .width(<span class="hljs-number">40</span>)

      .height(<span class="hljs-number">20</span>)

      .objectFit(ImageFit.Contain)

      .alignRules({

        center: {

          anchor: <span class="hljs-string">"__container__"</span>,

          align: VerticalAlign.Center

        },

        left: {

          anchor: <span class="hljs-string">"__container__"</span>,

          align: HorizontalAlign.Start

        },

        right: {

          anchor: <span class="hljs-string">"doc_title"</span>,

          align: HorizontalAlign.Start

        },

      })

      .onClick(() =&gt; {

        router.back()

      })

  }

  Text(<span class="hljs-keyword">this</span>.title)

    .id(<span class="hljs-string">'doc_title'</span>)

    .fontColor(Color.White)

    .maxLines(<span class="hljs-number">1</span>)

    .layoutWeight(<span class="hljs-number">1</span>)

    .textOverflow({ overflow: TextOverflow.Ellipsis })

    .textAlign(TextAlign.Center)

    .fontSize(<span class="hljs-keyword">this</span>.pageSize * <span class="hljs-keyword">this</span>.unFontSize + <span class="hljs-string">'fp'</span>)

    .padding({ top: <span class="hljs-number">10</span>, bottom: <span class="hljs-number">10</span>, })

    .alignRules({

      center: {

        anchor: <span class="hljs-string">"__container__"</span>,

        align: VerticalAlign.Center

      },

      left: {

        anchor: <span class="hljs-string">"doc_back_iv"</span>,

        align: HorizontalAlign.End

      },

      right: {

        anchor: <span class="hljs-string">"opt"</span>,

        align: HorizontalAlign.Start

      },

      middle: {

        anchor: <span class="hljs-string">"__container__"</span>,

        align: HorizontalAlign.Center

      }

    })

  Row(){

    Text(<span class="hljs-string">'转发'</span>)

      .id(<span class="hljs-string">'share'</span>)

      .fontColor(Color.White)

      .maxLines(<span class="hljs-number">1</span>)

      .textAlign(TextAlign.Center)

      .fontSize(<span class="hljs-keyword">this</span>.normalSize * <span class="hljs-keyword">this</span>.unFontSize + <span class="hljs-string">'fp'</span>)

      .padding({ top: <span class="hljs-number">10</span>, bottom: <span class="hljs-number">10</span>})

      .margin({ right:<span class="hljs-number">5</span> })

    Text(<span class="hljs-keyword">this</span>.screenStyle)

      .id(<span class="hljs-string">'hv'</span>)

      .fontColor(Color.White)

      .maxLines(<span class="hljs-number">1</span>)

      .textAlign(TextAlign.Center)

      .fontSize(<span class="hljs-keyword">this</span>.normalSize * <span class="hljs-keyword">this</span>.unFontSize + <span class="hljs-string">'fp'</span>)

      .padding({ top: <span class="hljs-number">10</span>, bottom: <span class="hljs-number">10</span>, right:<span class="hljs-number">10</span> })

      .onClick(() =&gt; {

        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.screenStyle.includes(<span class="hljs-string">'横'</span>)){

          <span class="hljs-keyword">let</span> orient = window.Orientation.LANDSCAPE

          <span class="hljs-keyword">this</span>.setScreenOrientation(orient)

          <span class="hljs-keyword">this</span>.screenStyle = <span class="hljs-string">'竖屏'</span>

        }<span class="hljs-keyword">else</span>{

          <span class="hljs-keyword">let</span> orient = window.Orientation.PORTRAIT

          <span class="hljs-keyword">this</span>.setScreenOrientation(orient)

          <span class="hljs-keyword">this</span>.screenStyle = <span class="hljs-string">'横屏'</span>

        }

      })

  }

  .id(<span class="hljs-string">'opt'</span>)

  .alignRules({

    center: {

      anchor: <span class="hljs-string">"__container__"</span>,

      align: VerticalAlign.Center

    },

    left: {

      anchor: <span class="hljs-string">"doc_title"</span>,

      align: HorizontalAlign.End

    },

    right: {

      anchor: <span class="hljs-string">"__container__"</span>,

      align: HorizontalAlign.End

    },

  })

  <span class="hljs-comment">/*.width(120)*/</span>

  .height(CommonConstants.FULL_PARENT)

}

.width(CommonConstants.FULL_PARENT)

.height($r(<span class="hljs-string">'app.float.title_height'</span>))

.backgroundColor($r(<span class="hljs-string">'app.color.title_top_color'</span>))

}

// 设置页面横屏

setScreenOrientation(orientation: window.Orientation) {

<span class="hljs-keyword">let</span> windowClass: window.Window | <span class="hljs-literal">undefined</span> = <span class="hljs-literal">undefined</span>;

<span class="hljs-keyword">try</span> {

  <span class="hljs-keyword">let</span> promise = window.getLastWindow(getContext());

  promise.then((data) =&gt; {

    windowClass = data;

    windowClass.setPreferredOrientation(orientation);

    console.info(<span class="hljs-string">'setScreenOrientation----&gt;Succeeded'</span>);

  }).catch((err: BusinessError) =&gt; {

    console.error(<span class="hljs-string">'setScreenOrientation----&gt;Failed: '</span> + <span class="hljs-built_in">JSON</span>.stringify(err));

  });

} <span class="hljs-keyword">catch</span> (exception) {

  console.error(<span class="hljs-string">'setScreenOrientation----&gt;Failed2: '</span> + <span class="hljs-built_in">JSON</span>.stringify(exception));

}

}

aboutToDisappear(): void {

<span class="hljs-comment">// 退出、取消竖屏展示</span>

<span class="hljs-keyword">let</span> orient = window.Orientation.PORTRAIT

<span class="hljs-keyword">this</span>.setScreenOrientation(orient)

<span class="hljs-keyword">this</span>.screenStyle = <span class="hljs-string">'横屏'</span>

}

}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>


更多关于HarmonyOS 鸿蒙Next如何通过相对布局画出图片中的标题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

参考代码如下(可以按需修改Visibility的属性,来满足自己的布局要求):

import window from '@ohos.window';

import router from ‘@ohos.router’;

// import { CommonConstants } from ‘…/constant/CommonConstants’;

import { BusinessError } from ‘@kit.BasicServicesKit’;

/**

 * @author: kwb

 * @copyright: 2.0

 * @description: 顶部标题

 */

@Entry

@Component

struct MPage {

  @State title: string = ‘你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你n你你你你你你你你你你你你你你你男男女女你你你你你你你你你你你你你你你你你你你你’

  @State showBack: boolean = true

  @State screenStyle: string = ‘横屏’

  // @State normalSize: number = CommonConstants.NORMAL_TEXT_SIZE

  // @State smallSize: number = CommonConstants.SMALL_TEXT_SIZE

  // @State pageSize: number = CommonConstants.PAGE_TITLE_TEXT_SIZE

  // @StorageLink(‘unFontSize’) unFontSize: number = 1;

  build() {

    Column() {

      RelativeContainer() {

        // if (this.showBack) {

          Image($r(‘app.media.startIcon’))

            .id(‘doc_back_iv’)

            .width(40)

            .height(20)

            .objectFit(ImageFit.Contain)

            .alignRules({

              center: {

                anchor: container,

                align: VerticalAlign.Center

              },

              left: {

                anchor: container,

                align: HorizontalAlign.Start

              }

            })

            .visibility(this.showBack ? Visibility.Visible : Visibility.Hidden)

            .onClick(() => {

              router.back()

            })

        // }

        Text(this.title)

          .id(‘doc_title’)

          .fontColor(Color.White)

          .maxLines(1)

          .layoutWeight(1)

          .textOverflow({ overflow: TextOverflow.Ellipsis })

          .textAlign(TextAlign.Center)

          .fontSize(15)

            // .fontSize(this.pageSize * this.unFontSize + ‘fp’)

          .padding({ top: 10, bottom: 10, })

          .alignRules({

            center: {

              anchor: container,

              align: VerticalAlign.Center

            },

            left: {

              anchor: “doc_back_iv”,

              align: HorizontalAlign.End

            },

            right: {

              anchor: “opt”,

              align: HorizontalAlign.Start

            }

          })

        Row(){

          Text(‘转发’)

            .id(‘share’)

            .fontColor(Color.White)

            .maxLines(1)

            .textAlign(TextAlign.Center)

              // .fontSize(this.normalSize * this.unFontSize + ‘fp’)

            .padding({ top: 10, bottom: 10})

            .margin({ right:5 })

          Text(this.screenStyle)

            .id(‘hv’)

            .fontColor(Color.White)

            .maxLines(1)

            .textAlign(TextAlign.Center)

              // .fontSize(this.normalSize * this.unFontSize + ‘fp’)

            .padding({ top: 10, bottom: 10, right:10 })

            .onClick(() => {

              if (this.screenStyle.includes(‘横’)){

                let orient = window.Orientation.LANDSCAPE

                this.setScreenOrientation(orient)

                this.screenStyle = ‘竖屏’

              }else{

                let orient = window.Orientation.PORTRAIT

                this.setScreenOrientation(orient)

                this.screenStyle = ‘横屏’

              }

            })

        }

        .id(‘opt’)

        .visibility(this.showBack ? Visibility.Visible : Visibility.Hidden)

        .alignRules({

          center: {

            anchor: container,

            align: VerticalAlign.Center

          },

          right: {

            anchor: container,

            align: HorizontalAlign.End

          },

        })

        /.width(120)/

        .height(‘100%’)

      }

      .width(‘100%’)

      .height(60)

      .backgroundColor(Color.Red)

      Button(‘点击控制显隐’)

        .onClick(()=> {

          this.showBack = !this.showBack

        })

    }

  }

  // 设置页面横屏

  setScreenOrientation(orientation: window.Orientation) {

    let windowClass: window.Window | undefined = undefined;

    try {

      let promise = window.getLastWindow(getContext());

      promise.then((data) => {

        windowClass = data;

        windowClass.setPreferredOrientation(orientation);

        console.info(‘setScreenOrientation---->Succeeded’);

      }).catch((err: BusinessError) => {

        console.error('setScreenOrientation---->Failed: ’ + JSON.stringify(err));

      });

    } catch (exception) {

      console.error('setScreenOrientation---->Failed2: ’ + JSON.stringify(exception));

    }

  }

  aboutToDisappear(): void {

    // 退出、取消竖屏展示

    let orient = window.Orientation.PORTRAIT

    this.setScreenOrientation(orient)

    this.screenStyle = ‘横屏’

  }

}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

完全居中,可以设置左右两侧的最外层父元素宽度保持一致

最右侧组件不论是一个还是两个,并不会影响到标题居中布局,因为标题是以最右侧两个组件的父组件为锚点,父组件内容的多少并不会影响到标题栏的整体布局,同样左侧也可以添加个父级容器,以此父组件为锚点,都不会影响到RelativeContainer标题栏的布局,使用我上述提供的位置设置,可以保持标题栏居中~

更多关于HarmonyOS 鸿蒙Next如何通过相对布局画出图片中的标题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,通过相对布局(Relative Layout)来放置并显示图片中的标题,可以按照以下步骤进行:

  1. 定义布局文件:在XML布局文件中,使用<DirectionalLayout>(方向布局)或<DependentLayout>(依赖布局)来模拟相对布局的功能。HarmonyOS中相对布局的概念通过这两个布局实现。

  2. 添加图片和标题组件:在布局中,使用<Image>组件来显示图片,使用<Text>组件来显示标题。

  3. 设置相对位置

    • 使用<DirectionalLayout>时,通过alignment属性设置组件的对齐方式(如leftrighttopbottom等)。
    • 使用<DependentLayout>时,通过leftOfrightOfabovebelow等属性设置组件之间的依赖关系,从而确定相对位置。
  4. 设置标题文本:在<Text>组件中,使用text属性来设置标题的内容。

示例代码片段(使用<DependentLayout>):

<DependentLayout>
    <Image id="image" src="$media:image_path" />
    <Text id="title" text="图片标题" leftOf="$+id:image" below="$+id:image" margin="10vp" />
</DependentLayout>

上述代码展示了如何将标题放置在图片的下方和左侧。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部