0

有没有办法在ionic v1应用程序的导航抽屉(菜单)中获得本机外观和感觉,而不是推送中心内容?

在此处输入图像描述

我想在 ionic 应用程序中获得 Android 原生的外观和感觉,如上图所示。

4

1 回答 1

0

虽然这是一个老问题,并且Ionic v2+目前可用于本机导航抽屉功能 ( <ion-menu>)。我只是想分享一些代码来展示如何在Ionic v1应用程序中实现此功能。我认为这对那些仍在他们的移动应用程序中使用Ionic v1的人会有所帮助。也可以在本文末尾找到Ionic v2+实现。


离子 v1

我刚刚使用他们现成的应用程序模板创建了一个示例Ionic v1应用程序。sidemenu

ionic start myApp sidemenu --type ionic1

然后我在文件夹中创建了以下nativeSideMenu.js文件js

(function () {

    'use strict';

    angular.module('ionic.contrib.NativeDrawer', ['ionic'])

        .controller('drawerCtrl', ['$rootScope', '$scope', '$element', '$attrs', '$ionicGesture', '$ionicBody', '$document', function ($rootScope, $scope, $element, $attr, $ionicGesture, $ionicBody, $document) {
            var el = document.querySelectorAll("drawer")[0];
            var mainContent = angular.element(document.querySelectorAll("ion-pane")[0]);
            var dragging = false;
            var startX, lastX, offsetX, newX, startY, lastY, offsetY, newY;
            var side;
            var isOpen = false;
            var primaryScrollAxis = null;

            mainContent.addClass('drawer-content');

            // How far to drag before triggering
            var thresholdX = 10;
            // How far from edge before triggering
            var edgeX = 40;
            // Width of drawer set in css
            var drawerWidth = 270;

            var LEFT = 0;
            var RIGHT = 1;

            var isTargetDrag = false;

            var isContentDrag = false;

            var width = $element[0].clientWidth;
            var height = $element[0].clientHeight;

            var enableAnimation = function () {
                angular.element(el).addClass('animate');
            };
            var disableAnimation = function () {
                angular.element(el).removeClass('animate');
            };

            // Check if this is on target or not
            var isTarget = function (el) {
                while (el) {
                    if (el === $element[0]) {
                        return true;
                    }
                    el = el.parentNode;
                }
            };

            var startDrag = function (e) {
                disableAnimation();

                dragging = true;
                offsetX = lastX - startX;
                offsetY = lastY - startY;
                $ionicBody.addClass('drawer-open');
            };

            var startTargetDrag = function (e) {
                disableAnimation();

                dragging = true;
                isTargetDrag = true;
                offsetX = lastX - startX;
                offsetY = lastY - startY;
            };

            var doEndDrag = function (e) {
                startX = null;
                lastX = null;
                offsetX = null;
                startY = null;
                lastY = null;
                offsetY = null;
                isTargetDrag = false;

                if (!dragging) {
                    return;
                }

                dragging = false;

                enableAnimation();
                if (isOpen && newX < (-width / 3)) {
                    el.style.transform = el.style.webkitTransform = 'translate3d(' + (-width - 5) + 'px, 0, 0)';
                    $ionicBody.removeClass('drawer-open');
                    isOpen = false;
                } else if (newX < (-width / 1.5)) {
                    el.style.transform = el.style.webkitTransform = 'translate3d(' + (-width - 5) + 'px, 0, 0)';
                    $ionicBody.removeClass('drawer-open');
                    isOpen = false;
                } else {
                    el.style.transform = el.style.webkitTransform = 'translate3d(0px, 0, 0)';
                    $ionicBody.addClass('drawer-open');
                    isOpen = true;
                }
            };

            var doEndContentDrag = function (e) {
                if (startX > lastX) {
                    startX = null;
                    lastX = null;
                    offsetX = null;
                    startY = null;
                    lastY = null;
                    offsetY = null;
                    isTargetDrag = false;
                    isContentDrag = false;

                    if (!dragging) {
                        return;
                    }

                    dragging = false;

                    enableAnimation();
                    el.style.transform = el.style.webkitTransform = 'translate3d(-101%, 0, 0)';
                    $ionicBody.removeClass('drawer-open');
                    isOpen = false;
                }
                else {
                    el.style.transform = el.style.webkitTransform = 'translate3d(0 0, 0)';
                }

            };

            var doDrag = function (e) {
                if (e.defaultPrevented) {
                    return;
                }

                if (!lastX) {
                    startX = e.gesture.touches[0].pageX;
                }
                if (!lastY) {
                    startY = e.gesture.touches[0].pageY;
                }

                lastX = e.gesture.touches[0].pageX;
                lastY = e.gesture.touches[0].pageY;

                if (!dragging) {

                    // Dragged 15 pixels and finger is by edge
                    if (Math.abs(lastX - startX) > thresholdX) {
                        if (isTarget(e.target)) {
                            startTargetDrag(e);
                        } else if (startX < edgeX) {
                            startDrag(e);
                        }
                    }
                    // Closing from outside of drawer
                    else if (isOpen && startX > width) {
                        disableAnimation();
                        dragging = true;
                        isContentDrag = true;
                    }
                } else {
                    newX = Math.min(0, (-width + (lastX - offsetX)));
                    newY = Math.min(0, (-height + (lastY - offsetY)));
                    var absX = Math.abs(lastX - startX);
                    var absY = Math.abs(lastY - startY);
                    if (isContentDrag && lastX < startX) {
                        var drawerOffsetX = lastX - drawerWidth;
                        el.style.transform = el.style.webkitTransform = 'translate3d(' + -absX + 'px, 0, 0)';
                    }
                    else if (isTargetDrag && absX > absY + 5) {
                        el.style.transform = el.style.webkitTransform = 'translate3d(' + newX + 'px, 0, 0)';
                    } else {
                        el.style.transform = el.style.webkitTransform = 'translate3d(' + newX + 'px, 0, 0)';
                    }
                }

                if (dragging) {
                    e.gesture.srcEvent.preventDefault();
                }
            };

            side = $attr.side == 'left' ? LEFT : RIGHT;

            var dragFunction = function (e) {
                if (el.attributes.candrag) {
                    doDrag(e);
                }
            };

            var dragEndFunction = function (e) {
                if (el.attributes.candrag) {
                    doEndDrag(e);
                }
            };

            var onContentDrag = function (e) {
                if (isOpen) {
                    doDrag(e);
                }
            };

            var onContentTap = function (e) {
                if (isOpen) {
                    closeDrawer();
                    e.gesture.srcEvent.preventDefault();
                }
            };

            var contentDragEndFunction = function (e) {
                if (isOpen) {
                    doEndContentDrag(e);
                    e.gesture.srcEvent.preventDefault();
                }
            };

            var openDrawer = function () {
                enableAnimation();
                el.style.transform = el.style.webkitTransform = 'translate3d(0%, 0, 0)';
                $ionicBody.addClass('drawer-open');
                isOpen = true;
            };

            var closeDrawer = function () {
                enableAnimation();
                el.style.transform = el.style.webkitTransform = 'translate3d(-101%, 0, 0)';
                $ionicBody.removeClass('drawer-open');
                isOpen = false;
            };

            var toggleDrawer = function () {
                if (isOpen) {
                    closeDrawer();
                } else {
                    openDrawer();
                }
            };

            this.close = function () {
                closeDrawer();
            };

            $rootScope.toggleDrawerRoot = function () {
                toggleDrawer();
            };

            this.open = function () {
                openDrawer();
            };

            this.toggle = function () {
                toggleDrawer();
            };

            $ionicGesture.on('drag', function (e) {
                doDrag(e);
            }, $document);
            $ionicGesture.on('dragend', function (e) {
                doEndDrag(e);
            }, $document);

            var dragGesture = $ionicGesture.on('drag', dragFunction, $document);
            var dragEndGesture = $ionicGesture.on('dragend', dragEndFunction, $document);
            var contentTapGesture = $ionicGesture.on('tap', onContentTap, mainContent);
            var contentDragGesture = $ionicGesture.on('drag', onContentDrag, mainContent);
            var contentDragEndGesture = $ionicGesture.on('dragend', contentDragEndFunction, mainContent);

            $scope.$on('$destroy', function () {

                $ionicGesture.off(dragGesture, 'drag', dragFunction);
                $ionicGesture.off(dragEndGesture, 'dragend', dragEndFunction);
                $ionicGesture.off(contentTapGesture, 'tap', onContentTap);
                $ionicGesture.off(contentDragGesture, 'drag', onContentDrag);
                $ionicGesture.off(contentDragEndGesture, 'dragend', contentDragEndFunction);
            });

        }])

        .directive('drawer', ['$rootScope', '$ionicGesture', function ($rootScope, $ionicGesture) {
            return {
                restrict: 'E',
                controller: 'drawerCtrl',
                link: function ($scope, $element, $attr, ctrl) {
                    $element.addClass($attr.side);
                    $scope.openDrawer = function () {
                        ctrl.open();
                    };
                    $scope.closeDrawer = function () {
                        ctrl.close();
                    };
                    $scope.toggleDrawer = function () {
                        ctrl.toggle();
                    };
                }
            }
        }])

        .directive('menuAndDrawerToggle', ['$rootScope', '$ionicGesture', function ($rootScope, $ionicGesture) {
            return {
                controller: '',
                link: function ($scope, $element, $attr) {
                    $element.bind('click', function () {
                        $rootScope.toggleDrawerRoot();
                    });
                }
            };
        }])

        .directive('menuAndDrawerClose', ['$ionicViewService', function ($ionicViewService) {
            return {
                restrict: 'AC',
                require: '^drawer',
                link: function ($scope, $element, $attr, ctrl) {
                    $element.bind('click', function () {
                        ctrl.close();
                    });
                }
            };
        }]);

})();

并且还在文件夹nativeSideMenu.css内创建了以下文件css

drawer {
    display: block;
    position: fixed;
    width: 270px;
    height: 100%;
    z-index: 100;
    background-color:white;
}
drawer .header-menu{
    margin-top:0px;
    padding-top:0px;
}
drawer .header-menu ion-list .list{
    padding-top:0px;
}
drawer.animate {
    -webkit-transition: all ease-in-out 400ms;
    transition: all ease-in-out 400ms;
}
drawer.left {
    -webkit-transform: translate3d(-101%, 0, 0);
    transform: translate3d(-101%, 0, 0);
    box-shadow: 1px 5px 10px rgba(0,0,0,0.3);
}
drawer.right {
    right: 0;
    top: 0;
    -webkit-transform: translate3d(100%, 0, 0);
    transform: translate3d(100%, 0, 0);
}
.drawer-open .drawer-content .pane, .drawer-open .drawer-content .scroll-content {
    pointer-events: none;
    opacity:0.2;
}
drawer .item-icon-left .icon{
    font-size: 24px;
    padding-bottom: 2px;
}
ion-side-menu .current a.item-content,ion-side-menu .clickable.current, drawer .current a.item-content, drawer .clickable.current {
    color:#343434 !important;
}
drawer a.item-content, drawer .clickable{
    color: #858585;
    font-size:20px;
}
drawer .item-complex .item-content{
    padding-top:16px;
    padding-bottom:16px;
    font-size:20px;
}
/*This section would normally have .platform-android at the front */
.platform-android4_0 drawer.left{
    box-shadow: none;
    border-left:0px;
    border-right:0px;
}
.header-menu{
    top:0px;
    bottom:44px;
}
.menu .scroll-content {
    top: 42px;
}
.menu-content{
    box-shadow: none;
}
.drawer-open ion-pane.pane{
    background-color: rgb(0,0,0);
}
.drawer-open view{
    background-color: rgb(0,0,0);
}
.ion-view.pane{
    transition: opacity .25s ease-in-out;
    -moz-transition: opacity .25s ease-in-out;
    -webkit-transition: opacity .25s ease-in-out;
}
.menu-open ion-view.pane, .drawer-open ion-view.pane{
   /* opacity:0.4;
    */
}
.bar .title.no-nav{
    text-align: left;
    left: 0px !important;
}
.bar .button-icon.ion-navicon{
    margin-left: -20px;
    padding-right: 20px;
}
.bar .title{
    text-align: left;
    left: 16px !important;
}
.modal-wrapper .bar .title{
    text-align: center;
    left: 0px !important;
}
.bar .title.title-center{
    text-align: center;
    left: 0px !important;
    right: 0px !important;
}
.ion-ios7-arrow-back:before{
    content:"\f2ca";
}
.bar .button.button-icon.ion-ios7-arrow-back:before{
    font-size: 17px;
    line-height: 32px;
    padding-right: 100px;
}

之后,我将参考链接添加到index.html文件

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
  <title></title>

  <link rel="manifest" href="manifest.json">

  <!-- un-comment this code to enable service worker
    <script>
      if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('service-worker.js')
          .then(() => console.log('service worker installed'))
          .catch(err => console.log('Error', err));
      }
    </script>-->

  <link href="lib/ionic/css/ionic.css" rel="stylesheet">
  <link href="css/style.css" rel="stylesheet">
  <link href="css/nativeSideMenu.css" rel="stylesheet">
  <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
    <link href="css/ionic.app.css" rel="stylesheet">
    -->

  <!-- ionic/angularjs js -->
  <script src="lib/ionic/js/ionic.bundle.js"></script>

  <!-- cordova script (this will be a 404 during development) -->
  <script src="cordova.js"></script>

  <!-- your app's js -->
  <script src="js/app.js"></script>
  <script src="js/nativeSideMenu.js"></script>
  <script src="js/controllers.js"></script>
</head>

<body ng-app="starter">
  <ion-nav-view></ion-nav-view>
</body>

</html>

然后我将其包含ionic.contrib.NativeDrawer在文件angular.module中。app.js

angular.module('starter', ['ionic', 'starter.controllers','ionic.contrib.NativeDrawer'])

之后,我更新了menu.html模板文件夹中的文件代码,如下所示。

<ion-side-menus>
  <ion-side-menu-content>
    <ion-nav-bar class="bar-stable bar-positive-900">
      <ion-nav-back-button>
      </ion-nav-back-button>
      <ion-nav-buttons side="left">
        <button class="button button-icon button-clear ion-navicon" menu-and-drawer-toggle>
        </button>
      </ion-nav-buttons>
    </ion-nav-bar>
    <ion-pane drawer-menu-content>
      <ion-nav-view name="menuContent"></ion-nav-view>
    </ion-pane>
  </ion-side-menu-content>

  <drawer side="left">
    <ion-content>
      <ion-list>
        <ion-item menu-and-drawer-close ng-click="login()">
          Login
        </ion-item>
        <ion-item menu-and-drawer-close href="#/app/search">
          Search
        </ion-item>
        <ion-item menu-and-drawer-close href="#/app/browse">
          Browse
        </ion-item>
        <ion-item menu-and-drawer-close href="#/app/playlists">
          Playlists
        </ion-item>
      </ion-list>
    </ion-content>
  </drawer>
</ion-side-menus>

现在只需ionic serve在导航抽屉中运行并拥有原生感觉。

使用下面的参考链接了解更多详情

Ref. 1 Ref. 2 Ref. 3


离子 v2+

在Ionic v2+中,我们没有太多工作要做,因为默认情况下它给人以导航抽屉的原生感觉。但是我们可以通过将值传递给typeon来改变这种行为<ion-menu>

<ion-menu type="overlay" [content]="mycontent">...</ion-menu>

根据以下DOC type详情。

菜单的显示类型。默认值因模式而异,请参阅config中的 menuType 。可用选项:“覆盖”、“显示”、“推送”。

希望这对其他人有帮助!

于 2018-05-30T15:47:40.923 回答