16.7 挑战练习:优化照片显示
现在虽然能够看到拍摄的照片,但没法看到它们的细节。
请创建能显示缩放版本照片的 DialogFragment 。只要点击缩略图,就会弹出这个
DialogFragment ,让用户查看缩放版本的陋习现场图片。

创建一个根节点为ImageView的布局文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/iv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
</ImageView>

接着创建一个PictureDialogFragment继承DialogFragement,用来显示大图。

 1 package com.bignerdranch.android.criminallntent;
 2 
 3 import android.app.Dialog;
 4 import android.os.Bundle;
 5 import android.support.annotation.NonNull;
 6 import android.support.v4.app.DialogFragment;
 7 import android.view.View;
 8 import android.widget.ImageView;
 9 
10 /**
11  * Created by Leo on 2017/7/16.
12  */
13 
14 public class PictureDialogFragment extends DialogFragment {
15 
16     public static PictureDialogFragment newInstance(String path){
17         Bundle args = new Bundle();
18         args.putString("path",path);
19 
20         PictureDialogFragment pictureDialogFragment = new PictureDialogFragment();
21         pictureDialogFragment.setArguments(args);
22         return pictureDialogFragment;
23     }
24 
25     @NonNull
26     @Override
27     public Dialog onCreateDialog(Bundle savedInstanceState) {
28         //获取到之前传过来的路径
29         String path = getArguments().getString("path");
30         //创建一个dialog
31         final Dialog dialog = new Dialog(getActivity());
32         //设置dialog的布局,为之前创建的布局文件,里面仅有一个ImageView
33         dialog.setContentView(R.layout.picture);
34         //找到控件
35         ImageView imageView = (ImageView)dialog.findViewById(R.id.iv);
36         //使用 PictureUtils 类的工具来获得缩放的 Bitmap
37         imageView.setImageBitmap(PictureUtils.getScaleBitmap(path,getActivity()));
38         //设置点击事件,当点击图片时候,dialog消失。
39         imageView.setOnClickListener(new View.OnClickListener() {
40             @Override
41             public void onClick(View v) {
42                 dialog.dismiss();
43             }
44         });
45 
46         return dialog;
47     }
48 }

最后修改CrimeFragment中的代码,使点击缩略图的时候让大图显示出来。

给缩略图控件增加点击事件即可

1 mPhotoView.setOnClickListener(new View.OnClickListener() {
2             @Override
3             public void onClick(View v) {
4                 FragmentManager manager = getFragmentManager();
5                 PictureDialogFragment pictureDialogFragment = PictureDialogFragment.newInstance(mPhotoFile.getPath());
6                 pictureDialogFragment.setTargetFragment(CrimeFragment.this,0);
7                 pictureDialogFragment.show(manager,"a");
8             }
9         });

 


16.8 挑战练习:优化缩略图加载
本章,我们只能大致估算缩略图的目标尺寸。虽说可行且实施迅速,但还不够理想。
Android有个现成的API工具可用,叫作 ViewTreeObserver 。利用这个对象,我们可以从
Activity 层级结构中获取任何视图:
ViewTreeObserver observer = mImageView.getViewTreeObserver();
我们可以为 ViewTreeObserver 对象设置包括 OnGlobalLayoutListener 在内的各种监听
器。使用 OnGlobalLayoutListener 监听器,可以监听任何布局的传递,控制事件的发生。
调整代码,使用有效的 mPhotoView 尺寸,等到有布局切换时再调用 updatePhotoView()
方法。

修改CrimeFragment()方法中的updatePhotoView()方法。

1 private void updatePhotoView(int width, int height){
2         if(mPhotoFile == null || !mPhotoFile.exists()){
3             mPhotoView.setImageDrawable(null);
4         }else {
5             mBitmap = PictureUtils.getScaledBitmap(mPhotoFile.getPath(),width,height);
6             mPhotoView.setImageBitmap(mBitmap);
7         }
8     }

对其增加了width和height两个参数,让updatePhoto方法按照我们传过来的参数进行缩放。

之后在在onCreateView()方法中增加如下代码:

1       mPhotoObserver = mPhotoView.getViewTreeObserver();
2         mPhotoObserver.addOnGlobalLayoutListener(
3                 new ViewTreeObserver.OnGlobalLayoutListener() {
4                     @Override
5                     public void onGlobalLayout() {
6                         updatePhotoView(mPhotoView.getWidth(), mPhotoView.getHeight());
7                     }
8                 });

首先获得一个注册监听视图树的观察者,通过这个观察者可以监听任何布局的传递,控制事件的发生。

这里增加了一个OnGlobalLayoutListener 作用是注册一个回调函数,当在一个视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变时调用这个回调函数。