android textView 加载HTML 异步加载网络图片

TextView与WebView加载HTML对比
本文探讨了在Android应用中使用TextView与WebView加载HTML内容的优缺点。TextView适合纯文本内容,而涉及图片尤其是网络图片时,WebView表现更佳。同时介绍了如何优化WebView加载速度及流畅度。

请尊重别人的劳动成果,转发文章请注明出处


概述
大家都知道textview可以格式化html格式的文本内容。是否有了textView就可以实现了一个控件“代替“游览器展示html页面内容呢?
个人觉得不可能那么强大吧。不然怎么会出现了webView这种东西呢?那么现在问题来了,是不是webView就是最完美的选择呢?
个人实践之后得出结论:
1.如果只是格式化html文本类的内容,推荐使用textView,省时省力,还能得到很好的效果
2.如果html页面内容涉及到图片,特别是网络图片加载的,个人觉得尽可能的往webView方向去实现。
两种方式都做过了尝试,下面说一说遇到的问题和解决思路

textView加载html内容问题

1.textView只是加载文本类型html,可以直接使用textView的方法格式化
	String message="html内容";
		TextView textView=new TextView(mContext);
		textView.setText(Html.fromHtml(message));
这种方式基本能识别html的标签,对于特殊的,比较新的标签,可以根据实际需求转化成textView能够实现的标签

2.textView加载网络图片
如果加载的html内容中包含图片,那么使用上面的方法则无法实现了,运行之后会出现小方框代替了图片,加载网络图片是一件比较麻烦的事情,需要使用Html.fromHtml的另外一个构造方法。Html.fromHtml(source, imageGetter, tagHandler);
参数说明:source=需要展示的html文本内容,imageGetter=需要继承Html.ImageGetter接口实现逻辑,tagHandler=这个参数表示,当textView解析遇到无法识别的html标签是否发送通知或者消息,如果遇到无法解析的标签,该方法将会被调用。这个没有具体测试过,一般赋值null。

2.1网络图片的加载不能阻塞主线程,因此需要异步加载
2.2加载图片之后无法正常显示(偏小)
2.3重新设置图片大小之后在个别系统上会出现图片错位(这个暂时无法解决,还望有解决办法的共享一下解决思路)

下面是重写的Html.ImageGetter类。
重点思路:先异步加载网络图片,图片加载完成之后重新赋值textView内容,(由于加载的图片会比实际图片偏小,因此我这里将图片的宽拉伸到屏幕宽,将图片的高按照原图等比例拉伸,最致命的一点是:只要重新修改了宽,图片就开始错位。这个看开发者需求,如果小图不影响业务,可以不对图片进行等比例缩放,不缩放就能相对完美实现)

	/**
	 * 重写图片加载接口
	 * 
	 * @author Ruffian
	 * @date 2016年1月15日
	 * 
	 */
	class HtmlImageGetter implements Html.ImageGetter {

		/**
		 * 获取图片
		 */
		@Override
		public Drawable getDrawable(String source) {
			LevelListDrawable d = new LevelListDrawable();
			Drawable empty = getResources().getDrawable(
					R.drawable.image_horizontal);
			d.addLevel(0, 0, empty);
			d.setBounds(0, 0, PhoneUtils.getScreenWidth(mContext),
					empty.getIntrinsicHeight());
			new LoadImage().execute(source, d);
			return d;
		}

		/**
		 * 异步下载图片类
		 * 
		 * @author Ruffian
		 * @date 2016年1月15日
		 * 
		 */
		class LoadImage extends AsyncTask<Object, Void, Bitmap> {

			private LevelListDrawable mDrawable;

			@Override
			protected Bitmap doInBackground(Object... params) {
				String source = (String) params[0];
				mDrawable = (LevelListDrawable) params[1];
				try {
					InputStream is = new URL(source).openStream();
					return BitmapFactory.decodeStream(is);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (MalformedURLException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				return null;
			}

			/**
			 * 图片下载完成后执行
			 */
			@Override
			protected void onPostExecute(Bitmap bitmap) {
				if (bitmap != null) {
					BitmapDrawable d = new BitmapDrawable(bitmap);
					mDrawable.addLevel(1, 1, d);
					/**
					 * 适配图片大小 <br/>
					 * 默认大小:bitmap.getWidth(), bitmap.getHeight()<br/>
					 * 适配屏幕:getDrawableAdapter
					 */
					mDrawable = getDrawableAdapter(mContext, mDrawable,
							bitmap.getWidth(), bitmap.getHeight());

					// mDrawable.setBounds(0, 0, bitmap.getWidth(),
					// bitmap.getHeight());

					mDrawable.setLevel(1);

					/**
					 * 图片下载完成之后重新赋值textView<br/>
					 * mtvActNewsContent:我项目中使用的textView
					 * 
					 */
					mtvActNewsContent.invalidate();
					CharSequence t = mtvActNewsContent.getText();
					mtvActNewsContent.setText(t);

				}
			}

			/**
			 * 加载网络图片,适配大小
			 * 
			 * @param context
			 * @param drawable
			 * @param oldWidth
			 * @param oldHeight
			 * @return
			 * @author Ruffian
			 * @date 2016年1月15日
			 */
			public LevelListDrawable getDrawableAdapter(Context context,
					LevelListDrawable drawable, int oldWidth, int oldHeight) {
				LevelListDrawable newDrawable = drawable;
				long newHeight = 0;// 未知数
				int newWidth = PhoneUtils.getScreenWidth(context);// 默认屏幕宽
				newHeight = (newWidth * oldHeight) / oldWidth;
				// LogUtils.w("oldWidth:" + oldWidth + "oldHeight:" +
				// oldHeight);
				// LogUtils.w("newHeight:" + newHeight + "newWidth:" +
				// newWidth);
				newDrawable.setBounds(0, 0, newWidth, (int) newHeight);
				return newDrawable;
			}
		}

	}

调用处代码

	String content="这里是html内容";
		HtmlImageGetter htmlImageGetter = new HtmlImageGetter();
		Spanned spanned = Html.fromHtml(content, htmlImageGetter, null);
		//mtvActNewsContent:这个textView是我测试项目用到的textView
		mtvActNewsContent.setText(spanned);		
所以,使用textView加载带网络图片的html内容需求是可以实现的,只是不尽人意。

那么使用webView吧。但是webView加载的是完整的页面内容,需要后台处理好,返回一个页面路径,这个得看个人需求,但是忠告是,图文并茂的页面还是使用webView比较好,但是webView是不是就完美解决了呢?然而并不是,毕竟webView加载页面是页面的内容,效果没有Android原生的好,同事使用webView加载页面在Android系统4.4+开始滑动页面会有明显的卡顿跳帧,有些简直无法接受

使用腾讯X5SDK优化webView加载

腾讯X5SDK能够加速webView加载优化滑动卡顿,效果还是比较明显的(亲测),只是使用条件比较苛刻,在国内使用的APP还是可以考虑的。具体使用去官网查看吧,使用遇到什么问题也可以交流一下



评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值