自学安卓编程权威指南(二十五)

这一章是来讲解网页浏览,我们有两种方式来整合网页内容(1)使用浏览器应用(2)使用WebView在应用中显示网页的内容

一.通过浏览器获得图片对应的URL

(1)对于图片对应的URL,我们能会联想到上面的json内容,感觉应该会需要更多的内容,但实际上我们可以根据官方文档来发现其实网页URL都是有固定的格式的,如下面

http://www.flickr.com/photos/user-id/photo-id

对于上面的全部信息,其实在返回来的json都有,但是需要我们自己去解析出来,然后去拼接起来

查看官方的文档,我们也可以知道json文件中的owner属性值就是用户的ID,那么就可以创建图片的完整URL了

http://www.flickr.com/photos/owner/id

之前已经有了部分从json中获取到一些数据了,所以就直接在GalleryItem中去添加mmOwner属性

private String mOwner;

public String getOwner(){

return mOwner;

}

public void setOwner(String owner) {

mOwner = owner;

}

//增加一个方法来生成图片的URL

public Uri getPhotoPagerUri(){

return Uri.parse("http://www.flickr.com/photos/").buildUpon().appendPath(mOwner).appendPath(mId).build()

}

(2)修改parseItem()方法,从JSON数据中获取owner属性,在方法中添加下面的代码:

item.setOwner(photoJsonObject.getString("owner"));

现在获得图片的URL就已经完成了

(3)使用隐式intent来访问图片URL,隐式intent可以启动浏览器,并在其中打开图片URL指定的网页

首先需要监听RecyclerView的点击事件,更新PhotoGalleryFragment中的PhotoHolder,实现一个可以发送隐式intent的方法

private class PhotoHolder extends RecyclerView.ViewHolder implement View.OnClickListener {

private ImageView mItemImageView;

private GalleryItem mGalleryItem;

public PhotoHolder(View itemView) {

super(itemView);

mItemImageView = (ImageView)itemView.findViewById(R.id.item_image_view);

itemView.setOnClickListener(this);

}

public void bindDrawable(Drawable drawable) {

mItemImageView.setImageDrawable(drawable);

}

public void bindGalleryItem(GalleryItem galleryItem) {

mGalleryItem = galleryItem;

}

public void onClick(View v) {

Intent i = new Intent(Intent.ACTION_VIEW,mGalleryItem.getPhotoPageUri());

startActivity(i);

}

然后在PhotoAdapter.onBindViewHolder()方法中绑定PhotoHolder给GalleryItem

photoHolder.bindGalleryItem(galleryItem);

现在启动应用和点击任意图片,浏览器应用就会弹出加载显示对应的图片网页

 

二.使用WebView来打开图片的网页URL

通常如果我们不想打开浏览器来显示网页内容,而是想在activity中去显示网页的内容,对于大多数需要帮助文档的应用,常见的做法就是以网页的形式提供帮助文档,这样会方便后期的更新和维护,而打开浏览器查看帮助文档既不专业,也妨碍应用行为的定制,无法将网页整理到自己的用户界面里面去

如果想要在应用中显示网页的内容,那么我们就可以使用WebView类,对于这种方法需要用到下面的行为

(1)首先需要创建一个activity和一个显示WebView的fragment,先按照惯例定义一个名为fragment_photo_page.xml的文件,使用一个ConstraintLayout作为一级组件,在布局编辑框里面安排一个WebView作为一个ConstraintLayout的子组件

添加完WebView,相对于父组件,为每一边添加一个拘束,然后给WebView一个ID

下面是用来创建fragment,新建立PhotoPagerFragment类,继承上一章的VisibleFragment类,然后在这个新类里面实例化布局文件,引用WebView,并转发从intent数据中获取的URL

public class PhotoPagerFragment extends VisibleFragment {

private static final String ARG_URI = "photo_pager_url";

private Uri mUri;

private WebView mWebView;

public static PhotoPagerFragment newInstance(Uri uri) {

Bundle args = new Bundle();

args.putParcelable(ARG_URI,uri);

PhotoPagerFragment fragment = new PhotoPagerFragment();

fragment.setArguments(args);

return fragment;

}

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mUri = getArguments().getParcelable(ARG_URI);

}

public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {

View v = inflater.inflate(R.layout.fragment_photo_page,container,false);

mWebView = (WebView)v.findViewById(R.id.web_view);

return v;

}

}

}

此时PhotoPager类还没有完成,接下来就需要来完成它,新建立PhotoPageActivity的托管类,继承SingleFragmentActivity

//创建网页的activity

public class PhotoPagerActivity extends SingleFragmentActivity{

public static Intent newIntent(Context context,Uri PhotoPagerUri) {

Intent i = new Intent(context,PhotoPageActivity.class);

i.setData(photoPagerUri);

return i;

}

protected Fragment createFragment(){

return PhotoPagerFragment.newInstance(getInstance().getData());

}

}

现在放弃隐式intent,然后是启动新建立的activity

Intent i = PhotoPagerActivity.newIntent(getActivity(),mGalleryItem.getPhotoPagerUri());

startActivity(i);

然后这个activity还需要在配置文件中去配置好,这样这个activity才可以使用,不然程序会崩溃

现在启动的话,点击任意图片就会出现一个新的空的activity的出现

三.让WebView来显示Flickr的图片网页,需要完成下面的三件事

(1)首先告诉WebView需要打开的URL

(2)启动JavaScript,JavaScrip默认是禁止的(需要启动时Android Lint就会发起警告,那么对此就可以使用@SuppressLint("SetJavaScriptEndable"))来注解onCreateView()方法以用来禁止Lint的警告

(3)最后需要实现一个WebViewClient类(用来实现WebView的渲染事件)

public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {

View v = inflater.inflate(R.layout.fragment_photo_page,container,false);

mWebView = (WebView)v.findViewById(R.id.web_view);

mWebView.getSetting().setJavaScriptEnabled(true);

//如果没有WebViewClient,那么WebView会要求activity管理器找到一个新的activity来加载新的Url,我们需要在自己的应用中展示网页,那么添加WebViewClient后,按照它的默认实现,它会说:WebView,自己来载入URL吧,这样目标网页就会在WebView里面来打开

mWebView.setWebViewClient(new WebViewClient(){

mWebView.loadUrl(mUril.toString());//加载URL必须等到WebView配置完成后再来进行,这是最后一步

})

return v;

}

四.使用WebChromeClient优化WebView显示

这边我们来优化,为它添加一个标题视图和一个进度条,以视图的方式打开fragment_photo_page.xnl,拖入一个ProgressBar作为第二个子组件,删除WebView最上面的约束,再来设置他们之间的联系

接下来设置WebView的高度为Any Size,设置ProgressBar的高度为wrap_content,宽度为Any Size

最后选中ProgressBar组件,在右边的属性窗口中,将visibility和tools visibility分别设置为gone和visible,最后命名为progress_bar

为了使用ProgressBar,还需要使用WebView:WebChromeClient的第二个回调方法,WebChromeClient是一个事件回调接口,用来响应那些改变了浏览器中装饰元素的事件,包含 JavaScript警告信息,网页图标,状态条加载,以及当前网页标题的刷新

在PhotoPageFragment中添加

private ProgressBar mProgressBar;

在onCreateView方法中添加

mProgressBar = (ProgressBar)v.findViewById(R.id.progress_bar);

mProgressBar.setMax(100);

mWebView.setWebChromeClient(new WebChromeClient(){

public void onProgressChanged(WebView webView,int newProgress) {

if(newProgress == 100) {

mProgressBar.setVisibity(View.GONE);

}esle {

mProgressBar.setVisibility(View.VISIBLE);

mProgressBar.setProgress(newProgress);

}

//状态栏的改变的,变成来自网页的子标题

public void onReceivedTitle(WebView webView,String title) {

AppCompatActivity activity = (AppCompatActivity)getActivity();

Activity.getSupportActionBar().setSubtitle(title);

}

}

})

五.解决WebView的设备旋转问题

如果我们对设备进行了旋转,那么尽管应用工作如常,但是WebView重新加载了网页,这是因为网页数据太多,无法在onSaveInstanceState()里面保存,这边不能按照PhotoPagerFragment的保存,因为WebView是视图层级结构的一部分,所以它旋转肯定会摧毁然后重建,所以对于这些类(如VideoView),Android 推荐让activity自己去处理配置变更,也就是说,无需重新销毁重建activity,就能够直接调整自己的视图用来适应新的屏幕尺寸

需要在AndroidManidest文件里面去,对这个activity里面添加下面的代码

android:configChanges = "keyboardHidden|orientation|screenSize"//

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值