1. 程式人生 > >安卓權威編程 挑戰練習 16章

安卓權威編程 挑戰練習 16章

pack 拍攝 eat 節點 setimage widget 我們 over getheight

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 作用是註冊一個回調函數,當在一個視圖樹中全局布局發生改變或者視圖樹中的某個視圖的可視狀態發生改變時調用這個回調函數。

安卓權威編程 挑戰練習 16章