Android 原生瀏覽器標(biāo)題欄功能與JS交互優(yōu)化

需求分析

APP內(nèi)原生“BrowserActivity”(有WebView的界面)洁闰,嵌入H5模塊功能界面如在線商城等塘慕。

其中部分界面需要原生提供標(biāo)題欄模塊的功能:

  • 下拉框選項(xiàng)
  • 右邊圖片按鈕
  • 文本按鈕
image

解決方案

  1. 將具體的需求抽象出來
  2. 實(shí)現(xiàn)相應(yīng)的接口,預(yù)先提供相應(yīng)的數(shù)據(jù)以及相應(yīng)方法
  3. 在原生跳轉(zhuǎn)“BrowserActivity”時(shí)傳入 Provider(抽象出來的接口)

優(yōu)點(diǎn):

  • 避免BrowserActivity類里面的代碼膨脹
  • 比較好的保證了通用界面獨(dú)立性
  • 降低后期開發(fā)升級(jí)維護(hù)的難度
  • 產(chǎn)品更改需求我們只需要在Provider里面進(jìn)行擴(kuò)展即可
  • 不同模塊的擴(kuò)展功能可以獨(dú)立開戒傻,避免造成誤改通用性代碼

交互抽象類

/**
 * Des:交互抽象類
 * created by Zishu.Ye on 2017/6/12  10:27
 */
public interface IBrowserProvider<T> {

    /**
     * 綁定到相應(yīng)的web 瀏覽器
     * @param context           context
     * @param webViewManager    manager
     */
    void bind(Context context, WebViewManager webViewManager);

    /**
     * webView 加載頁面開始加載的回調(diào)
     * @param url 相應(yīng)的url
     */
    void onPageStarted(String url);

    /**
     * webView 加載頁面結(jié)束加載的回調(diào)
     * @param url 相應(yīng)的url
     */
    void onPageFinished(String url);

    /**
     *  當(dāng)webview 第一次收到 js 調(diào)用是進(jìn)行回調(diào)
     * @param url url
     */
    void onJsCalled(String url);

    /**
     * web 瀏覽器在銷毀的時(shí)候解綁
     */
    void unBind();

    /**
     * 根據(jù)與H5定義的交互分類
     * 返回h5橋接的需要展示彈窗分類的鍵值對(duì)
     *
     * @return 返回h5橋接的需要展示彈窗分類的數(shù)據(jù)
     */
    Map<String,List<DropDownBrowserBean<T>>> getDropTypeMap();

    /**
     * @param h5JSBridgeTypeKey     h5調(diào)用彈窗的類型
     * @param bean 下拉列表item點(diǎn)擊事件
     */
    void onDropListItemClick(String h5JSBridgeTypeKey ,DropDownBrowserBean<T> bean);

    /**
     * @return 右邊按鈕需要顯示的圖標(biāo)
     */
    Map<String,Integer> getRightImgBtnMap();

    /**
     * 右邊按鈕點(diǎn)擊事件
     * @param h5JSBridgeTypeKey    h5調(diào)用按鈕的類型
     */
    void onRightBtnClick(String h5JSBridgeTypeKey);

    /**
     * @return 右邊文本按鈕需要顯示的文本
     */
    Map<String,String> getRightTextBtnMap();

    /**
     * 右邊文本按鈕點(diǎn)擊事件
     * @param h5JSBridgeTypeKey    h5調(diào)用按鈕的類型
     */
    void onRightTextBtnClick(String h5JSBridgeTypeKey);
}

下拉選項(xiàng)類型Bean

/**
 * Des:下拉瀏覽器 通用數(shù)據(jù)類
 * create by Zishu.Ye on 2017/6/12  10:24
 */
public class DropDownBrowserBean<T> {

    String key;     //索引
    String label;   //顯示標(biāo)簽
    boolean isChioced;//是否選中
    T data;         //數(shù)據(jù)實(shí)體
    
}

Provider 的基類 BaseBrowserProvider

也可以不需要此基類税手,提供它好處在于可以統(tǒng)一處理一些通用的綁定界面等
繼承此基類也不需要實(shí)現(xiàn)所有抽象的方法,可以根據(jù)具體需求選擇實(shí)現(xiàn)提供

/**
 * Des:Provider 的基類 BaseBrowserProvider
 * create by Zishu.Ye on 2017/6/12  10:16
 */
public abstract class BaseBrowserProvider<T> implements IBrowserProvider<T>, Serializable {

    public Context mContext;
    public WebViewManager mWebViewManager;

    @Override
    public void bind(Context context, WebViewManager webViewManager) {
        this.mContext = context;
        this.mWebViewManager = webViewManager;
    }

    @Override
    public void unBind() {
        mContext=null;
        mWebViewManager=null;
    }

    @Override
    public void onPageStarted(String url) {}

    @Override
    public void onPageFinished(String url) {}

    @Override
    public void onJsCalled(String url) {}

    @Override
    public Map<String, String> getRightTextBtnMap() {
        return null;
    }

    @Override
    public void onRightTextBtnClick(String h5JSBridgeTypeKey) {}
}

具體業(yè)務(wù)需求實(shí)現(xiàn)類

在這里進(jìn)行提供具體需求所需要的數(shù)據(jù)

/**
 * Des:具體業(yè)務(wù)需求實(shí)現(xiàn)類
 * create by Zishu.Ye on 2017/8/28  10:13
 */
public class SeriviceBrowserProvider extends BaseBrowserProvider<Bean> implements IView {

    private ServiceTypePresenter presenter;

    @Override
    public void bind(Context context, WebViewManager webViewManager) {
        super.bind(context, webViewManager);
        //做綁定的操作 比如初始化Presenter等
        presenter = new ServiceTypePresenter(this);
        presenter.getProductType(type);
    }

    @Override
    public void unBind() {
        super.unBind();
        if (presenter != null) {
            presenter.detachView();
        }
    }

    @Override
    public void onJsCalled(String url) {
        super.onPageFinished(url);
        mWebViewManager.loadUrl("javascript:method(par)");
    }

    @Override
    public Map<String, List<DropDownBrowserBean<Bean>>> getDropTypeMap() {
        Map<String, List<DropDownBrowserBean<Bean>>> map = new HashMap<>();
        return map;
    }

    @Override
    public void onDropListItemClick(String h5JSBridgeTypeKey, DropDownBrowserBean<Bean> bean) {
        switch (h5JSBridgeTypeKey) {
            case KEY:
                doSomething(bean);
                break;
            default:
                break;
        }
    }

    @Override
    public Map<String, Integer> getRightImgBtnMap() {
        return map;
    }

    @Override
    public void onRightBtnClick(String h5JSBridgeTypeKey) {
        switch (h5JSBridgeTypeKey) {
            case KEY:
                doSomething(h5JSBridgeTypeKey);
                break;
            default:
                break;
        }
    }

    @Override
    public Map<String, String> getRightTextBtnMap() {
        Map<String, String> map = new HashMap<>();
        return map;
    }

    @Override
    public void onRightTextBtnClick(String h5JSBridgeTypeKey) {
        switch (h5JSBridgeTypeKey) {
            case KEY:
                doSomething(h5JSBridgeTypeKey);
                break;
            default:
                break;
        }
    }
}

跳轉(zhuǎn)BrowserActivity

Intent intent = new Intent(context, BrowserActivity.class);
intent.putExtra(URL_KEY, url);
intent.putExtra(KEY, seriviceBrowserProvider)
context.startActivity(intent);

BrowserActivity 部分的處理

/**
 * Des:標(biāo)題欄功能瀏覽器
 * create by Zishu.Ye on 2017/6/13  10:57
 */
public class BrowserActivity extends BaseAppCompatActivity {
    
    private IBrowserProvider mBrowserProvider;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_browser);
        init();
        initView();
    }

    @Override
    protected void onDestroy() {
        if (mBrowserProvider != null) {
            mBrowserProvider.unBind();
        }
    }

    @Override
    protected void init() {
        mBrowserProvider = (IBrowserProvider) getIntent().getSerializableExtra(KEY);
    }

    @Override
    protected void initView() {
        if (mBrowserProvider != null)
            mBrowserProvider.bind(this, webViewManager);
    }
    
    @OnClick({R.id.iv_right, R.id.tv_right})
    void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv_right://右邊按鈕點(diǎn)擊事件
                if (mBrowserProvider != null)
                    mBrowserProvider.onRightBtnClick(curRightImgBtnType);
                break;
            case R.id.tv_right:
                if (mBrowserProvider != null)
                    mBrowserProvider.onRightTextBtnClick(curRightTextBtnType);
                break;
            default:
                break;
        }
    }
    
    /**
     * 收到JS 調(diào)用指定功能 進(jìn)行相應(yīng)的初始化界面控件
     * 設(shè)置右邊按鈕圖片需纳、文本  加載下拉彈窗等
     * @param javaScriptEvent e
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(final BusEvent.JavaScriptEvent javaScriptEvent) {
        if (mBrowserProvider != null) {
            Map<String, Object> map = (Map<String, Object>) javaScriptEvent.getT();
            doSetRightBtn(map, mBrowserProvider.getDropTypeMap(), mBrowserProvider.getRightImgBtnMap(), mBrowserProvider.getRightTextBtnMap());
        }
    }
    
    /**
     * 下拉彈窗item點(diǎn)擊
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(DropDownBrowserEvent event) {
        if (event.getOrderTypeBeam() != null)
            mBrowserProvider.onDropListItemClick(event.getH5JSBridgeTypeKey(), event.getOrderTypeBeam());
    }

    BaseWebViewClient<XXX> baseWebViewClient = new BaseWebViewClient<XXX>() {

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            if (mBrowserProvider != null)
                mBrowserProvider.onPageStarted(url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (mBrowserProvider != null)
                mBrowserProvider.onPageFinished(url);
        }
    };
    
}

最后

感謝觀看芦倒,歡迎留言指導(dǎo)交流

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市不翩,隨后出現(xiàn)的幾起案子兵扬,更是在濱河造成了極大的恐慌,老刑警劉巖口蝠,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件器钟,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡妙蔗,警方通過查閱死者的電腦和手機(jī)傲霸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眉反,“玉大人昙啄,你說我怎么就攤上這事〈缥澹” “怎么了梳凛?”我有些...
    開封第一講書人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)播歼。 經(jīng)常有香客問我伶跷,道長(zhǎng),這世上最難降的妖魔是什么秘狞? 我笑而不...
    開封第一講書人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任叭莫,我火速辦了婚禮,結(jié)果婚禮上烁试,老公的妹妹穿的比我還像新娘雇初。我一直安慰自己,他們只是感情好减响,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開白布靖诗。 她就那樣靜靜地躺著郭怪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪刊橘。 梳的紋絲不亂的頭發(fā)上鄙才,一...
    開封第一講書人閱讀 51,245評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音促绵,去河邊找鬼攒庵。 笑死,一個(gè)胖子當(dāng)著我的面吹牛败晴,可吹牛的內(nèi)容都是我干的浓冒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼尖坤,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼稳懒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起慢味,我...
    開封第一講書人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤场梆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后贮缕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辙谜,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俺榆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年感昼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罐脊。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡定嗓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出萍桌,到底是詐尸還是另有隱情宵溅,我是刑警寧澤,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布上炎,位于F島的核電站恃逻,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏藕施。R本人自食惡果不足惜寇损,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望裳食。 院中可真熱鬧矛市,春花似錦、人聲如沸诲祸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至找田,卻和暖如春歌憨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背墩衙。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來泰國打工躺孝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人底桂。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓植袍,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親籽懦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子于个,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,088評(píng)論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)暮顺,斷路器厅篓,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,806評(píng)論 6 342
  • 親密關(guān)系的破裂惫恼,往往是從“你怎么不這樣做档押?”“你實(shí)在太讓人失望!”“你再…就…”等等的互相指責(zé)開始祈纯。 察覺...
    清不負(fù)此生閱讀 261評(píng)論 0 2
  • 拆書《4D卓越團(tuán)隊(duì)》P12-14 I:工作場(chǎng)所的績(jī)效高與低令宿,不僅依賴于個(gè)人因素,還取決于背景環(huán)境腕窥。培訓(xùn)是否能產(chǎn)生績(jī)...
    plait_7015閱讀 138評(píng)論 0 0