Android - 用WebView开发简单的浏览器

2017-08-18  本文已影响0人  DJN_

Android-用WebView开发简单的浏览器

Android 提供了 WebView 组件,WebView 本身就是一个浏览器实现。

例子中主要用到了 WebView 的以下方法:

浏览器功能概述:

  1. 第一次打开应用时默认会把百度设置为首页,可通过底部主页按钮跳转到主页,或通过长按弹出对话框修改主页
  2. 主页的 URL 地址使用SharedPreference保存
  3. 底部四个ImageButton从做往右依次为主页 刷新 回退 前进
  4. 顶部的ActionBarvoid setCustomView(View)添加了一个自定义的用于输入网址的输入框和一个转到按钮,转到按钮默认是不可见且不可用的,当点击了用于输入网址EditText就会显示并可用。
  5. 用于显示网页加载进度的ProgressBar

截图

这里写图片描述

代码部分

 mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                mShowTitle.setText("加载中...");
            }
            ...
}
mWebView.setWebViewClient(new WebViewClient() {
            ...
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
            ...
}
mWebView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                mProgressBar.setProgress(newProgress);
                if (newProgress == 100) {
                    mProgressBar.postDelayed(() -> mProgressBar.setProgress(0), 2000);
                }
        }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                currentUrlTitle = title;
                mShowTitle.setText(currentUrlTitle);
            }
        });
@Override
    public void onBackPressed() {
        if (mWebView.canGoBack())
            mWebView.goBack();
        else finish();
    }
private void finishEdit() {
        if (isEditFocus) {
            isEditFocus = false;
            mShowTitle.clearFocus();

            Animation animation = AnimationUtils.loadAnimation(MainActivity.this, android.R.anim.fade_out);
            animation.setFillAfter(true);
            mLoadUrl.startAnimation(animation);
            mLoadUrl.setEnabled(false);

            mShowTitle.setText(currentUrlTitle);
        }
    }

这个方法有三个地方调用到:
1 当正在输入网址时用户转移注意力到WebView上,并触摸到WebView,此时会先判断软键盘是否正在显示,正在显示就关闭软键盘然后使输入框失去焦点并隐藏转到按钮

 mWebView.setOnTouchListener((View view, MotionEvent event) -> {
       if (event.getAction() == MotionEvent.ACTION_DOWN) {
           finishEdit();
           InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
           if (imm.isActive())
               imm.hideSoftInputFromWindow(mShowTitle.getWindowToken(),0);

       }
       return false;
   });

2 当正在输入网址时点击了物理按键返回,此时void onBackPressed()方法是不会被调用的,因为此时软键盘正在显示,调用boolean dispatchKeyEvent(KeyEvent event)方法拦截返回按键的点击事件,关闭软键盘的同时使输入框失去焦点并隐藏转到按钮。

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK)
            finishEdit();
        return super.dispatchKeyEvent(event);
    }

3 点击了 actionBar 处的转到按钮
3.1 此时要先判断是否正确输入,然后判断输入网址是否是新的(和当前正在显示的网页的网址不同),满足就让WebView加载该网页
3.2 判断软键盘是否正在显示,正在显示就关闭软键盘然后使输入框失去焦点并隐藏转到按钮

以下代码包含所有按钮的点击事件,每个按钮都在xml中添加了
android:onClick="onClick"属性

 public void onClick(View view) {
        switch (view.getId()) {
            case R.id.main_goBack:
                if (mWebView.canGoBack())
                    mWebView.goBack();
                break;
            case R.id.main_goForward:
                if (mWebView.canGoForward())
                    mWebView.goForward();
                break;
            case R.id.main_refresh:
                mWebView.loadUrl(currentUrl);
                break;
            case R.id.actionBar_goto:
                String url = mShowTitle.getText().toString() == "" ? null : mShowTitle.getText().toString().equals(currentUrl) ? null : mShowTitle.getText().toString();
                if (url != null)
                    mWebView.loadUrl(url);

                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm.isActive())
                    imm.hideSoftInputFromWindow(mShowTitle.getWindowToken(),0);

                finishEdit();
                break;
            case R.id.main_home:
                if (!currentUrl.equals(homeUrl))
                    mWebView.loadUrl(homeUrl);
                break;
        }
    }

值得注意的地方:

<item name="colorControlHighlight">@color/colorPrimary</item>
style=`"@style/Base.Widget.AppCompat.Button.Borderless.Colored"

使按钮的点击效果不受布局边界限制。其他默认不可点击的view(如EditText,TextView等)还要在添加一个:

android:clickable="true"
 AlertDialog.Builder builder
     .setTitle("修改主页")
     .setNegativeButton("取消", (DialogInterface dialog, int which) -> dialog.dismiss())

这里本来是用new DialogInterface.OnClickListener() {...}的形式写的,后来改成使用Lambda的方式,这时要在app的build.gradle里加上:

android {
    ...
        jackOptions {
            enabled true
        }
        ...
    }
    ...
    compileOptions {
        targetCompatibility 1.8
        sourceCompatibility 1.8
    }
    ...
}

上一篇 下一篇

猜你喜欢

热点阅读