沉浸式彈層越來越多,開發該怎麼做好彈層體驗?
theme: v-green highlight: atom-one-dark
本文為掘金社群首發簽約文章,14天內禁止轉載,14天后未獲授權禁止轉載,侵權必究!
前言
當前 App 的設計趨勢越來越希望給使用者沉浸式體驗,這種設計會讓使用者儘量停留在當前的介面,而不需要太多的跳轉,這就需要引入彈層。比如,抖音引入購物功能後,就實現了在觀看視訊介面可以通過彈層完成加入購物車、下單操作,無需離開當前的視訊介面。本篇我們就來講講彈層這塊需要注意哪些使用者體驗。
彈層的形式選擇
彈層從形式上來說有中間彈層、左側彈層、右側彈層、底部彈層和頂部彈層,如下圖所示。 移動端經過這麼多年的發展,不同的彈層的應用場景相對來說比較固定。因此,在選擇的時候,建議遵循現有的習慣來選擇合適的彈層。
- 中間彈層:通常用於詢問對話方塊形式,例如退出登入、刪除操作的二次確認。
- 左側彈層:通常用於抽屜式的個人中心或設定介面,這種一般是底部欄無法放下個人中心類介面的時候一個不錯的選擇。
- 右側彈層:通常用於做資料篩選,典型的場景是購物類應用的精準篩選。
- 底部彈層:這種非常常見,如我們提到的目前抖音的商品購買,還有像單選、多選、級聯選擇、時間選擇等等。
- 頂部彈層:頂部彈層一般也是用於篩選,比較常見的是列表表頭的篩選,或者導航欄帶類似 PC 端的下拉類的篩選。
這裡需要提兩個比較通用的原則:
- 彈層出現的位置應當儘量靠近觸發互動的位置,比如點選導航欄左上角的按鈕通常會從左側彈出。
- 蒙層的顏色要根據實際情況來定,一般都是黑色半透明的蒙層,但是主要面對是為了讓使用者能夠看清蒙層底下的內容,比如如果是在視訊播放頁面疊加蒙層就會影響使用者體驗了。
接下來我們依次來用 Flutter 實現上述的5類彈層,並講講一些體驗要點。
中間彈層
中間彈層在 Flutter中可以通過showDialog
和 ShowCupertinoDialog
(iOS 風格)實現,下面是示例程式碼。
dart
showDialog(
context: context,
barrierDismissible: false,
builder: (_) => AlertDialog(
title: const Text('操作提醒'),
content: const Text('確認要進行此操作嗎?'),
actionsAlignment: MainAxisAlignment.end,
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('取消'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text(
'刪除',
style: TextStyle(color: Colors.red),
),
),
],
),
);
這裡有一個體驗要素是是否支援點選底部的黑色蒙層隱藏彈層。通常來說,如果是二次確認類操作,建議不要點選蒙層隱藏。因為使用者的操作目的性非常明確,如果不小心誤觸的話,使用者還得再點選一次。這個時候需要設定barrierDismissible
為 false
。
左右抽屜彈層
在 Flutter 的 Scaffold
中 提供了兩個屬性來設定左側抽屜和右側抽屜彈層,對應的引數分別是 drawer
和 endDrawer
。我們來看看具體的程式碼。
dart
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('左右抽屜彈層'),
backgroundColor: Colors.red[800],
leading: Builder(builder: (context) {
return IconButton(
onPressed: () {
Scaffold.of(context).openDrawer();
},
icon: const Icon(
Icons.menu,
),
);
}),
actions: [
Builder(builder: (context) {
return IconButton(
onPressed: () {
Scaffold.of(context).openEndDrawer();
},
icon: const Icon(
Icons.filter_list_alt,
),
);
}),
],
),
drawer: Container(
width: MediaQuery.of(context).size.width * 3 / 4,
color: Colors.white,
child: Center(
child: TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('收起'),
),
),
),
endDrawer: Container(
width: MediaQuery.of(context).size.width * 3 / 4,
color: Colors.blue,
child: Center(
child: TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text(
'收起',
style: TextStyle(
color: Colors.white,
),
),
),
),
),
body: const Center(child: Text('抽屜示例')),
);
}
實現的效果如下圖所示。實用左側或右側彈層需注意三個體驗要素:
- 寬度:建議設定為螢幕寬度的3/4,這種寬度抽屜的顯示內容足夠寬,而底下的蒙層點選區域寬度也比較合適點選退出彈層。
- 頂部內容區域需要注意留出一定的頭部位置(比如左側通常會放頭像+暱稱),一個是美觀,一個是要避免顯示內容碰到了手機螢幕的挖孔位置。
- 一般側邊彈層點選蒙層都會支援收起,所以建議保留這個操作習慣,而不是非得點彈層的某個按鈕才關閉彈層。
頂部彈層
頂部彈層在 Flutter 中需要自己去實現,一個比較好的方式是使用 showGeneralDialog
來實現。這裡有個技巧是實用 Column
元件可以讓內容區靠頂部,然後利用動畫實現從上往下滑的彈出效果。下面是實現程式碼,實際通過這種方式可以實現底部,左側,右側和中間的彈層。
dart
showGeneralDialog(
context: context,
barrierDismissible: true,
transitionDuration: const Duration(milliseconds: 300),
barrierLabel: MaterialLocalizations.of(context).dialogLabel,
barrierColor: Colors.black.withOpacity(0.5),
pageBuilder: (context, _, __) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: Card(
margin: const EdgeInsets.all(0),
child: ListView(
shrinkWrap: true,
children: <Widget>[
ListTile(
title: const Text('選項 1'),
onTap: () => Navigator.of(context).pop('1'),
),
ListTile(
title: const Text('選項2'),
onTap: () => Navigator.of(context).pop('2'),
),
ListTile(
title: const Text('選項3'),
onTap: () => Navigator.of(context).pop('3'),
),
],
),
),
),
],
);
},
transitionBuilder:
(context, animation, secondaryAnimation, child) {
return SlideTransition(
position: CurvedAnimation(
parent: animation,
curve: Curves.easeOut,
).drive(Tween<Offset>(
begin: const Offset(0, -1.0),
end: Offset.zero,
)),
child: child,
);
},
);
效果如下所示,頂部彈層彈出的方向最好是從上到下,如果是從下到上的話移動距離過長,會覺得很突兀。
底部彈層
底部彈層和頂部彈層其實是類似的,而且更為常見一點。之前在文章底部彈窗ModelBottomSheet詳解有過介紹,這裡就不再講具體實現了。說一下底部彈層的幾個體驗要點:
- 彈出方向從底部往上彈出,動畫時長建議200-300毫秒;
- 如果是多選這種需要二次確認操作的,需要在頂部提供確認和取消按鈕;
- 適用選項不太多的場景,如果選擇的內容很多建議單獨跳轉到選擇頁面完成,並且支援模糊搜尋匹配選項;
- 需要區分選中項,讓使用者知道之前的選項;
- 如果涉及到網路請求,建議是在網路請求完成後再關閉彈層,因為有可能操作失敗導致使用者需要再次操作。
總結
本篇介紹了各類彈層開發過程的體驗注意點,同時給出了示例程式碼。隨著沉浸式體驗的推動,彈層會越來越多,因此建議各位開發同學也能夠多多思考彈層如何改善使用者體驗,雖然咱不是產品經理也不是設計師,但是從開發角度給產品和設計一些專業的意見,也是能夠“提升話語權”的,嘿嘿!
- 屌炸天!國外同行這樣用Chat GPT提高Flutter開發的效率!
- Flutter 增強版的頁面懸浮按鈕(FloatingActionButton)
- 介紹一個令強迫症討厭的小紅點元件
- 我用了幾行程式碼就搞定了介面變灰效果
- 不就是一個空白頁,有必要那麼講究嗎?
- 花裡胡哨的文字特效,你學會了嗎?
- 這一篇讓你搞定 Flutter 的資料表格
- 用 Flutter 輕鬆做個紅包介面
- 沉浸式彈層越來越多,開發該怎麼做好彈層體驗?
- 列表的載入過程很重要的!
- 這個表單打死我也不填!
- 例項講述開發中的圖片使用者體驗要點
- C 位出道按鈕的自我獨白
- Flutter 繪製3D效果動畫
- 封裝一個有趣的 Loading 元件
- 普通的載入千篇一律,有趣的 loading 萬里挑一
- 由點匯聚成字的動效炫極了
- 給滅霸點顏色看看
- 來看光影流動之美
- Flutter 實現背景圖片毛玻璃效果