Android开源中国客户端学习(3) 查看资讯正文

 一:资讯正文 

开源中国和大部分新闻客户端一样,使用webview显示html的数据

 

首先看看是如何获取数据,这里是在initData实现的

        // 初始化控件数据
	private void initData() {
		mHandler = new Handler() {
			public void handleMessage(Message msg) {
				if (msg.what == 1) {
					headButtonSwitch(DATA_LOAD_COMPLETE);

					mTitle.setText(newsDetail.getTitle());
					mAuthor.setText(newsDetail.getAuthor());
					mPubDate.setText(StringUtils.friendly_time(newsDetail
							.getPubDate()));
					mCommentCount.setText(String.valueOf(newsDetail
							.getCommentCount()));

					// 是否收藏
					if (newsDetail.getFavorite() == 1)
						mFavorite
								.setImageResource(R.drawable.widget_bar_favorite2);
					else
						mFavorite
								.setImageResource(R.drawable.widget_bar_favorite);

					// 显示评论数
					if (newsDetail.getCommentCount() > 0) {
						bv_comment.setText(newsDetail.getCommentCount() + "");
						bv_comment.show();
					} else {
						bv_comment.setText("");
						bv_comment.hide();
					}

					String body = UIHelper.WEB_STYLE + newsDetail.getBody();
					// 读取用户设置:是否加载文章图片--默认有wifi下始终加载图片
					boolean isLoadImage;
					AppContext ac = (AppContext) getApplication();
					if (AppContext.NETTYPE_WIFI == ac.getNetworkType()) {
						isLoadImage = true;
					} else {
						isLoadImage = ac.isLoadImage();
					}
					if (isLoadImage) {
						// 过滤掉 img标签的width,height属性
						body = body.replaceAll(
								"(<img[^>]*?)\\s+width\\s*=\\s*\\S+", "$1");
						body = body.replaceAll(
								"(<img[^>]*?)\\s+height\\s*=\\s*\\S+", "$1");

						// 添加点击图片放大支持
						body = body.replaceAll("(<img[^>]+src=\")(\\S+)\"",
								"$1$2\" onClick=\"javascript:mWebViewImageListener.onImageClick('$2')\"");

					} else {
						// 过滤掉 img标签
						body = body.replaceAll("<\\s*img\\s+([^>]*)\\s*>", "");
					}

					// 更多关于***软件的信息
					String softwareName = newsDetail.getSoftwareName();
					String softwareLink = newsDetail.getSoftwareLink();
					if (!StringUtils.isEmpty(softwareName)
							&& !StringUtils.isEmpty(softwareLink))
						body += String
								.format("<div id='oschina_software' style='margin-top:8px;color:#FF0000;font-weight:bold'>更多关于: <a href='%s'>%s</a> 的详细信息</div>",
										softwareLink, softwareName);

					// 相关新闻
					if (newsDetail.getRelatives().size() > 0) {
						String strRelative = "";
						for (Relative relative : newsDetail.getRelatives()) {
							strRelative += String
									.format("<a href='%s' style='text-decoration:none'>%s</a><p/>",
											relative.url, relative.title);
						}
						body += String.format(
								"<p/><hr/><b>相关资讯</b><div><p/>%s</div>",
								strRelative);
					}

					body += "<div style='margin-bottom: 80px'/>";

					System.out.println(body);

					mWebView.loadDataWithBaseURL(null, body, "text/html",
							"utf-8", null);
					mWebView.setWebViewClient(UIHelper.getWebViewClient());

					// 发送通知广播
					if (msg.obj != null) {
						UIHelper.sendBroadCast(NewsDetail.this,
								(Notice) msg.obj);
					}
				} else if (msg.what == 0) {
					headButtonSwitch(DATA_LOAD_FAIL);

					UIHelper.ToastMessage(NewsDetail.this,
							R.string.msg_load_is_null);
				} else if (msg.what == -1 && msg.obj != null) {
					headButtonSwitch(DATA_LOAD_FAIL);

					((AppException) msg.obj).makeToast(NewsDetail.this);
				}
			}
		};

		initData(newsId, false);
	}
  (1)由于在 WebView 上显示HTML,不可能只显示纯文本,而没有一点样式,这会显得很难看,String body = UIHelper.WEB_STYLE + newsDetail.getBody()中的WEB_STYLE中定义了全局web样式

public final static String WEB_STYLE = "<style>* {font-size:16px;line-height:20px;} p {color:#333;} a {color:#3E62A6;} img {max-width:310px;} "
			+ "img.alignleft {float:left;max-width:120px;margin:0 10px 5px 0;border:1px solid #ccc;background:#fff;padding:2px;} "
			+ "pre {font-size:9pt;line-height:12pt;font-family:Courier New,Arial;border:1px solid #ddd;border-left:5px solid #6CE26C;background:#f6f6f6;padding:5px;} "
			+ "a.tag {font-size:15px;text-decoration:none;background-color:#bbd6f3;border-bottom:2px solid #3E6D8E;border-right:2px solid #7F9FB6;color:#284a7b;margin:2px 2px 2px 0;padding:2px 4px;white-space:nowrap;}</style>";
 上面全局样式:“*”定义了字体大小以及行高;“p”标签内的字体颜色;“a”标签内的字体颜色;“img”标签的图片最大宽度;“pre”为代码样式; 
  资讯内容是由服务返回的一串带HTML标签的字符串   : newsDetail.getBody()

 相关资讯等是有返回的数据组装成的

					if (newsDetail.getRelatives().size() > 0) {
						String strRelative = "";
						for (Relative relative : newsDetail.getRelatives()) {
							strRelative += String
									.format("<a href='%s' style='text-decoration:none'>%s</a><p/>",
											relative.url, relative.title);
						}
						body += String.format(
								"<p/><hr/><b>相关资讯</b><div><p/>%s</div>",
								strRelative);
					}

 (2)图片显示

  WebView上显示图片,不能直接显示大图,这会影响页面的美观以及用户体验,因此要过滤掉原始图片的高宽属性,使用全局的图片样式。同时客户端可以根据用户设置,是否加载图片显示,以达到节省流量的目的。 

	                              if (isLoadImage) {
						// 过滤掉 img标签的width,height属性
						body = body.replaceAll(
								"(<img[^>]*?)\\s+width\\s*=\\s*\\S+", "$1");
						body = body.replaceAll(
								"(<img[^>]*?)\\s+height\\s*=\\s*\\S+", "$1");

						// 添加点击图片放大支持
						body = body.replaceAll("(<img[^>]+src=\")(\\S+)\"",
								"$1$2\" onClick=\"javascript:mWebViewImageListener.onImageClick('$2')\"");

					} else {
						// 过滤掉 img标签
						body = body.replaceAll("<\\s*img\\s+([^>]*)\\s*>", "");
					}
(3)将HTML数据显示到WebView中

mWebView.loadDataWithBaseURL(null, body, "text/html","utf-8", null);
(4)处理超链接

我们知道Webview的setWebViewClient函数可以处理超链接跳转等功能,OSC也是这样实现的

mWebView.setWebViewClient(UIHelper.getWebViewClient());
接下来看看UIHelper.getWebViewClient()

public static WebViewClient getWebViewClient() {
		return new WebViewClient() {
			@Override
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				showUrlRedirect(view.getContext(), url);
				return true;
			}
		};
	}
继续看看showUrlRedirect,这个方法实现了url跳转

public static void showUrlRedirect(Context context, String url) {
		URLs urls = URLs.parseURL(url);
		if (urls != null) {
			showLinkRedirect(context, urls.getObjType(), urls.getObjId(),
					urls.getObjKey());
		} else {
			openBrowser(context, url);
		}
	}
URLs urls = URLs.parseURL(url); 是将url转换为URLs实体
public static void showLinkRedirect(Context context, int objType,int objId, String objKey)
showLinkRedirect是根据不同类型跳转到不同的Activity

 (5)点击查看大图

body = body.replaceAll("(<img[^>]+src=\")(\\S+)\"","$1$2\" onClick=\"javascript:mWebViewImageListener.onImageClick('$2')\"");
接下来我们在UIHelper中查找mWebViewImageListener ,发现addWebImageShow这个方法,这就是添加网页的点击图片展示支持

public static void addWebImageShow(final Context cxt, WebView wv) {
		wv.getSettings().setJavaScriptEnabled(true);
		wv.addJavascriptInterface(new OnWebViewImageListener() {
			@Override
			public void onImageClick(String bigImageUrl) {
				if (bigImageUrl != null)
					UIHelper.showImageZoomDialog(cxt, bigImageUrl);
			}
		}, "mWebViewImageListener");
	}
在初始化控件时调用了这个方法   UIHelper.addWebImageShow(this, mWebView);
showImageZoomDialog这是方法是调用了ImageZoomDialog这个Activity,这是查看大图的Activity,并且支持缩放等,我们下次就研究这个。。。

二:底部视图

(1)底部视图中资讯和评论的切换

private void viewSwitch(int type) {
		switch (type) {
		case VIEWSWITCH_TYPE_DETAIL:
			mDetail.setEnabled(false);
			mCommentList.setEnabled(true);
			mHeadTitle.setText(R.string.news_detail_head_title);
			mViewSwitcher.setDisplayedChild(0);
			break;
		case VIEWSWITCH_TYPE_COMMENTS:
			mDetail.setEnabled(true);
			mCommentList.setEnabled(false);
			mHeadTitle.setText(R.string.comment_list_head_title);
			mViewSwitcher.setDisplayedChild(1);
			break;
		}
	}
使用了viewswitch,可以省去重复设置setVisibility

(2)评论视图

  评论使用了一个开源控件BadgeView

  这个的使用也很简单 ,首先设置
        bv_comment = new BadgeView(this, mCommentList);
        bv_comment.setBackgroundResource(R.drawable.widget_count_bg2);
        bv_comment.setIncludeFontPadding(false);
        bv_comment.setGravity(Gravity.CENTER);
        bv_comment.setTextSize(8f);
        bv_comment.setTextColor(Color.WHITE);

  接着

                                        if (newsDetail.getCommentCount() > 0) {
						bv_comment.setText(newsDetail.getCommentCount() + "");
						bv_comment.show();
					} else {
						bv_comment.setText("");
						bv_comment.hide();
					}
(3)发表评论

		mFootEditebox.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				mFootViewSwitcher.showNext();
				mFootEditer.setVisibility(View.VISIBLE);
				mFootEditer.requestFocus();
				mFootEditer.requestFocusFromTouch();
			}
		});
		mFootEditer = (EditText) findViewById(R.id.news_detail_foot_editer);
		mFootEditer.setOnFocusChangeListener(new View.OnFocusChangeListener() {
			public void onFocusChange(View v, boolean hasFocus) {
				if (hasFocus) {
					imm.showSoftInput(v, 0);
				} else {
					imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
				}
			}
		});
		mFootEditer.setOnKeyListener(new View.OnKeyListener() {
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				if (keyCode == KeyEvent.KEYCODE_BACK) {
					if (mFootViewSwitcher.getDisplayedChild() == 1) {
						mFootViewSwitcher.setDisplayedChild(0);
						mFootEditer.clearFocus();
						mFootEditer.setVisibility(View.GONE);
					}
					return true;
				}
				return false;
			}
		});
		// 编辑器添加文本监听
		mFootEditer.addTextChangedListener(UIHelper.getTextWatcher(this,
				tempCommentKey));

		// 显示临时编辑内容
		UIHelper.showTempEditContent(this, mFootEditer, tempCommentKey);


 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值