美文网首页
Android编程权威指南(第二版)学习笔记(二十八)—— 第2

Android编程权威指南(第二版)学习笔记(二十八)—— 第2

作者: kniost | 来源:发表于2017-05-18 09:56 被阅读15次

    本章主要讲的是使用 WebView 在应用内浏览网页

    GitHub 地址:
    完成第28章,未完成挑战
    完成第28章挑战

    1. WebView

    如果不使用 WebView,我们可以使用隐式 intent,也就是用独立的浏览器打开一个网页。但是我们通常只想在 activity 中显示网页内容而不是打开浏览器:或许是想显示自己生成的 HTML,或许是想以某种方式限制用户使用浏览器。对于大多数需要帮助文档的应用,普遍做法是以网页的形式提供帮助文档,这样会方便后期的更新与维护。打开浏览器查看帮助文档,既不专业,又妨碍应用行为的定制,同时也无法将网页整合进自己的用户界面。

    1.1 WebView 的使用

    和其他的 View 一样,在 fragment 的布局文件中声明之后,在 fragment 中获取实例,然后进行一番设置:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">
        <WebView
            android:id="@+id/fragment_photo_page_web_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </RelativeLayout>
    
    public class PhotoPageFragment extends VisibleFragment {
        private static final String ARG_URI = "photo_page_url";
    
        private Uri mUri;
        private WebView mWebView;
    
        ………………
        
        // 在这里防止 Lint 警告 JavaScript 被启用
        @SuppressLint("SetJavaScriptEnabled")
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.fragment_photo_page, container, false);
    
            // 首先获取实例
            mWebView = (WebView) v.findViewById(R.id.fragment_photo_page_web_view);
            // 然后将 JavaScript 设置为启用
            mWebView.getSettings().setJavaScriptEnabled(true);
            mWebView.setWebViewClient(new WebViewClient() {
                // 这个方法决定 url 在哪里处理,返回 false 代表让 WebView 去加载
                // 其实该方法默认返回的就是 false
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    return false;
                }
            });
            mWebView.loadUrl(mUri.toString());
    
            return v;
        }
    }
    
    

    可以看到,WebClient 是一个关键,如果不重写该方法,WebView 可能不会加载这个 url

    1.2 使用 WebChromeClient 优化 WebView 显示

    WebViewClient 主要帮助 WebView 处理各种通知、请求事件,而 WebChromeClient 主要辅助 WebView 处理 Javascript 的对话框、网站图标、网站 title、加载进度等。

    我们在视图中加入 ProgressBar 放在 WebView 上方并默认隐藏,由于 WebChromeClient 返回进度值在0~100之间,所以我们要设置进度条的最大值为100。

    mProgressBar.setMax(100); // WebChromeClient 进度范围就是0~100
    
    mWebView.setWebChromeClient(new WebChromeClient() {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            if (newProgress == 100) {
                mProgressBar.setVisibility(View.GONE);
            } else {
                mProgressBar.setVisibility(View.VISIBLE);
                mProgressBar.setProgress(newProgress);
            }
        }
    
        @Override
        public void onReceivedTitle(WebView view, String title) {
            AppCompatActivity activity = (AppCompatActivity) getActivity();
            设置网站标题
            activity.getSupportActionBar().setSubtitle(title);
        }
    });
    

    1.3 处理 WebView 的设备旋转问题

    尝试旋转设备屏幕,可以发现 WebView 必须重新加载网页。这是因为 WebView 包含太多的数据,无法在 onSaveInstanceState(...)方法内全部保存。所以每次设备旋转,它都必须从头开始加载网页数据。

    因为 WebView 是视图层级结构的一部分,所以旋转后它肯定会销毁并重建,不能用 retainFragment 来保留。对于一些类似的类(如 VideoView),Android 文档推荐让 activity 自己处理设备配置变更。也就是说,无需销毁重建 activity,就能直接调整自己的视图以适应新的屏幕尺寸。这样,WebView 也就不必重新加载全部数据了。

    <activity android:name=".PhotoPageActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"/>
    

    android:configChanges 属性表明,如果因键盘开或关、屏幕方向改变、屏幕大小改变(也包括 Android 3.2之后的屏幕方向变化)而发生设备配置更改,那么 activity 应自己处理配置更改。

    2. 挑战练习

    2.1 使用后退键浏览历史页面

    我们覆盖 Activity.onBackPressed 方法,就可以对返回键的行为进行控制,但是要获取 WebView 的实例,所以在 fragment 中加入了一个 getter。

    // PhotoPageActivity.java
    @Override
    public void onBackPressed() {
        PhotoPageFragment fragment = (PhotoPageFragment) getSupportFragmentManager()
                .findFragmentById(R.id.fragment_container);
        if (fragment.getWebView().canGoBack()) {
            fragment.getWebView().goBack();
        } else {
            super.onBackPressed();
        }
    }
    

    2.2 非 HTTP 链接支持

    只需要修改重写的 shouldOverrideUrlLoading 方法即可。

    mWebView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (url.startsWith("https://") || url.startsWith("http://")) {
                return false;
            } else {
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(intent);
                return true;
            }
        }
    });
    

    GitHub Page: kniost.github.io
    简书:http://www.jianshu.com/u/723da691aa42

    相关文章

      网友评论

          本文标题:Android编程权威指南(第二版)学习笔记(二十八)—— 第2

          本文链接:https://www.haomeiwen.com/subject/mhxsxxtx.html