當下主流 APP , Hybrid app 中需要熟練掌握的交互知識(二)

如果感覺略有用處,點贊支持下作者。上一篇將關于 WebView 的設置仔細的捋了一遍,我們通過 WebViewController 這個類完成了所有 WebView 的設置,并且在布局的時候,只需在布局文件中引入這個類的完整包名,前提是這個類要繼承于 WebView,就可以完成所有 WebView 的設置,具體可參考上一篇 當下主流 APP,Hybrid app 中需要熟練掌握的交互知識(一) 其實有人就說到了,現在有現成的框架可,那我的出發點是從自己動手開始,再去接觸框架,這個系列我們一步步來!

那么本篇將就以下幾點展開:

  • 頁面布局相同情況下Activity 的 共用問題。

  • 在原生與網頁混合的開發狀態下,如何確定頁面跳轉以及參數傳遞。

  • 根據服務端發送的 Js 接口名去做具體實現

Activity 共用

這是當下很多 WebApp 都在使用的一個套路,除了避免了創建多個 Activity 后影響性能之外,還可以保持項目「友好」的結構!這樣的處理大多適應于這樣的場景:

  • 頁面布局上方只有一個 ToolBar 或者 ActionBar 等等的標題欄

  • 下方則是一個 WebView 用于呈現網頁內容

  • 如此則可以將共同的屬性提取出來,WebView 則不用管,都是一致的東西。ToolBar 上無論是標題還是按鈕的設置,當點擊了某處后我們會進入我們在本地實現的網頁接口,具體的原理請看下面的詳細解釋!

一 、建立共用的 Activity:

我們將之命名為 NewWebViewActivity

//獲取到消息處理類傳過來的 url 網址
String url = getIntent().getStringExtra("url");
//獲取到消息處理類傳過來的動畫操作
int anim = getIntent().getIntExtra("animation", 0);
if (url == null) {
   finish();
}else if (url.equals(Constants.urlHostBase + Constants.urlLogIn)){
   baseWebView.loadUrl(url);
   topToolbar.setVisibility(View.GONE);
} else {
   baseWebView.loadUrl(url);
   //用動畫文件判斷新開頁面
   if (anim == R.anim.slide_right_out) {  //當所有的新開頁面 是從右往左打開時(表示新開頁面)
        //添加返回按鈕
        backImageView.setImageResource(R.drawable.returns);
        //變為顯示狀態
        backImageView.setVisibility(View.VISIBLE);
        //返回鍵點擊事件
        backImageView.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               finish(); //關閉頁面
               //設置頁面退出動畫為從左往右退出
               overridePendingTransition(R.anim.none, R.anim.slide_right_out);
           }
         });
    }
}

可以看到,并沒有多少邏輯。我們這樣就可以所有新開的頁面添加一個返回鍵了,前提是有一個消息處理的類來完成打開頁面的 url 參數設置,以及動畫參數設置,其實實現起來也是很簡單!往下看

二 、建立共用的 Activity 的布局:

我們緊接著需要將我們這個 Activity 布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_new_web_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:theme="@android:style/Animation.Toast"
    android:background="@android:color/white"
    tools:context="com.lansum.eip.activity.NewWebViewActivity">
    <!-- 標題欄 -->
    <android.support.v7.widget.Toolbar
        android:id="@+id/web_top_toolbar"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:layout_alignParentTop="true"
        android:background="#00a6ff"/>
    <!-- WebView -->
    <com.lansum.eip.webview.WebViewController
        android:id="@+id/base_web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/web_top_toolbar" />
    <!-- 標題欄右上角圖片點擊按鈕 默認隱藏狀態 下同 -->
    <ImageView
        android:id="@+id/right_Button"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_alignRight="@id/web_top_toolbar"
        android:layout_alignTop="@id/web_top_toolbar"
        android:layout_marginRight="16dp"
        android:layout_marginTop="30dp"
        android:visibility="gone" />
    <!-- 標題欄正中顯示的標題 根據點擊區域切換標題內容 -->
    <TextView
        android:id="@+id/toolbar_text_top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@id/web_top_toolbar"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="32dp"
        android:textColor="@android:color/white"
        android:textSize="18sp" />
    <!-- 標題欄左上角用于關閉打來頁面的圖片按鈕 -->
    <ImageView
        android:id="@+id/back_web"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_alignLeft="@id/web_top_toolbar"
        android:layout_alignTop="@id/web_top_toolbar"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="30dp"
        android:visibility="gone" />
    <!-- 右上角文字點擊按鈕 -->
    <TextView
        android:id="@+id/right_Button_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@id/web_top_toolbar"
        android:layout_alignTop="@id/web_top_toolbar"
        android:layout_marginRight="16dp"
        android:layout_marginTop="32dp"
        android:textColor="@android:color/white"
        android:textSize="18sp"
        android:visibility="gone" />
</RelativeLayout>

布局文件很簡單,我們將標題欄上正中標題,左上角關閉頁面的圖片點擊按鈕,右上角的文字提交按鈕以及圖片點擊按鈕都放在了布局中,那接下來就是如何去控制他們的顯示時機,以及按下后的反饋了!

建立好了這個用于展示我們所有網頁的共用 Activity 后,就是我們本篇的核心類了,敲黑板!!

核心類 HtmlMessageForLocal

在開始之前我們先將思路捋清楚

  • 處理所有網頁的接口實現,以及跳轉操作和添加標題欄上的按鈕添加。

  • 此類用于接收我們點擊或打開 WebView 服務端暴漏給我們的接口,我們負責具體實現!

  • 將我們實現的方法上加上 @JavascriptInterface 注解

  • 此注解表明所有服務端 Js 接口,都會進入我們自定義的這個方法里找同名方法,直接執行里面的邏輯!

好了,通過以上說明相信明眼的你可以發現,這是一個網頁與我們本地的交互的核心類,所有的交互邏輯實現都需要在這里進行!

接下來我們分層進行,一層層,一個個方法的具體實現步驟,來剖析整個過程。

一 、判斷接口名執行具體的方法:

@JavascriptInterface
public void callHandler(final String methodName, final String data, final String callbackName) {
    Log.e(TAG, "Method:" + methodName);
    if (methodName.equals("openAttendanceFromJS")) {
       openAttendanceFromJS(data);      // 打開新窗口
    }
}

這里只是起到了判斷作用,特定的方法執行特定的操作,就比如上面這個方法,只負責用戶點擊了 WebView 去打開新的 WebView 的所有操作。

如何判斷

/**
 * Js 與 Native(android 原生交互)
 * Native 調用 JS 方法
 * @param methodName Js 方法名
 * @param data 需要用到的數據 比如圖片資源需要傳遞的數據 以下代碼的實體類為 RightInfo
 我們需要聲明一個實體類 用到什么數據資源就傳給這個參數 
 * @param callbackName 回調的方法名 這里具體用不到
 */
@JavascriptInterface
public void callHandler(final String methodName, final String data, final String callbackName) {
    Log.e(TAG, "Method:" + methodName);
    if (methodName.equals("openAttendanceFromJS")) {
       openAttendanceFromJS(data);      // 打開新窗口
    } else if (methodName.equals("addRightBarButtonItemFromJS")) {
       addRightBarButtonItemFromJS(data);// 添加右上角按鈕
    }

/**
 * 打開新窗口
 * @param url
 */
protected void openAttendanceFromJS(String url) {
    Log.i("js", url);
    // TODO Auto-generated method stub
    Intent intent = new Intent(ActivityCollector.getTopActivity(), NewWebViewActivity.class);
    intent.putExtra("url", url);
    intent.putExtra("animation", R.anim.slide_right_out);
    intent.putExtra("animation", R.anim.slide_right_in);
    ActivityCollector.getTopActivity().startActivity(intent);
}

/**
 * 設置右上角圖片按鈕
 * @param data
 */
protected void addRightBarButtonItemFromJS(String data) {
    topRightImage.setBackgroundResource(imageId);  //找到圖片按鈕資源
    topRightImage.setVisibility(View.VISIBLE);     //設置為可見狀態
    topRightImage.setOnClickListener(new View.OnClickListener() {  //此按鈕點擊事件
        @Override
        public void onClick(View v) {
            Activity activity = ActivityCollector.getTopActivity();//獲取到棧頂 Activity
            activity.runOnUiThread(new Runnable() {  //強制運行到主線程
                @Override
                public void run() {
                    //找到共用打的 WebView                       
                    ActivityCollector.getTopActivity().findViewById(R.id.base_web_view);
                    activity.overridePendingTransition(R.anim.push_bottom_out, R.anim.push_bottom_in);
                    //找到對應 web url網址
                    baseWebView.loadUrl("javascript:" + rightInfo.funcName);
                }
            });
        }
    });
}

在這里用兩個方法舉例,重要的步驟在這里都呈現了出來,根據我們服務端和 Android 端的需求做相應邏輯和方法的疊加就可以了!

總結

此次在這里將 Js 與 Native 的交互做了一個簡單總結記錄,整理了通用流程和思想,下個系列將使用當下比較流行的 Hybrid APP 框架來實現一個總體的處理流程。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容