Nativescript : Android new navigation bar

假如想象 提交于 2019-12-12 09:55:34

问题


According to Google's new Material Design guidelines, the navigation bar is supposed to be at the bottom. How can I implement it (if there is a way) ? For the moment, I'm using a Tabview which, by default on Android, is put at the top of the page. Thank you


回答1:


For this case, i created a custom Nativescript component. It's really basic but i hope it will help you.

  • app/components/bottom-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>

EDIT : Here is the associated SASS style

.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:


As of right now there isn't a shipped widget from Google. So you have to roll your own. There are several open source implementations of the component spec.

One of the better ones I have found that you could use with NativeScript is, https://github.com/roughike/BottomBar

Another alternative is to use a grid-layout pinned to the bottom of you view, set the navigation bar to be transparent, this is covered in my blog post here. Then you could use the nativescript animation API to animate the labels for the effect. You would then use this :http://developer.android.com/reference/android/view/ViewAnimationUtils.html#createCircularReveal(android.view.View, int, int, float, float) to animate the circular reveal effect.

I might write up a post using already available NativeScript and then if I have time make that library into a plugin for NativeScript

I put this together in a few minutes yesterday using a library for the Bottom Bar.




回答3:


This might not be the perfect solution but, Since you should use viewpager in this case. Put gravity of the parent linear layout to bottom. The tab automatically moves to bottom of the page.

Hope this helps thanks!!!



来源:https://stackoverflow.com/questions/36567491/nativescript-android-new-navigation-bar

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!