【问题标题】:How to position element at the bottom of Absolute Layout in NativeScript?如何在 NativeScript 中的绝对布局底部定位元素?
【发布时间】:2017-12-24 09:07:34
【问题描述】:

我想在 NativeScript 中的绝对布局中将一个元素定位在屏幕底部。

我有这个代码:

<AbsoluteLayout>
    <maps:mapView 
        left="0"
        top="0"
        width="100%"
        height="100%"
        latitude="{{ map.latitude }}" 
        longitude="{{ map.longitude }}" 
        zoom="{{ map.zoom }}"
        padding="{{ map.padding }}"  
        mapReady="onMapReady"
        coordinateTapped="onCoordinateTapped"
        markerSelect="onMarkerSelect"
        shapeSelect="onShapeSelect"
        cameraChanged="onMapCameraChanged"/>

    <ScrollView
        left="0"
        top="0"
        width="100%"
        orientation="horizontal">
        <!-- More XML -->
    </ScrollView>

    <StackLayout
        left="0"
        bottom="0"
        width="100%"
        visibility="visible"
        orientation="horizontal"
        style="background-color: red;">

        <Label text="TITLE"></Label>

    </StackLayout>
</AbsoluteLayout>

我发现AbsoluteLayout没有底部属性...这是我要创建的图片:

那么如何排列图片中的物品,尤其是底部的物品?

编辑:我应该注意这个底部矩形的尺寸可能并不总是相同的......

【问题讨论】:

    标签: nativescript


    【解决方案1】:

    GridLayout也可以做到:

    <GridLayout rows="16,*,16" columns="16,*,16" width="100%" backgroundColor="red">
        <GridLayout row="1" col="1" rows="auto, auto, auto" columns="auto" horizontalAlignment="right" verticalAlignment="bottom" backgroundColor="blue">
            <!-- Your content at bottom right corner -->
            <Label row="0" text="Your content" textAlignment="center" textWrap="true"></Label>
            <Label row="1" text="at" textAlignment="center" textWrap="true"></Label>
            <Label row="2" text="bottom right corner" textAlignment="center"></Label>
        </GridLayout>
    </GridLayout>
    

    【讨论】:

      【解决方案2】:

      这是绝对最佳的解决方案,从其中一位开发者处获得:https://github.com/NativeScript/NativeScript/issues/5591#issuecomment-482640921

      <GridLayout rows="*,auto">
         <ItemTakingFullScreen rowSpan="2"/>
         <ItemShownUnder row="1"/>
         <ItemShownAbove row="1">
      </GridLayout>
      

      基本上,您可以使用网格布局,让一个项目占据多个网格空间,并与其他项目共享。

      【讨论】:

        【解决方案3】:

        这是最好的解决方案 将所有元素包装在一个绝对布局中,宽度和高度为 100%,并可能添加一个网格布局来保存主要内容。

                <AbsoluteLayout width='100%' height='100%'>
                   <StackLayout width='100%' hieght='100%' left='0' top='0'>
                         //add you structure here
        
                   </StackLayout>
                   add your fixed element here
        
                   <image src='add the float item'/>
               </AbsoluteLayout>
        

        【讨论】:

          【解决方案4】:

          另一种选择是在您的 AbsoluteLayout 容器中使用 FlexboxLayout,如下所示:

          <FlexboxLayout flexDirection="column" justifyContent="space-between" height="100%">
              <ScrollView
                  width="100%"
                  orientation="horizontal">
                  <!-- More XML -->
              </ScrollView>
          
              <StackLayout
                  width="100%"
                  visibility="visible"
                  orientation="horizontal"
                  style="background-color: red;">
          
                  <Label text="TITLE"></Label>
          
              </StackLayout>
          </FlexboxLayout>
          

          【讨论】:

            【解决方案5】:

            有一天我做了类似的事情,以编程方式 & 使用 Angular,也许这会有所帮助。

            如果您不想使用 GridLayout,您可以尝试获取底部元素和屏幕的高度,然后通过简单的计算从顶部放置元素:屏幕的高度 - 底部元素的高度(如果你想要一些填充)。您可以使用两种类型的值:DIP 和像素。如果您使用像素,则需要使用屏幕比例将值转换为 DIP。

            类似这样的(我没有测试我给你的代码,这只是一个例子)

            1] 为你的底部元素添加一个 id,这样你就可以在你的组件中访问它:

            <StackLayout #bottomElt></StackLayout>
            

            2] 更新您的组件以在绝对布局中设置元素位置

            // you need ElementRef, OnInit and ViewChild
            import { Component, ElementRef, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
            import { AbsoluteLayout } from "ui/layouts/absolute-layout";
            import { StackLayout } from "ui/layouts/stack-layout";
            // you need access to screen properties
            import { screen } from "tns-core-modules/platform";
            [...]
            
            export class YourComponent implements OnInit {
                // add access to element inside your component
                @ViewChild("bottomElt") bottomElt: ElementRef;
            
                // create variable to access bottom element properties
                bottomContainer: StackLayout;
            
                // set bottom element position after view init
                // example : inside ngOnInit function (for Angular version)
                ngOnInit(): void {
                    this.bottomContainer = <StackLayout>this.bottomElt.nativeElement;
            
                    // using DIPs values only
                    AbsoluteLayout.setTop(this.bottomContainer, (screen.mainScreen.heightDIPs - Number(this.bottomContainer.height)));
            
                    // using pixels and screen scale
                    // this way you can get height without knowing it
                    AbsoluteLayout.setTop(this.bottomContainer, (screen.mainScreen.heightDIPs - (Number(this.bottomContainer.getMeasuredHeight()) / screen.mainScreen.scale)));
            
                }
            

            有关屏幕值的更多信息:https://docs.nativescript.org/api-reference/interfaces/platform.screenmetrics.html

            另一种方式

            您可以使用 GridLayout 来设置底部栏,而不是使用 AbsoluteLayout,它有两行:一排具有通配符大小,另一排具有自动大小,以便每次更改时都能适应底部栏的高度。我在移动应用程序中这样做是为了在 Android 和 IOS 的底部获得一个菜单:

            <GridLayout rows="*, auto" width="100%">
                <AbsoluteLayout row="0" orientation="vertical">
                    <!-- YOUR CONTENT (maps & ScrollView) -->
                </AbsoluteLayout>
            
                <!-- YOUR BOTTOM BAR (StackLayout). Don't forget to add row="1" -->
                <StackLayout #bottomElt row="1">[...]</StackLayout>
            </GridLayout>
            

            【讨论】:

            • 你知道我怎样才能计算底栏的高度,因为它里面的内容会随着时间的推移而改变,而且它也会被显示/隐藏。所以我需要在显示它之前计算它的新高度......或者即使它被隐藏它也会在内容更改后更新它的高度而我不计算它?
            • 您可以使用getMeasuredHeight() 函数并将其转换为DIP,然后在每次更改他的内容时更改他的位置。您也可以采用完全不同的方式:使用 GridLayout 显示底部栏,您可以使用 visibility 属性隐藏/显示该栏。这样,无论他的身高如何,您的底栏都将始终位于底部,并且主要内容将始终填满所有可用空间。我将在我的答案中添加此选项
            • 我选择了第一个解决方案。因此,布局最初是隐藏的,标签是空的。在未来的某个时候,一个事件被触发,它应该用适当的文本显示这个隐藏的布局。所以我写bottomBarLabel.text='some text'; let h = bottomBar.getMeasuredHeight();。但是 bottomBar 的高度为零,至少 getMeasuredHeight() 返回零。但是我设置了一个超时来运行,并在该超时打印出 getMeasuredHeight() 并且它是正确的,但我不喜欢使用超时函数来等待组件计算它的高度....
            • 不错的解决方案。在 Angular 中,我会将计算移至“ngAfterViewInit()”,以避免在 Angular 完成绘制之前尝试访问元素时出错。
            猜你喜欢
            • 2018-03-23
            • 1970-01-01
            • 1970-01-01
            • 2019-08-06
            • 1970-01-01
            • 1970-01-01
            • 2011-07-01
            • 1970-01-01
            • 2013-11-06
            相关资源
            最近更新 更多