如何在NativeScript的Absolute Layout底部定位元素?

时间:2017-07-19 08:16:14

标签: nativescript

我想在NativeScript的Absolute Layout中将元素放在屏幕的底部。

我有这段代码:

<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没有底层属性......以下是我想要创建的图片:

enter image description here

那么如何排列图片中的项目,特别是底部的项目?

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

4 个答案:

答案 0 :(得分:8)

我有一天做了类似的事情,以编程方式&amp;使用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>

答案 1 :(得分:1)

这是绝对最佳的解决方案,它来自以下一名开发人员:https://github.com/NativeScript/NativeScript/issues/5591#issuecomment-482640921

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

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

答案 2 :(得分:0)

这是最好的解决方案 将所有元素包装为一个绝对布局,其宽度和高度为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>

答案 3 :(得分:0)

也可以使用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>