Адаптация пользовательской панели навигации мини-программы (идеальная версия)

Апплет WeChat
Адаптация пользовательской панели навигации мини-программы (идеальная версия)

1. Найдите проблему

Функция настройки панели навигации страницы апплета открыта уже несколько дней (если вы не знаете эту функцию, вы можете сначала>>Узнать больше), что значительно увеличивает свободу разработки апплетов.Я считаю, что многие мелкие партнеры уже использовали эту функцию, и я также считаю, что многие мелкие партнеры наступили на те же ямы в процессе разработки этой функции:

  1. Моделей много: высота пользовательской панели навигации не всегда может обеспечить визуальное единство в разных моделях;
  2. Непослушные кнопки-капсулы: элементы панели навигации (текст, значки и т. д.) не совпадают с этой проклятой кнопкой-капсулой;
  3. Полный экран разного размера и странные челки просто сводят с ума.
Точно так же с этими проблемами сталкивается и Сяо Хуэй. Но Сяо Хуэй считает, что решений всегда больше, чем проблем, поэтому он начал собственное исследование:

2. Узнайте

Для того, чтобы понять, как адаптировать, старые правила, я сначала перелистал волну официальных документов, не говоря уже о том, что у чиновника действительно есть такой пункт, чтобы ввести соответствующие детали,>>Нажмите для подробностей:


Из анализа рисунка мы можем получить следующую информацию:

  1. Между Android и iOS есть разница, которая отражается в разнице между верхней и капсульной кнопкой на 6pt.
  2. Высота кнопки Capsule — 32pt, одинаковая для iOS и Android.

Этот. . . , вроде бы толку от L нет? ? Это только для справки об обычном экране, ipx, полноэкранный режим Android вообще не представлен.

С хладнокровием продолжаем анализировать:

  1. Расстояние от кнопки капсулы до нижнего края строки состояния вроде фиксированное?
  2. Эта картина Android кажется немного странной? Панель навигации разделена на строку состояния + строку заголовка?
Если два условия автомобиля верны, наша проблема решена на 80%?

Итак, поспорим:

Первый вопрос: Фиксировано ли расстояние от кнопки капсулы до нижнего края статус бара?

  • Очень просто, пишем строку состояния и устанавливаем высоту через wx.getSystemInfoSync().statusBarHeight
  • На всякий случай мы установили темный цвет фона строки состояния.
js-код:

    var sysinfo = wx.getSystemInfoSync();
    this.setData({ 
         statusBarHeight:sysinfo.statusBarHeight 
    })

wxml-код:

<view class="status-bar" style="height:{{statusBarHeight}}px"></view>

wxs-код:

.status-bar{    background: rgb(141, 71, 71);}

Рендеринг (iPhone6):


Рендеринг (iPhoneX):


Рендеринг (Android):


Это немного хмурится? Да, как видно из скриншотов, iOS такая же, а вот Android как бы другой.

Так какое расстояние? Мы используем артефакт (скриншот WeChat) для измерения:

Андроид:


iOS:


Видно, что расстояние между кнопкой капсулы iOS и строкой состояния составляет: 6 пикселей, Android — 8 пикселей, и после измерения результаты всех моделей iOS и моделей Android одинаковы (из-за нехватки места скриншоты не показаны по порядку, есть Если интересно можете сами померить)

Второй вопрос: панель навигации разделена на строку состояния + строку заголовка?

Из аргументации по первому вопросу ясно, что это действительно так. И по результатам измерения первого вопроса и официальным данным мы можем рассчитать высоту строки заголовка:

Высота панели навигации = высота кнопки капсулы + расстояние между строкой состояния и кнопкой капсулы * 2 Высота панели навигации Android = 32 пикселя + 8 пикселей * 2 = 48 пикселей Высота панели навигации iOS = 32 пикселя + 6 пикселей * 2 = 44 пикселя

*Примечание. Так как капсульная кнопка является родным компонентом, ее единица измерения — пиксели в каждой системе для стабильной производительности, поэтому единица измерения каждой высоты нашей пользовательской панели навигации должна быть пикселями (помните, что не используйте rpx) для идеального соответствия.


3. Решить проблему

Благодаря приведенному выше анализу я считаю, что у каждого может быть идея для решения проблемы.Прежде чем вводить код, Сяо Хуэй нарисует для вас ключевые моменты:

  • При написании пользовательского компонента навигации вам необходимо разделить структуру компонента на две части: строка состояния + строка заголовка.
  • Высоту строки состояния можно получить с помощью wx.getSystemInfoSync().statusBarHeight.
  • Высота строки заголовка: Android: 48px, iOS: 44px
  • Устройство должно быть таким же, как кнопка капсулы, используйте PX
Без лишних слов, приведенный выше код (адрес гитхаба):

js:

Component({   
   properties: {        
    background: {            
        type: String,            
        value: 'rgba(255, 255, 255, 1)'        
    },        
    color: {            
        type: String,            
        value: 'rgba(0, 0, 0, 1)'        
    },        
    titleText: {            
        type: String,            
        value: '导航栏'        
    },        
    titleImg: {            
        type: String,            
        value: ''        
    },        
    backIcon: {            
        type: String,            
        value: ''        
     },        
    homeIcon: {            
        type: String,            
        value: ''        
    },        
    fontSize: {            
        type: Number,            
        value: 16        
    },        
    iconHeight: {            
        type: Number,            
        value: 19       
    },        
    iconWidth: {            
        type:Number,            
        value: 58        
    }    
   },    
attached: function(){        
    var that = this;        
    that.setNavSize();        
    that.setStyle();    
   },    
 data: {
    },    
methods: {        
// 通过获取系统信息计算导航栏高度        
setNavSize: function() {            
var that = this                
    , sysinfo = wx.getSystemInfoSync()                
    , statusHeight = sysinfo.statusBarHeight                
    , isiOS = sysinfo.system.indexOf('iOS') > -1                
    , navHeight;            
if (!isiOS) {                
    navHeight = 48;            
   } else {                
    navHeight = 44;            
}            
that.setData({                
    status: statusHeight,                
    navHeight: navHeight            
  })        
},        
setStyle: function() {            
    var that  = this                
    , containerStyle                
    , textStyle                
    , iconStyle;            
    containerStyle = [                
        'background:' + that.data.background                
        ].join(';');            
        textStyle = [                
        'color:' + that.data.color,                
        'font-size:' + that.data.fontSize + 'px'            
        ].join(';');            
        iconStyle = [                
        'width: ' + that.data.iconWidth + 'px',                
        'height: ' + that.data.iconHeight + 'px'            
        ].join(';');            
        that.setData({               
             containerStyle: containerStyle,                
             textStyle: textStyle,                
             iconStyle: iconStyle            
        })        },        
        // 返回事件        
back: function(){            
    wx.navigateBack({                
        delta: 1            
    })            
    this.triggerEvent('back', {back: 1})        
},        
home: function() {            
    this.triggerEvent('home', {});       
 }   
 }})



wxml:

<view class='nav' style='height: {{status + navHeight}}px'>    
<view class='status' style='height: {{status}}px;{{containerStyle}}'></view>    <view class='navbar' style='height:{{navHeight}}px;{{containerStyle}}'>        <view class='back-icon' wx:if="{{backIcon}}" bindtap='back'>                    <image src='{{backIcon}}'></image>       
     </view>        
<view class='home-icon' wx:if="{{homeIcon}}" bindtap='home'>            
    <image src='{{homeIcon}}'></image>        
</view>        
<view class='nav-icon' wx:if="{{titleImg}}">            
<image src='{{titleImg}}' style='{{iconStyle}}'></image>       
 </view>
        <view class='nav-title' wx:if="{{titleText && !titleImg}}">
            <text style='{{textStyle}}'>{{titleText}}</text>
        </view>
    </view>
</view>

wxss:

.navbar{    position: relative}.back-icon, .home-icon{    width: 28px;    height: 100%;    position: absolute;    transform: translateY(-50%);    top: 50%;    display: flex;}.back-icon{    left: 16px;}.home-icon{    left: 44px}.back-icon image{    width: 28px;    height: 28px;    margin: auto;}.home-icon image{    width: 20px;    height: 20px;    margin: auto;}.nav-title, .nav-icon{    position: absolute;    transform: translate(-50%, -50%);    left: 50%;    top: 50%;    font-size: 0;    font-weight: bold;}

Запуск рендеринга:

Текстовое название:



Подпись к изображению:



4. Резюме

После некоторой демонстрации и практического опыта Xiaohui я, наконец, пришел к приведенному выше окончательному решению, но я надеюсь, что оно будет полезно друзьям.Если друзья сочтут это полезным, не забудьте поставить звезду -->нажми на меня, и другие компоненты будут обновлены в будущем.

Если у вас есть план получше или вы считаете, что с планом Xiaohui возникли проблемы, оставьте сообщение.