首页 文章

Nativescript:Android新导航栏

提问于
浏览
3

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

3 回答

  • 4

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

    • 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>
    

    编辑:这是相关的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;
        }
    }
    
  • 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](http://developer.android.com/reference/android/view/ViewAnimationUtils.html#createCircularReveal(android.view.View),int,int,float,float)来设置圆形显示效果的动画 .

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

    我昨天在几分钟内将这个放在一起,使用了Bottom Bar的库 .
    enter image description here

  • 0

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

    希望这有助于谢谢!

相关问题