Android(安卓)- 用WebView开发简单的浏览器
16lz
2021-01-26
Android-用WebView开发简单的浏览器
Android 提供了 WebView 组件,WebView 本身就是一个浏览器实现。
例子中主要用到了 WebView 的以下方法:
- void loadUrl(String url) 加载指定 url 对应的网页
- void goBack() 后退
- void goForward() 前进
- boolean canGoBack() 根据
历史记录
判断是否可以回退 - boolean canGoForward() 根据
历史记录
判断是否可以前进 - WebSettings getSettings() 获得对 WebView 进行控制的 WebSettings 对象
(调用其setJavaScriptEnabled
方法使WebView
支持JavaScript
) - void setWebViewClient(WebViewClient client) WebViewClient 负责处理
WebView 各种通知,请求,比如页面开始加载及加载完成、资源加载中、url已打开等 - void setWebChromeClient(WebChromeClient client) WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等
浏览器功能概述:
- 第一次打开应用时默认会把
百度
设置为首页,可通过底部主页
按钮跳转到主页,或通过长按弹出对话框修改主页 -
主页
的 URL 地址使用SharedPreference
保存 - 底部四个
ImageButton
从做往右依次为主页
刷新
回退
前进
- 顶部的
ActionBar
用void setCustomView(View)
添加了一个自定义的用于输入网址
的输入框和一个转到
按钮,转到
按钮默认是不可见且不可用的,当点击了用于输入网址
的EditText
就会显示并可用。 - 用于显示网页加载进度的
ProgressBar
截图
这里写图片描述代码部分
- 每次打开一个网页时会调用该方法,在这里控制
ActionBar
内的Edittext
显示加载中...
mWebView.setWebViewClient(new WebViewClient() { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); mShowTitle.setText("加载中..."); } ...}
- 覆写
shouldOverrideUrlLoading
并返回true
,否则 WebView 默认会调用系统的浏览器或第三方浏览器,而不使用当前activity中的WebView
mWebView.setWebViewClient(new WebViewClient() { ... @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } ...}
- 当网页加载进度改变时会回调
onProgressChanged
方法,在这里更新用于显示进度的ProgressBar
。注意newProgress
值为 0 到 100 ,因而将ProgressBar
最大值设为 100 。 -
onReceivedTitle
返回当前加载网页的标题将标题显示在 actionBar 内的 EditText 上。
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); } });
- 监听物理按键
返回
的点击事件,如果WebView
的历史记录
里有上一页相关记录就调用void goBack()
方法
@Override public void onBackPressed() { if (mWebView.canGoBack()) mWebView.goBack(); else finish(); }
- 判断当前是否处于正在输入网址(actionBar上的 EditText)的状态
1 是的话调用此方法表示输入结束从使转到
按钮消失并不可用
2 使EditText
控件失去焦点,不然会一直显示光标,效果不好
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)
方法拦截返回
按键的点击事件,关闭软键盘的同时使输入框失去焦点并隐藏转到
按钮。
@Overridepublic 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; } }
值得注意的地方:
- 在style中使用
colorControlHighlight
属性改变默认的按钮点击波纹效果的颜色
比如这样:
- @color/colorPrimary
- 在按钮的xml属性中通过设置
style=`"@style/Base.Widget.AppCompat.Button.Borderless.Colored"
使按钮的点击效果不受布局边界限制。其他默认不可点击的view(如EditText,TextView等)还要在添加一个:
android:clickable="true"
- 使用到的图标在这里下载的:Material icons - Material Design
- 调用
ActionBar
的setCustomView
方法前先要调用setDisplayShowCustomEnabled
方法并置为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 } ...}
更多相关文章
- android wifi之WifiMonitor
- android调用手机摄像头拍照
- 自定义ThreadPoolExecutor
- Android(安卓)高德地图,显示地图,并定位当前的位置
- Android(安卓)webView 中loadData方法加载 带中文时出现乱码
- 微信青蛙刷脸支付——Android
- Android中调用系统所装的软件打开文件
- 如何定制PopupWindow弹出框及方法介绍
- Android中调用外部程序的方法[整理]