⑴ 6、控制項系列之Action Sheet(動作菜單/動作面板/行動列表)
Action Sheet(動作菜單/動作面板/行動列表)是由用戶操作後觸發的一種特定的模態彈出框 ,呈現一組與當前情境相關的兩個或多個選項。用戶可以使用Action Sheet啟動某個任務,或者確認是否開始執行某個可能具有破壞性的操作。Action Sheet屬於iOS規范,近年來android平台也出現了類似功能的控制項。
如何使用
提供完成一項任務的多個選項
移動設備屏幕空間是寶貴的,不可能把所有選項都羅列在一個頁面上,如果反其道而行把相關程度非常高的操作分割到多個頁面上,又會造成操作繁瑣體驗不連續的感覺。Action Sheet能承載較多內容,而且僅覆蓋當前屏幕的一部分,即不會對用戶心流有很大的干擾,操作也非常便捷。適合呈現與當前任務相關的多個選項。
選項較少可使用列表模式,選項過多時,不建議在列表模式中滾動,因為選項的觸發橫向區域很大,在滾動過程中很容易不小心誤點了其中一個。
宮格模式適用於選項非常多的情況,並且能以圖標形式展現選項,常見於分享到其他社交App或使用第三方App打開文件的場景。使用宮格模式建議將相關選項分組,如果某組的數量太多,可以在屏幕右邊緣露出部分圖標,暗示可以橫向滑動查看更多選項。
注意:Action Sheet中的選項點擊後會立即執行任務,而不是僅僅填寫一個選項,它不能用在表單中,表單單選應當使用Picker、Segment Control、Radio Button等控制項。
危險操作二次確認
用戶在使用過程中,出現刪除、未保存退出等可能產生潛在風險的行為時,應當彈出Action Sheet,讓用戶有機會停下來充分考慮當前操作可能導致的危險結果,並將危險操作用紅色標注,為他們提供其它替代的安全選項。Action Sheet是可以連續彈出的,例如第一個Action Sheet中選擇刪除,第二個Action Sheet中確認刪除。此外,如果危險的情況並非由用戶主動發起或者嚴重影響系統本身的完整性,應該使用Alert(這是Alert和Aciton Sheet最大的區別)。
不同屏幕尺寸的呈現樣式
在iPhone屏幕上,為了便於單手持握時操作,Action Sheet通常占據屏幕底部區域。在屏幕較大的iPad上,如果繼續顯示在屏幕底部,注意力切換和手指移動的路徑會很長,頻繁使用會比較累,因此iPad的Action Sheet通常在觸發區域附近以Popover(彈出式氣泡)呈現。
關閉Action Sheet可以通過點擊「取消」按鈕和空白區域。Action Sheet以Popover呈現時不需要「取消」按鈕,因為點擊寬廣的空白區域關閉更方便。
清晰准確的描述
如果一個頁面有多個喚起Action Sheet的對象,例如文件列表,點擊某個文件彈出Action Sheet後遮蓋了頁面,用戶不知道當前操作的文件是哪個,也許就會引發誤操作。因此,在頁面有多個喚起對象或選項本身不夠明晰的情況下,提供清晰准確的描述是非常有必要的。
合理的視覺強調手法
出於業務方面的考慮,有時我們希望用戶更多的點擊其中某個選項。例如豆瓣為了更好的把內容引入廣播里傳播,特地在Action Sheet把「推薦廣播」放到第一位獨佔一行,但是線性圖標和淺色的文字比起下面的面性圖標看上去反倒是讓「推薦廣播」像Action Sheet的描述說明而不是可以點擊的按鈕。
好在後來的版本豆瓣和LOFTER都改過來,想要某個選項更突出應該採取合理的視覺強調手法。
相關資料
Android對應的控制項
Android有2個使用場景和Action Sheet相似的控制項。第一個是Modal Bottom Sheet(模態底部菜單),和Action Sheet最大的區別是沒有「取消」按鈕,因為Android有物理Back導航鍵。
另一個是Simple dialogs(簡易對話框),從屏幕中央彈出,沒有「取消」按鈕,通過點擊空白區域關閉。微博、豆瓣的Android版使用了這個控制項。
Action圖標不等同於分享圖標
吆喝科技曾用A/B Test幫助墨跡天氣優化分享按鈕的點擊率,在准備的4個分享圖標方案中,方案2撥得頭籌,相對於原始方案點擊率暴漲近20%!(詳見 http://www.appadhoc.com/blog/mojitianqi-fenxiangtubiao/ )
一方面我們可以得出用戶對分享圖標認知比較集中,對Apple原生的圖標很熟悉的結論。事實上Apple規范中對此圖標的定義是喚起模態視圖(Modal View)的Action圖標,並非特指分享功能。
iOS支持非相冊文件上傳
普遍認為iOS上傳內容時,Action Sheet只有選擇相冊、打開攝像頭拍照這兩個選項。事實並非如此,網盤類App使用標準的API,能從在Action Sheet中選擇iCloud或者其他網盤跨雲傳輸,突破了只能上傳本機內容的限制
什麼把Activity View稱為宮格模式
熟讀iOS規范的讀者會發現,iOS 10規范新增了Activity View控制項( https://developer.apple.com/ios/human-interface-guidelines/ui-views/activity-views/ ),通過閱讀多個版本的iOS規范,我發現Activity View是從Action Sheet演化出來的,除了由系統本身使用,布局是宮格而非列表外,並沒有其他不同。再考慮到用於分享功能的宮格Action Sheet大家非常熟悉,因此把Activity View歸為宮格模式。
⑵ android 怎麼實現點擊菜單在頂部和底部同時呼出不同的菜單選項
菜單是用戶界面中最常見的元素之一,使用非常頻繁,在Android中,菜單被分為如下三種,選項菜單(OptionsMenu)、上下文菜單(ContextMenu)和子菜單(SubMenu),以下說的是創建OptionsMenu
一、概述
public boolean onCreateOptionsMenu(Menu menu):使用此方法調用OptionsMenu。
public boolean onOptionsItemSelected(MenuItem item):選中菜單項後發生的動作。
public void onOptionsMenuClosed(Menu menu):菜單關閉後發生的動作。
public boolean onPrepareOptionsMenu(Menu menu):選項菜單顯示之前onPrepareOptionsMenu方法會被調用,你可以用此方法來根據打當時的情況調整菜單。
public boolean onMenuOpened(int featureId, Menu menu):單打開後發生的動作。
二、默認樣式
默認樣式是在屏幕底部彈出一個菜單,這個菜單我們就叫他選項菜單OptionsMenu,一般情況下,選項菜單最多顯示2排每排3個菜單項,這些菜單項有文字有圖標,也被稱作Icon Menus,如果多於6項,從第六項開始會被隱藏,在第六項會出現一個More里,點擊More才出現第六項以及以後的菜單項,這些菜單項也被稱作Expanded Menus。下面介紹。
1.main.xml
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextViewandroid:layout_width="wrap_content"
android:layout_height="wrap_content"android:text="請點擊Menu鍵顯示選項菜單"
android:id="@+id/TextView02"/>
</LinearLayout>
2。重載onCreateOptionsMenu(Menu menu)方法
重載onCreateOptionsMenu(Menu menu)方法,並在此方法中添加菜單項,最後返回true,如果false,菜單則不會顯示。
(Menumenu)
@Override
(Menumenu){
/*
*
*add()方法的四個參數,依次是:
*
*1、組別,如果不分組的話就寫Menu.NONE,
*
*2、Id,這個很重要,Android根據這個Id來確定不同的菜單
*
*3、順序,那個菜單現在在前面由這個參數的大小決定
*
*4、文本,菜單的顯示文本
*/
menu.add(Menu.NONE,Menu.FIRST+1,5,"刪除").setIcon(
android.R.drawable.ic_menu_delete);
//setIcon()方法為菜單設置圖標,這里使用的是系統自帶的圖標,同學們留意一下,以
//android.R開頭的資源是系統提供的,我們自己提供的資源是以R開頭的
menu.add(Menu.NONE,Menu.FIRST+2,2,"保存").setIcon(
android.R.drawable.ic_menu_edit);
menu.add(Menu.NONE,Menu.FIRST+3,6,"幫助").setIcon(
android.R.drawable.ic_menu_help);
menu.add(Menu.NONE,Menu.FIRST+4,1,"添加").setIcon(
android.R.drawable.ic_menu_add);
menu.add(Menu.NONE,Menu.FIRST+5,4,"詳細").setIcon(
android.R.drawable.ic_menu_info_details);
menu.add(Menu.NONE,Menu.FIRST+6,3,"發送").setIcon(
android.R.drawable.ic_menu_send);
returntrue;
}
3。為菜單項注冊事件
使用onOptionsItemSelected(MenuItem item)方法為菜單項注冊事件
(MenuItemitem)
@Override
(MenuItemitem){
switch(item.getItemId()){
caseMenu.FIRST+1:
Toast.makeText(this,"刪除菜單被點擊了",Toast.LENGTH_LONG).show();
break;
caseMenu.FIRST+2:
Toast.makeText(this,"保存菜單被點擊了",Toast.LENGTH_LONG).show();
break;
caseMenu.FIRST+3:
Toast.makeText(this,"幫助菜單被點擊了",Toast.LENGTH_LONG).show();
break;
caseMenu.FIRST+4:
Toast.makeText(this,"添加菜單被點擊了",Toast.LENGTH_LONG).show();
break;
caseMenu.FIRST+5:
Toast.makeText(this,"詳細菜單被點擊了",Toast.LENGTH_LONG).show();
break;
caseMenu.FIRST+6:
Toast.makeText(this,"發送菜單被點擊了",Toast.LENGTH_LONG).show();
break;
}
returnfalse;
}
4.完整代碼
packagecom.android.menu;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.view.Menu;
importandroid.view.MenuItem;
importandroid.widget.Toast;
{
/**.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
(Menumenu){
/*
*
*add()方法的四個參數,依次是:
*
*1、組別,如果不分組的話就寫Menu.NONE,
*
*2、Id,這個很重要,Android根據這個Id來確定不同的菜單
*
*3、順序,那個菜單現在在前面由這個參數的大小決定
*
*4、文本,菜單的顯示文本
*/
menu.add(Menu.NONE,Menu.FIRST+1,5,"刪除").setIcon(
android.R.drawable.ic_menu_delete);
//setIcon()方法為菜單設置圖標,這里使用的是系統自帶的圖標,同學們留意一下,以
//android.R開頭的資源是系統提供的,我們自己提供的資源是以R開頭的
menu.add(Menu.NONE,Menu.FIRST+2,2,"保存").setIcon(
android.R.drawable.ic_menu_edit);
menu.add(Menu.NONE,Menu.FIRST+3,6,"幫助").setIcon(
android.R.drawable.ic_menu_help);
menu.add(Menu.NONE,Menu.FIRST+4,1,"添加").setIcon(
android.R.drawable.ic_menu_add);
menu.add(Menu.NONE,Menu.FIRST+5,4,"詳細").setIcon(
android.R.drawable.ic_menu_info_details);
menu.add(Menu.NONE,Menu.FIRST+6,3,"發送").setIcon(
android.R.drawable.ic_menu_send);
returntrue;
}
@Override
(MenuItemitem){
switch(item.getItemId()){
caseMenu.FIRST+1:
Toast.makeText(this,"刪除菜單被點擊了",Toast.LENGTH_LONG).show();
break;
caseMenu.FIRST+2:
Toast.makeText(this,"保存菜單被點擊了",Toast.LENGTH_LONG).show();
break;
caseMenu.FIRST+3:
Toast.makeText(this,"幫助菜單被點擊了",Toast.LENGTH_LONG).show();
break;
caseMenu.FIRST+4:
Toast.makeText(this,"添加菜單被點擊了",Toast.LENGTH_LONG).show();
break;
caseMenu.FIRST+5:
Toast.makeText(this,"詳細菜單被點擊了",Toast.LENGTH_LONG).show();
break;
caseMenu.FIRST+6:
Toast.makeText(this,"發送菜單被點擊了",Toast.LENGTH_LONG).show();
break;
}
returnfalse;
}
@Override
publicvoidonOptionsMenuClosed(Menumenu){
Toast.makeText(this,"選項菜單關閉了",Toast.LENGTH_LONG).show();
}
@Override
(Menumenu){
Toast.makeText(this,
"選項菜單顯示之前onPrepareOptionsMenu方法會被調用,你可以用此方法來根據打當時的情況調整菜單",
Toast.LENGTH_LONG).show();
//如果返回false,此方法就把用戶點擊menu的動作給消費了,onCreateOptionsMenu方法將不會被調用
returntrue;
}
}
5.運行效果