Nativescript:Android新导航栏

时间:2016-04-12 08:22:10

标签: nativescript

根据谷歌的新材料设计guidelines,导航栏应该位于底部。我该如何实现它(如果有办法)?目前,我正在使用Tabview,默认情况下,它位于页面顶部。 谢谢

3 个答案:

答案 0 :(得分:4)

截至目前,还没有来自Google的小部件。所以你必须自己动手。组件规范有几种开源实现。

我发现可以与NativeScript一起使用的更好的一个是https://github.com/roughike/BottomBar

另一种方法是使用固定在视图底部的grid-layout,将导航栏设置为透明,这在我的博文here中有所介绍。然后,您可以使用nativescript动画API为效果的标签设置动画。然后,您将使用它:http://developer.android.com/reference/android/view/ViewAnimationUtils.html#createCircularReveal(android.view.View,int,int,float,float)来设置循环显示效果的动画。

我可能会使用已经可用的NativeScript写一篇文章然后如果我有时间将该库变成NativeScript的插件

我昨天在几分钟内使用底部栏的库将它放在一起。 enter image description here

答案 1 :(得分:4)

对于这种情况,我创建了一个自定义的Nativescript组件。这是非常基本的,但我希望它会对你有所帮助。

  • 应用/组件/底面navigation.ts
import gridLayoutModule = require("ui/layouts/grid-layout");
import {Label} from "ui/label";
import dependencyObservableModule = require("ui/core/dependency-observable");
import {EventData} from "data/observable";
import frameModule = require("ui/frame");

export class BottomNavigation extends gridLayoutModule.GridLayout {
    public static selectedItemProperty = new dependencyObservableModule.Property(
        "selectedItem",
        "BottomNavigation",
        new dependencyObservableModule.PropertyMetadata(undefined, dependencyObservableModule.PropertyMetadataSettings.None,
        function(data: dependencyObservableModule.PropertyChangeData) {
            if (data.newValue) {
                let instance = <BottomNavigation>data.object;
                instance.setSelectedItem(data.newValue);
            }
        }));

    public get selectedItem() {
        return this._getValue(BottomNavigation.selectedItemProperty);
    }
    public set selectedItem(value: string) {
        this._setValue(BottomNavigation.selectedItemProperty, value);
    }

    private _items = [
        { code: "TAB_1", icon: 0xe90a, label: "Tab 1" },
        { code: "TAB_2", icon: 0xe90b, label: "Tab 2"},
        { code: "TAB_3", icon: 0xe90c, label: "Tab 3"}];

    constructor() {
        super();

        this.createUi();
    }

    public setSelectedItem(selectedItem: string) {
        this.selectedItem = selectedItem;

        let icon = this.getViewById(selectedItem + "_ICON");
        icon.className = icon.className.replace("icon-unselected", "icon-selected");

        let label = this.getViewById(selectedItem + "_LABEL");
        label.className = "label-selected";
    }

    private createUi() {
        this.removeChildren();

        this.className = "bottom-navigation";

        this.addColumn(new gridLayoutModule.ItemSpec(1, "star"));
        this.addColumn(new gridLayoutModule.ItemSpec(1, "star"));
        this.addColumn(new gridLayoutModule.ItemSpec(1, "star"));

        for (let i = 0; i < this._items.length; i++) {
            let currentItem = this._items[i];

            let icon = new Label();
            icon.id = currentItem.code + "_ICON";
            icon.text = String.fromCharCode(currentItem.icon);
            icon.className = "material-icon icon-unselected";
            icon.on("tap", args => this.onNavigate(args, currentItem.code));
            this.addChild(icon);
            gridLayoutModule.GridLayout.setColumn(icon, i);

            let label = new Label();
            label.id = currentItem.code + "_LABEL";
            label.text = currentItem.label;
            label.className = "label-unselected";
            label.on("tap", args => this.onNavigate(args, currentItem.code));
            this.addChild(label);
            gridLayoutModule.GridLayout.setColumn(label, i);
        }
    }

    private onNavigate(args: EventData, code: string) {
        let selectedLabel = <Label>args.object;

        if (selectedLabel.className.indexOf("icon-selected") > -1) {
            return;
        }

        let destinationUrl = "";

        switch (code) {
            case "TAB_1":
                destinationUrl = "views/tab-1/tab-1";
                break;
            case "TAB_2":
                destinationUrl = "views/tab-2/tab-2";
                break;
            case "TAB_3":
                destinationUrl = "views/tab-3/tab-3";
                break;
        }

        frameModule.topmost().navigate({
            animated: false,
            backstackVisible: false,
            moduleName: destinationUrl
        });
    }
}
  • MY-view.xml用
<Page xmlns="http://schemas.nativescript.org/tns.xsd"
    xmlns:bn="components/bottom-navigation">
  <GridLayout rows="*, auto">
    <GridLayout>
      <!-- Your view here -->
    </GridLayout>
    <bn:BottomNavigation row="1" selectedItem="TAB_1" />
  </GridLayout>
</Page>

编辑:这是相关的SASS风格

.bottom-navigation {
    background-color: $primary-color;
    height: 56;
    color: $primary-color-text;

    .icon {
        horizontal-align: center;
        font-size:46;
    }

    .icon-selected {
        @extend .icon;
    }

    .icon-unselected {
        @extend .icon;
        vertical-align: center;
    }

    .label {
        horizontal-align: center;
        vertical-align: bottom;
        margin-bottom: 4;
    }

    .label-unselected {
        @extend .label;
        visibility: collapse;
    }

    .label-selected {
        @extend .label;
        visibility: visible;
    }
}

答案 2 :(得分:0)

这可能不是完美的解决方案,但是, 因为在这种情况下你应该使用viewpager。将父线性布局的重力放在底部。标签会自动移动到页面底部。

希望这有助于谢谢!!!