在Android开发过程中,会遇到需要显示网页的需求,或者需要用webview控件来达到某个效果。我这段时间在做CSDN博客的客户端,使用webview来显示博文内容,一是因为解析博文内容再适配比较麻烦,并且效果很不理想,后来想到直接用webview来显示,将博文原汁原味的呈现出来。
webview使用起来比较容易,但是想要达到比较理想的效果还需要很多摸索。我做的CSDNBlog客户端,现在基本可以使用,已经在进行版本迭代了,但是博文的webview显示效果依然不太满意,主要是因为图片的缩放问题。接下来就看看代码:
<pre name="code" class="java"> webView = (WebView) findViewById(R.id.article_content); webView.setWebViewClient(new MyWebViewClient()); webView.getSettings().setDefaultTextEncodingName("utf-8"); webView.getSettings().setAppCacheEnabled(true);// 设置启动缓存 webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); boolean isLoadImg = CSDNPreferences.getPreferenceSetting(this, getString(R.string.pre_key_loadImg), true); Log.i(TAG, "isLoadImg=" + isLoadImg); webView.getSettings().setLoadsImagesAutomatically(isLoadImg); webView.getSettings().setBlockNetworkImage(true);//拦截图片的加载,网页加载完成后再去除拦截 // webView.getSettings().setJavaScriptEnabled(true); // webView.getSettings().setDisplayZoomControls(true);// 设置显示缩放按钮 // webView.getSettings().setSupportZoom(true); // 支持缩放 // webView.getSettings().setBuiltInZoomControls(true); //方法一: // webView.getSettings().setUseWideViewPort(true);//让webview读取网页设置的viewport,pc版网页 // webView.getSettings().setLoadWithOverviewMode(true); //方法二: webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);//适应内容大小 // webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);//适应屏幕,内容将自动缩放
写的博客已经是可以离线查看的,所以不需要启用缓存,每次打开新的博文时,已经把获取的网页源码截取出文章正文内容存储在数据库中了。
目前遗留的问题就是图片的缩放:打开网页时,字体显示的还好,只是图片显示太大了,如果图片的宽度大于屏幕的宽度,webview就可以横向滑动,这样的体验不太好,并且给用户的感觉很耗流量。在网上查找解决办法,得到代码里提示的两种方法(大家推荐的其实还有一种方法),第一种方法中,webview会按照pc网页设置的viewport属性进行加载网页。
<meta name="viewport" content="width=device-width" >
如果有上面这样的设置,就可以适配到移动设备上,如果没有,就会默认显示pc版式的网页。
第二种方法,如注释写的一样,NARROW_COLUMNS内容不变,会根据屏幕宽度自动换行;而SINGLE_COLUMN则会让更加内容的宽度,缩放内容的大小,这样的效果就是网页被缩小到甚至文字都看不到了。
第三种方法我还没有尝试过,就是根据不同的dpi,让网页进行相应的缩放。感觉是不能解决问题的,具体效果还是得试试。
其实我想通过修改网页源码来更改图片的标签的属性,把图片的宽度设置为屏幕的宽度,正准备尝试这种办法。
需要复写一个客户端类:
/** * 继承WebViewClient */ class MyWebViewClient extends WebViewClient { //重写shouldOverrideUrlLoading方法,使点击链接后不使用其他的浏览器打开。 @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { progressBar.setVisibility(View.VISIBLE); String bloger = Constants.DEFAULT_BLOG_USER_ID; Pattern pattern = null; System.out.println(url); if (url.matches(Constants.DEF_STR_REGEX.REGEX_DETAILS)) {//链接为CSDN博客内容 new MainTask().execute(url); return true; } else if (url.matches(Constants.DEF_STR_REGEX.REGEX_BLOG)) {//博客主页 pattern = Pattern.compile(Constants.DEF_STR_REGEX.REGEX_BLOG); } else if (url.matches(Constants.DEF_STR_REGEX.REGEX_CATEGORY)//博客列表或者分类 || url.matches(Constants.DEF_STR_REGEX.REGEX_BLOGLIST)) { pattern = Pattern.compile(Constants.DEF_STR_REGEX.REGEX_LIST); } else { return false;//让系统处理该链接请求 } Matcher matcher = pattern.matcher(url); if (matcher.find()) { bloger = matcher.group(1); } CSDNApplication.getInstance().setCurrentBlogerID(bloger); mDB.saveBloger(bloger); Intent intent = new Intent(); intent.setClass(BlogContentActivity.this, MainTabActivity.class); intent.putExtra(getString(R.string.app_name), Constants.DEF_BLOG_TYPE.BLOGERBLOG); startActivity(intent); BlogContentActivity.this.finish(); //如果不需要其他对点击链接事件的处理返回true,否则返回false return true; } @Override public void onPageFinished(WebView view, String url) {
<span style="white-space:pre"> </span>webView.getSettings().setBlockNetworkImage(false);//去除图片拦截,继续加载图片 super.onPageFinished(view, url); Log.i(TAG, "onPageFinished"); } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); Log.i(TAG, "onReceivedError"); //这里进行无网络或错误处理,具体可以根据errorCode的值进行判断,做跟详细的处理。 } }
在这里把代码都贴过来了,主要是对webview网页内部的链接进行的处理,如果是CSDN的博文,就直接显示在当前页,如果是博文列表就退出到上一个界面进行显示,如果是其他的网页链接就直接通过android默认的打开方式处理。
webview的其他使用技巧,等到大神前来指点。
此致