整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          干貨:HTML JS中你不一定知道的alert!

          avaweb

          經常做微信或者手機網頁開發的小伙伴們一定有這樣的苦惱,我們經常要在HTML 或者jsp 中輸出一些日志來確認獲取到的數據是不是我們想要的,或者利用輸出的日志來進行排錯,

          不像chrome那樣,有功能強大的dev tools來調試代碼,因為在手機端我們無法看到console.log這樣的日志。

          那么我們通常會alert一下,但是我們alert一個字符串啊什么的還行,alert一個對象的話就不行了,會彈出一個[object Object] 如下圖:

          Javaweb

          那么我今天就來教大家怎么樣alert出對象的信息:

          Javaweb

          方法就是: alert(JSON.stringify(obj, null, 4));//(其中的obj,就是你的js對象)

          是不是很方便,很神奇了?

          我在后續的文章中,會分享更多更實用的開發小技巧給大家,希望大家多多關注!

          • 現在很多App里都內置了Web網頁(Hybrid App),比如說很多電商平臺,淘寶、京東、聚劃算等等,如下圖

          • 上述功能是由Android的WebView實現的,其中涉及到Android客戶端與Web網頁交互的實現
          • 今天我將全面介紹Android通過WebView與JS交互的全面方式

          閱讀本文前請先閱讀:Android開發:最全面、最易懂的Webview詳解


          目錄


          1. 交互方式總結

          Android與JS通過WebView互相調用方法,實際上是:

          • Android去調用JS的代碼
          • JS去調用Android的代碼

          二者溝通的橋梁是WebView

          對于Android調用JS代碼的方法有2種:

          1. 通過WebView的loadUrl()

          2. 通過WebView的evaluateJavascript()

          對于JS調用Android代碼的方法有3種:

          1. 通過WebView的addJavascriptInterface()進行對象映射

          2. 通過 WebViewClient 的shouldOverrideUrlLoading ()方法回調攔截 url

          3. 通過 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回調攔截JS對話框alert()、confirm()、prompt() 消息


          2. 具體分析

          2.1 Android通過WebView調用 JS 代碼

          對于Android調用JS代碼的方法有2種:

          1. 通過WebView的loadUrl()

          2. 通過WebView的evaluateJavascript()

          方式1:通過WebView的loadUrl()

          • 實例介紹:點擊Android按鈕,即調用WebView JS(文本名為javascript)中callJS()
          • 具體使用:

          步驟1:將需要調用的JS代碼以.html格式放到src/main/assets文件夾里

          • 為了方便展示,本文是采用Andorid調用本地JS代碼說明;
          • 實際情況時,Android更多的是調用遠程JS代碼,即將加載的JS代碼路徑改成url即可

          需要加載JS代碼:javascript.html

          // 文本名:javascript

          <!DOCTYPE html>

          <html>

          <head>

          <meta charset="utf-8">

          <title>Carson_Ho</title>

          // JS代碼

          <script>

          // Android需要調用的方法

          function callJS(){

          alert("Android調用了JS的callJS方法");

          }

          </script>

          </head>

          </html>

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19

          步驟2:在Android里通過WebView設置調用JS代碼

          Android代碼:MainActivity.java

          注釋已經非常清楚

          public class MainActivity extends AppCompatActivity {

          WebView mWebView;

          Button button;

          @Override

          protected void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

          setContentView(R.layout.activity_main);

          mWebView =(WebView) findViewById(R.id.webview);

          WebSettings webSettings = mWebView.getSettings();

          // 設置與Js交互的權限

          webSettings.setJavaScriptEnabled(true);

          // 設置允許JS彈窗

          webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

          // 先載入JS代碼

          // 格式規定為:file:///android_asset/文件名.html

          mWebView.loadUrl("file:///android_asset/javascript.html");

          button = (Button) findViewById(R.id.button);

          button.setOnClickListener(new View.OnClickListener() {

          @Override

          public void onClick(View v) {

          // 通過Handler發送消息

          mWebView.post(new Runnable() {

          @Override

          public void run() {

          // 注意調用的JS方法名要對應上

          // 調用javascript的callJS()方法

          mWebView.loadUrl("javascript:callJS()");

          }

          });

          }

          });

          // 由于設置了彈窗檢驗調用結果,所以需要支持js對話框

          // webview只是載體,內容的渲染需要使用webviewChromClient類去實現

          // 通過設置WebChromeClient對象處理JavaScript的對話框

          //設置響應js 的Alert()函數

          mWebView.setWebChromeClient(new WebChromeClient() {

          @Override

          public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {

          AlertDialog.Builder b = new AlertDialog.Builder(MainActivity.this);

          b.setTitle("Alert");

          b.setMessage(message);

          b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

          @Override

          public void onClick(DialogInterface dialog, int which) {

          result.confirm();

          }

          });

          b.setCancelable(false);

          b.create().show();

          return true;

          }

          });

          }

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          • 67
          • 68
          • 69

          特別注意:JS代碼調用一定要在 onPageFinished() 回調之后才能調用,否則不會調用。

          onPageFinished()屬于WebViewClient類的方法,主要在頁面加載結束時調用

          方式2:通過WebView的evaluateJavascript()

          • 優點:該方法比第一種方法效率更高、使用更簡潔。
          • 因為該方法的執行不會使頁面刷新,而第一種方法(loadUrl )的執行則會。
          • Android 4.4 后才可使用
          • 具體使用

          // 只需要將第一種方法的loadUrl()換成下面該方法即可

          mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {

          @Override

          public void onReceiveValue(String value) {

          //此處為 js 返回的結果

          }

          });

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8

          2.1.2 方法對比

          2.1.3 使用建議

          兩種方法混合使用,即Android 4.4以下使用方法1,Android 4.4以上方法2

          // Android版本變量

          final int version = Build.VERSION.SDK_INT;

          // 因為該方法在 Android 4.4 版本才可使用,所以使用時需進行版本判斷

          if (version < 18) {

          mWebView.loadUrl("javascript:callJS()");

          } else {

          mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {

          @Override

          public void onReceiveValue(String value) {

          //此處為 js 返回的結果

          }

          });

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13

          2.2 JS通過WebView調用 Android 代碼

          對于JS調用Android代碼的方法有3種:

          1. 通過WebView的addJavascriptInterface()進行對象映射

          2. 通過 WebViewClient 的shouldOverrideUrlLoading ()方法回調攔截 url

          3. 通過 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回調攔截JS對話框alert()、confirm()、prompt() 消息

          2.2.1 方法分析

          方式1:通過 WebView的addJavascriptInterface()進行對象映射

          步驟1:定義一個與JS對象映射關系的Android類:AndroidtoJs

          AndroidtoJs.java(注釋已經非常清楚)

          // 繼承自Object類

          public class AndroidtoJs extends Object {

          // 定義JS需要調用的方法

          // 被JS調用的方法必須加入@JavascriptInterface注解

          @JavascriptInterface

          public void hello(String msg) {

          System.out.println("JS調用了Android的hello方法");

          }

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10

          步驟2:將需要調用的JS代碼以.html格式放到src/main/assets文件夾里

          需要加載JS代碼:javascript.html

          <!DOCTYPE html>

          <html>

          <head>

          <meta charset="utf-8">

          <title>Carson</title>

          <script>

          function callAndroid(){

          // 由于對象映射,所以調用test對象等于調用Android映射的對象

          test.hello("js調用了android中的hello方法");

          }

          </script>

          </head>

          <body>

          //點擊按鈕則調用callAndroid函數

          <button type="button" id="button1" onclick="callAndroid()"></button>

          </body>

          </html>

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19

          步驟3:在Android里通過WebView設置Android類與JS代碼的映射

          詳細請看注釋

          public class MainActivity extends AppCompatActivity {

          WebView mWebView;

          @Override

          protected void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

          setContentView(R.layout.activity_main);

          mWebView = (WebView) findViewById(R.id.webview);

          WebSettings webSettings = mWebView.getSettings();

          // 設置與Js交互的權限

          webSettings.setJavaScriptEnabled(true);

          // 通過addJavascriptInterface()將Java對象映射到JS對象

          //參數1:Javascript對象名

          //參數2:Java對象名

          mWebView.addJavascriptInterface(new AndroidtoJs(), "test");//AndroidtoJS類對象映射到js的test對象

          // 加載JS代碼

          // 格式規定為:file:///android_asset/文件名.html

          mWebView.loadUrl("file:///android_asset/javascript.html");

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24

          特點

          • 優點:使用簡單

          僅將Android對象和JS對象映射即可

          • 缺點:存在嚴重的漏洞問題,具體請看文章:你不知道的 Android WebView 使用漏洞

          方式2:通過 WebViewClient 的方法shouldOverrideUrlLoading ()回調攔截 url

          • 具體原理:
          1. Android通過 WebViewClient 的回調方法shouldOverrideUrlLoading ()攔截 url
          2. 解析該 url 的協議
          3. 如果檢測到是預先約定好的協議,就調用相應方法

          即JS需要調用Android的方法

          • 具體使用:
          • 步驟1:在JS約定所需要的Url協議
          • JS代碼:javascript.html

          以.html格式放到src/main/assets文件夾里

          <!DOCTYPE html>

          <html>

          <head>

          <meta charset="utf-8">

          <title>Carson_Ho</title>

          <script>

          function callAndroid(){

          /*約定的url協議為:js://webview?arg1=111&arg2=222*/

          document.location = "js://webview?arg1=111&arg2=222";

          }

          </script>

          </head>

          <!-- 點擊按鈕則調用callAndroid()方法 -->

          <body>

          <button type="button" id="button1" onclick="callAndroid()">點擊調用Android代碼</button>

          </body>

          </html>

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20

          當該JS通過Android的mWebView.loadUrl("file:///android_asset/javascript.html")加載后,就會回調shouldOverrideUrlLoading (),接下來繼續看步驟2:

          步驟2:在Android通過WebViewClient復寫shouldOverrideUrlLoading ()

          MainActivity.java

          public class MainActivity extends AppCompatActivity {

          WebView mWebView;

          // Button button;

          @Override

          protected void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

          setContentView(R.layout.activity_main);

          mWebView = (WebView) findViewById(R.id.webview);

          WebSettings webSettings = mWebView.getSettings();

          // 設置與Js交互的權限

          webSettings.setJavaScriptEnabled(true);

          // 設置允許JS彈窗

          webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

          // 步驟1:加載JS代碼

          // 格式規定為:file:///android_asset/文件名.html

          mWebView.loadUrl("file:///android_asset/javascript.html");

          // 復寫WebViewClient類的shouldOverrideUrlLoading方法

          mWebView.setWebViewClient(new WebViewClient() {

          @Override

          public boolean shouldOverrideUrlLoading(WebView view, String url) {

          // 步驟2:根據協議的參數,判斷是否是所需要的url

          // 一般根據scheme(協議格式) & authority(協議名)判斷(前兩個參數)

          //假定傳入進來的 url = "js://webview?arg1=111&arg2=222"(同時也是約定好的需要攔截的)

          Uri uri = Uri.parse(url);

          // 如果url的協議 = 預先約定的 js 協議

          // 就解析往下解析參數

          if ( uri.getScheme().equals("js")) {

          // 如果 authority = 預先約定協議里的 webview,即代表都符合約定的協議

          // 所以攔截url,下面JS開始調用Android需要的方法

          if (uri.getAuthority().equals("webview")) {

          // 步驟3:

          // 執行JS所需要調用的邏輯

          System.out.println("js調用了Android的方法");

          // 可以在協議上帶有參數并傳遞到Android上

          HashMap<String, String> params = new HashMap<>();

          Set<String> collection = uri.getQueryParameterNames();

          }

          return true;

          }

          return super.shouldOverrideUrlLoading(view, url);

          }

          }

          );

          }

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60

          特點

          • 優點:不存在方式1的漏洞;
          • 缺點:JS獲取Android方法的返回值復雜。

          如果JS想要得到Android方法的返回值,只能通過 WebView 的 loadUrl ()去執行 JS 方法把返回值傳遞回去,相關的代碼如下:

          // Android:MainActivity.java

          mWebView.loadUrl("javascript:returnResult(" + result + ")");

          // JS:javascript.html

          function returnResult(result){

          alert("result is" + result);

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7

          方式3:通過 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回調攔截JS對話框alert()、confirm()、prompt() 消息

          在JS中,有三個常用的對話框方法:

          方式3的原理:Android通過 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回調分別攔截JS對話框

          (即上述三個方法),得到他們的消息內容,然后解析即可。

          下面的例子將用攔截 JS的輸入框(即prompt()方法)說明 :

          • 常用的攔截是:攔截 JS的輸入框(即prompt()方法)
          • 因為只有prompt()可以返回任意類型的值,操作最全面方便、更加靈活;而alert()對話框沒有返回值;confirm()對話框只能返回兩種狀態(確定 / 取消)兩個值

          步驟1:加載JS代碼,如下:

          javascript.html

          以.html格式放到src/main/assets文件夾里

          <!DOCTYPE html>

          <html>

          <head>

          <meta charset="utf-8">

          <title>Carson_Ho</title>

          <script>

          function clickprompt(){

          // 調用prompt()

          var result=prompt("js://demo?arg1=111&arg2=222");

          alert("demo " + result);

          }

          </script>

          </head>

          <!-- 點擊按鈕則調用clickprompt() -->

          <body>

          <button type="button" id="button1" onclick="clickprompt()">點擊調用Android代碼</button>

          </body>

          </html>

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22

          當使用mWebView.loadUrl("file:///android_asset/javascript.html")加載了上述JS代碼后,就會觸發回調onJsPrompt(),具體如下:

          • 如果是攔截警告框(即alert()),則觸發回調onJsAlert();
          • 如果是攔截確認框(即confirm()),則觸發回調onJsConfirm();

          步驟2:在Android通過WebChromeClient復寫onJsPrompt()

          public class MainActivity extends AppCompatActivity {

          WebView mWebView;

          // Button button;

          @Override

          protected void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

          setContentView(R.layout.activity_main);

          mWebView = (WebView) findViewById(R.id.webview);

          WebSettings webSettings = mWebView.getSettings();

          // 設置與Js交互的權限

          webSettings.setJavaScriptEnabled(true);

          // 設置允許JS彈窗

          webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

          // 先加載JS代碼

          // 格式規定為:file:///android_asset/文件名.html

          mWebView.loadUrl("file:///android_asset/javascript.html");

          mWebView.setWebChromeClient(new WebChromeClient() {

          // 攔截輸入框(原理同方式2)

          // 參數message:代表promt()的內容(不是url)

          // 參數result:代表輸入框的返回值

          @Override

          public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {

          // 根據協議的參數,判斷是否是所需要的url(原理同方式2)

          // 一般根據scheme(協議格式) & authority(協議名)判斷(前兩個參數)

          //假定傳入進來的 url = "js://webview?arg1=111&arg2=222"(同時也是約定好的需要攔截的)

          Uri uri = Uri.parse(message);

          // 如果url的協議 = 預先約定的 js 協議

          // 就解析往下解析參數

          if ( uri.getScheme().equals("js")) {

          // 如果 authority = 預先約定協議里的 webview,即代表都符合約定的協議

          // 所以攔截url,下面JS開始調用Android需要的方法

          if (uri.getAuthority().equals("webview")) {

          //

          // 執行JS所需要調用的邏輯

          System.out.println("js調用了Android的方法");

          // 可以在協議上帶有參數并傳遞到Android上

          HashMap<String, String> params = new HashMap<>();

          Set<String> collection = uri.getQueryParameterNames();

          //參數result:代表消息框的返回值(輸入值)

          result.confirm("js調用了Android的方法成功啦");

          }

          return true;

          }

          return super.onJsPrompt(view, url, message, defaultValue, result);

          }

          // 通過alert()和confirm()攔截的原理相同,此處不作過多講述

          // 攔截JS的警告框

          @Override

          public boolean onJsAlert(WebView view, String url, String message, JsResult result) {

          return super.onJsAlert(view, url, message, result);

          }

          // 攔截JS的確認框

          @Override

          public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {

          return super.onJsConfirm(view, url, message, result);

          }

          }

          );

          }

          }

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          • 67
          • 68
          • 69
          • 70
          • 71
          • 72
          • 73
          • 74
          • 75
          • 76
          • 77
          • 78

          • Demo地址
          • 上述所有代碼均存放在:Carson_Ho的Github地址 : WebView Demo

          2.2.2 三種方式的對比 & 使用場景


          3. 總結

          • 本文主要對Android通過WebView與JS的交互方式進行了全面介紹

          • 關于WebView的系列文章對你有所幫助
          • Android開發:最全面、最易懂的Webview詳解
          • Android:你不知道的 WebView 使用漏洞
          • 手把手教你構建 Android WebView 的緩存機制 & 資源預加載方案
          • 接下來我會繼續講解其他安卓開發的知識,有興趣可以繼續關注Carson_Ho的安卓開發筆記!!!!

          請評論點贊!因為你們的贊同/鼓勵是我寫作的最大動力!

          窗的類型有非常多種,所以在使用時很容易被濫用,這樣不僅會對用戶帶來困擾,也會讓我們的設計中出現細枝末節的問題。本篇文章分析和總結了不同彈窗的使用場景及工作中的實際應用,知道這些后,以后再也不會“濫用”彈窗啦!

          一、前言

          我們口中常說的彈窗其實是個廣義的范圍,包括了對話框,動作菜單,浮出層,toast,snackbar等,這么多類型的彈窗在使用中很容易混亂或者說濫用,反而得不償失,給用戶帶來更多困擾。故本篇文章主要分析和總結不同彈窗的使用場景及工作中的實際應用。

          官方的設計樣式會提到,但是細節不展開,有需要的可以參閱MD官方文檔和蘋果HIG官方文檔,文檔里介紹的都很細致。

          除了官方文檔,本文還參閱了很多前輩的總結分析,參考鏈接已置于文末。(配圖主要來自體驗過程中的app截圖,安卓部分截圖主要來自MD規范)

          二、什么是彈窗

          在App使用中,彈窗出現的頻率越來越高,運營活動,系統通知,信息反饋,任務引導等。濫用的彈窗會漸漸導致用戶認知疲勞和視覺失調,甚至會出現“習慣性取消”等行為。

          彈窗最主要的功能就是服務于當前主任務之外的支線任務,包括信息傳遞,操作反饋等。

          對話框,警告框,toast……都屬于彈窗,但是使用場景都不一樣。

          在合適的業務場景選擇合適的彈窗組件,能夠保證最基礎的用戶體驗。因為像強干擾類彈窗的使用,對用戶而言,更是一種強加的任務,很容易導致用戶喪失耐心而流失。

          三、彈窗有哪些

          彈窗可以按照是否強制打斷用戶操作來分成兩種,模態彈窗和非模態彈窗(也可以叫做阻斷式彈窗和非阻斷式彈窗)。

          3.1 模態彈窗

          模態彈窗:模態提供了一個專注聚焦的環境,用戶只有完成或者關閉當前任務,才能進行其他任務。

          特點:打斷用戶當前的操作流程,屬于強勢的干擾行為,故運用彈窗需要慎重考慮。

          常用組件:dialog(對話框)/alert(警告框)、popover(浮出層)、action sheet(動作菜單)、activity views(活動視圖)、modal bottom sheet(模態底部菜單)。

          3.2 非模態彈窗

          非模態彈窗:常用于輕量級的操作反饋和信息傳遞,不需要獲取屏幕焦點,用戶可以同時操作屏幕中的其他內容。

          特點:屬于輕量級的反饋,不會對用戶流程產生干擾,但同時又給了用戶反饋和信息。

          常用組件:Toast(吐司),snackbar,Hud(透明指示層)。

          四.具體使用

          4.1 強干擾類——dialog(對話框)/alert(警告框)

          dialog和alert分別是MD和ios的官方彈出框,是最常見的彈窗,兩者功能一樣,在使用上以及樣式上略有區別(下文分析統一稱為彈出框)。

          彈出框通常用來傳達和app及設備相關的重要信息,并且要求用戶操作或反饋,且其出現在屏幕中央,對內容遮擋嚴重,會中斷用戶正常操作。用戶只有完成或者關閉當前任務,才能進行其他任務。

          其官方樣式如下:

          4.1.1 使用場景

          通知用戶app或設備相關的問題:

          通過強干擾通知用戶設備相關問題如備份,低電量等問題;這些潛在問題可能會對用戶造成一定負面的影響。

          再比如app的版本更新,消息通知,首飾引導等都關系到用戶的利益,所以也會用強干擾的方式讓用戶明確知道并選擇。

          輔助用戶完成任務,如系統權限:

          用戶在進行任務的過程中,受到阻攔,必須通過其他輔助操作幫助他完成任務。

          如完成一些任務必須要開啟相應的系統權限:上傳照片要開啟相冊權限;拍小視頻要麥克風權限;出行外賣等產品要開啟定位權限;新建相冊必須要為相冊命名;下載app要登錄itunes賬號。

          用戶主動中斷任務,破壞性操作等:

          用戶中斷當前任務,對之前的操作有一定的影響,或者一些無法挽回的破壞性操作,故需強干擾的彈窗通知,避免用戶因為失誤有了不可挽回的損失。如退出賬號;刪除訂單,活動消息等;放棄編輯。

          操作反饋:

          當操作后的反饋比較重要,會影響用戶接下來的操作或會影響當下的任務,那就需要用強干擾讓用戶明確知道,要完成此操作需要什么,或者接下來會發生什么。

          例如西瓜視頻的結算通過強干擾通知到用戶想要結算應該怎么做。

          運營活動:

          現在用彈出框來傳遞運營活動已經成為一個約定俗成的用法了,雖然ios規范中建議盡量少用彈出框,但公司還是要盈利的,所以基本上所有app都會以這種強干擾的形式來通知用戶“這里有優惠活動”等運營活動。

          這種場景下,彈出框會根據產品以及業務的運營需求及產品的調性做豐富的運營設計,來吸引用戶參加運營活動,需要注意的一點,需要用戶參加的buttom一定要加強,突出。

          功能引導:

          功能引導和運營活動一樣,是產品出于業務角度考慮,用強干擾的方式吸引用戶使用某功能,達到一定的業務目標,如用戶活躍度。

          例如完成訂單后(外賣或商品)引導用戶評價,并給予一定獎勵。如將流量引流到新業務,從而達到新業務推廣目的。

          4.2 強干擾——popover(浮出層)

          浮出層是ios的組件,是用戶點擊屏幕上的某個控件或區域出現在屏幕上方的臨時視圖,它最典型的是包含一個指向它出現位置的箭頭,且浮出層一般在入口下方,整個浮出層應該位于整個屏幕的中上方。

          浮出層最開始主要用于大屏幕的ipad,但由于手機屏幕越來越大,目前也被較多地運用到手機界面中。

          4.2.1 使用場景

          多個常用操作的快捷入口:

          多個常用操作通過popover折疊起來,視覺上更清爽簡潔,同時使用起來也方便,缺點是用戶不能直觀看到,需要一定的學習才能掌握,所以適合于有學習能力用戶群的產品

          呈現頁面中一些折疊的信息:

          屬于浮出層的衍生應用,和上個場景一樣,節約屏幕空間,顯露出一部分,并將剩余信息折疊起來,不影響用戶理解功能,又解決了屏幕空間,若用戶有需求,即可展開探索更多的信息,同樣也會用箭頭等指向出處

          對于新用戶的功能引導或者新功能的引導:

          此類場景也屬于浮出層的衍生應用,主要通過帶指向箭頭的浮層引導用戶學習某個功能,一般需要學習的功能是高亮的,且箭頭指向它。

          4.3 強干擾——action sheet(動作菜單)

          actionsheet是ios系統中特定的警告框,用來響應動作或控件,或者呈現和當前內容相關的兩個及更多的選項。一般在屏幕底部。官方不建議在動作菜單中應用滾動條,所以動作菜單中的選項不能過多。

          4.3.1 使用場景

          當前對象的多個操作或者完成任務的多個選擇:

          對當前對象的的多個操作,如qq中對圖片長按,出現多個對該圖片可進行的操作,幫助完成任務。除了文字列表外,還可以用圖標+宮格式的展示方式,例如分享功能的多個選項。

          執行潛在的破壞性操作前的二次確認:

          當執行潛在的破壞性操作前需再做提醒,避免產生不可挽回的失誤。需注意的是破壞性操作的按鈕需重點突出,一般用紅色,起到警示,危險的提醒作用

          和alert的區別:

          alert主要適用于兩個選項,而actionsheet可以有多個功能選項,且展示形式更多樣。前文講過,alert也有破壞性操作提醒的場景使用。

          兩者相比,alert出現在屏幕中央,actionsheet出現在屏幕底部。視覺角度上alert相較于actionsheet更有阻斷感,對用戶而言干擾性更大。

          另一方面底部的actionsheet從手勢操作的角度上來看,操作更方便,更容易對此作出選擇或關閉。所以alert更加適用于嚴重后果的破壞性操作提醒。

          4.4 強干擾——activity view(活動視圖)

          活動視圖是ios組件,是針對當前頁面提供的一系列任務和服務,例如復制,收藏,查找等。系統提供了許多內置活動,包括打印,信息和AirPlay。

          這些任務始終首先出現在活動視圖中,無法重新排序。無需創建執行這些內置任務的自定義活動。活動視圖還顯示來自其他應用的共享和操作擴展。

          4.5 強干擾類——modal bottom sheet(模態底部菜單)

          Bottom sheet是MD的組件,MD中底部菜單有兩種,一種是Standard bottom sheet(標準底部菜單),另一種是Modal bottom sheet(模態底部菜單)。

          MD的模態底部菜單和iOS的action sheet類似,它阻止用戶與屏幕其他地方交互,通過聚焦的底部菜單提供了更多的選項和功能。它可以是內聯菜單和簡單對話框的替代方案,為內容,圖標和動作提供了額外的空間。

          規范建議,模態底部淡淡的初始垂直位置的上限為屏幕高度的50%。內容超過屏幕高度50%的模態菜單可以在整個屏幕上拉動,在內部滾動以訪問其余項目。同樣他的展現方式有列表式,也可有宮格式

          4.6 輕反饋——snackbar

          snackbar是android專有控件,是出現在屏幕底部的提供有關app相關的簡短信息提醒,它屬于輕量級的信息提醒,一般出現幾秒后就會自動消失,不會中斷用戶操作。

          snackbar往往由一條文案+一個引導性按鈕(可選,按鈕可以引導用戶進一步操作)組成,帶有一定的交互性。因為它自動會消失,所以它一定沒有取消或者不要等否定性按鈕。

          4.6.1 使用場景

          傳達輕量級的信息和操作反饋,可以引導用戶操作:

          傳達輕量級的信息或反饋,并且可以引導用戶進行下一步行為,但并不強制用戶操作。比如chrome添加書簽時,可以進一步對新加的書簽進行編輯;刪除書簽時防止用戶后悔,提供一個撤銷按鈕。

          4.7 輕反饋——Toas

          Toast是android專有的控件,原先的MD規范中,toast是和snackbar放在一起講的,翻閱了最新的MD規范,snackbar里找不到關于toast的相關介紹(有小伙伴找到的望提醒一下)。

          Toast應該包含在snackbar里了,當snackbar沒有按鈕其實就是toast了,不過這邊還是把Toast單獨拿出來分析

          4.7.1 使用場景

          傳達輕量級的信息和操作反饋,且不需要用戶操作:

          適用于通知用戶不重要的信息和操作反饋,且不會對用戶當前的任務有影響,因為不能交互,且幾秒后消失,所以用戶很可能忽略,所以該類信息相對而言沒那么重要。

          雖然toast是android專有樣式,但現在很多ios版本的系統中都使用了改良版的“toast”,因為輕反饋,不打斷用戶操作,同時又能通知信息和操作反饋,對用戶而言及其友好,但是不易傳達過多的文字,因為用戶很有可能會忽略。

          ios文檔中的feedback中有建議:反饋可以幫助人們了解應用正在做什么,發現他們下一步可以做什么,并了解行動的結果。所以實際應用中,既要不打擾用戶,又要能引起用戶注意,還要和產品設計相協調。

          比如結合了文字和icon的樣式,再比如用較為突出的背景色,位置的話在中央,頂部,底部,都會出現,會根據具體的業務來選擇合適的位置。一般出現的位置會和操作內容在一起,這樣用戶才能清晰有效地得到即時反饋。

          下方例舉的toast案例因為選用了比內容更為突出的背景色,相比較上方案例的toast更易被用戶發現和察覺,達到通知用戶的目的。

          4.8 輕反饋——Hud

          Hud透明指示層,ios專用控件,典型的就是音量調節的彈窗樣式。部分改良的toast,在樣式上有借鑒學習Hud。

          五.總結

          5.1 對比總結

          Dialog/Alert:

          當信息或操作非常重要,并且必須要由用戶做決定或者操作才能繼續,一般用alert,更適用于用戶判斷選擇。

          Modal bottom sheet/Action sheet:

          稍弱于dialog/alert,更著重于提供更多的功能和選項時使用。

          Activity view:

          是針對當前頁面提供的一系列額外的任務和服務。

          Popover:

          使用更側重于指向性,更適用于信息或功能折疊。

          Toast:

          不太重要的信息提醒和操作反饋,更適用于不需用戶響應或反饋的場景。

          snackbar:

          不太重要的信息提醒和操作反饋,可以交互,但并不強制,更適用于可以引導用戶進行下一步或者一些撤銷上一步的場景。

          Hud:

          音量調節。

          5.2 其他

          了解了每個彈窗組件的用法,下次就可以根據實際業務設計合適的彈窗了,不過官方規范或者文章的建議也都只是參考,實際工作中還是要靈活變通,設計的目標是幫助用戶更好更快的解決問題。

          以上就是我對彈窗相關知識的總結,總結的過程中也對官方規范彈窗部分的內容再次熟悉了好幾遍,因為看的英文,所以理解上可能稍微有些不足,有不對的地方,還希望大家批評指正。(推薦大家多看看官方設計規范,就像一本非常實用的設計工具書,對于實際工作還是非常有幫助的)

          六.參考資料

          再次感謝前輩的經驗分享!

          這個控件叫什么系列之toast的曾經,現在,與未來 https://www.uisdc.com/ui-element-toast

          如何設計App中的提示控件(toast) https://zhuanlan.zhihu.com/p/22405748

          iOS和Android規范解析——底部浮層(上)https://www.jianshu.com/p/8bdfbc0a9339

          iOS和Android規范解析——提示框(Toast)對比 https://www.jianshu.com/p/e1beeacbea32

          不要濫用對話框!細說 iOS Alert View 與 Action Sheet https://zhuanlan.zhihu.com/p/20189186

          App設計中,6組常見組件的區別和用法 http://www.woshipm.com/pd/873075.html

          APP提示框架詳解:Toast提示、Snackers和Alert http://www.woshipm.com/pmd/296674.html

          本文由 @麥子_Maizi 原創發布于人人都是產品經理。未經許可,禁止轉載

          題圖來自Unsplash,基于CC0協議


          主站蜘蛛池模板: 成人精品一区久久久久| 亚洲一区二区三区免费| 久久精品道一区二区三区| 视频一区视频二区在线观看| 精品日本一区二区三区在线观看| 成人国产精品一区二区网站| 亚洲av无码一区二区三区乱子伦 | 国产一区二区三区在线观看免费| 欧洲精品一区二区三区| 久久久久无码国产精品一区| 亚洲第一区在线观看| 免费高清在线影片一区| 日韩一区二区在线观看视频| 暖暖免费高清日本一区二区三区 | 国产精品视频无圣光一区| 日韩精品无码一区二区三区免费 | 亚洲一区二区三区国产精品无码| 国产福利一区视频| 亚洲av无码一区二区三区四区| 麻豆AV一区二区三区久久| 91一区二区在线观看精品| 国产99精品一区二区三区免费 | 亚洲av无码一区二区三区天堂古代 | 国产日韩精品一区二区在线观看播放 | 精品无码人妻一区二区三区| 少妇一夜三次一区二区| 久久精品国内一区二区三区| 日韩一区二区在线播放| 国产在线观看91精品一区| 国产不卡视频一区二区三区| 国产伦一区二区三区高清 | 国产一区二区高清在线播放| 无码日韩精品一区二区免费暖暖| 亚洲一区二区在线免费观看| 日本精品一区二区三本中文| 国产日韩高清一区二区三区| 亚洲精品色播一区二区| 亚洲老妈激情一区二区三区| 成人在线一区二区| 国精产品一区一区三区有限在线| 亚洲第一区精品日韩在线播放|