安卓权威编程 挑战练习 16章

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 作用是注册一个回调函数,当在一个视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变时调用这个回调函数。

时间: 2024-12-31 15:11:37

安卓权威编程 挑战练习 16章的相关文章

安卓权威编程-挑战练习 15章。

15.5 挑战练习:ShareCompat 第一个练习比较简单.Android支持库有个叫作 ShareCompat 的类,它有一个 IntentBuilder. ShareCompat.IntentBuilder 内部类.利用这个内部类创建用于发送消息按钮的 Intent 略微方 便一些. 因此,你要接受的挑战就是:在 mReportButton 的监听器中,改用 ShareCompat. IntentBuilder 来创建你的 Intent . 修改CrimeFragment中的mRepor

安卓权威编程指南 - 第五章学习笔记(两个Activity)

学习安卓编程权威指南第五章的时候自己写了个简单的Demo来加深理解两个Activity互相传递数据的问题,然后将自己的学习笔记贴上来,如有错误还请指正. IntentActivityDemo学习笔记 题目:ActivityA登录界面(用户名.密码.登陆按钮),ActivityB(Edit,返回按键:SubmitButton).A界面输入用户名和密码传到B中,B验证用户输入的用户名和密码,如果错误就返回A,并用Toast 显示用户名和密码错误:如果正确,就在第二个 activity中显示一个Edi

安卓权威编程 挑战练习13.6

挑战练习:删除crime记录 CriminalIntent引用目前不支持删除现有crimes记录,请为CrimeFragment添加菜单项,允许用户删除当前记录,用户点击删除菜单项后,记得调用CrimeFragment托管活动的finish方法回退到前一个activity界面. 首先为Crime增加一个菜单项. 在menu文件夹下创建一个名为crimefragment_crime的布局文件,代码如下: <?xml version="1.0" encoding="utf-

安卓权威编程-笔记(19章 使用SoundPool播放音频)

针对BeatBox应用,可以使用SoundPool这个特别定制的实用工具. SoundPool能加载一批声音资源到内存中,并支持同时播放多个音频文件.因此所以,就算用户兴奋起来,狂按按钮播放全部音频,也不必担心会损坏应用或者耗光手机电量. 1. 创建SoundPool 1 /* 2 * Lollipop引入了新的方式创建SoundPool:使用SoundPool.Builder.为了兼容api 16最低级别,只能选择使用SoundPool(int int int)这个老构造方法. 3 * 第一个

安卓权威编程 挑战练习 13.8 用于RecyclerView的空视图

当前,CriminalIntent应用启动后,会显示一个空白列表.从用户体验上来讲,即使crime列表 是空的,也应展示提示或解释类信息. 请设置空视图展示类似"没有crime记录可以显示"的信息.再添加一个按钮,方便用户直 接创建新的crime记录. 判断crime列表是否包含数据,然后使用任何类都有的 setVisibility 方法控制占位视图的 显示. 首先修改fragment_crime_list视图,增加一个TextView和一个Button控件: <Relative

安卓权威编程指南 挑战练习 22章 应用图标

本章使用了 ResolveInfo.loadLabel(...) 方法,在启动器应用中显示了各个activity的名 称. ResolveInfo 类还提供了另一个名为 loadIcon() 的方法.可以使用该方法为每个应用加载 显示图标.你要接受的挑战就是,为NerdLauncher应用中显示的所有应用添加对应的图标. 首先增加一个RecyclerView的条目布局,代码如下: 1 <?xml version="1.0" encoding="utf-8"?&

安卓权威编程指南 挑战练习(第26章 在 Lollipop 设备上使用 JobService)

26.11 挑战练习:在 Lollipop 设备上使用 JobService 请创建另一个 PollService 实现版本.新的 PollService 应该继承 JobService 并使用 JobScheduler 来运行.在 PollService 启动代码中,检查系统版本是否为Lollipop:如果是,就 使用 JobScheduler 计划运行 JobService :如果不是,依然使用 AlarmManager 实现. JobService类: 1 package com.bign

安卓权威编程指南 挑战练习 24章 预加载以及缓存

24.7 挑战练习:预加载以及缓存 应用中并非所有任务都能即时完成,对此,大多用户表示理解.不过,即使是这样,开发者们也一直在努力做到最好.为了让应用反应更快,大多数现实应用都通过以下两种方式增强自己的代码:? 增加缓存层 ? 预加载图片 缓存指存储一定数目 Bitmap 对象的地方.这样,即使不再使用这些对象,它们也依然存储在那里. 缓存的存储空间有限,因此,在缓存空间用完的情况下,需要某种策略对保存的对象做一定的取舍.许多缓存机制使用一种叫作LRU(least recently used,最

安卓权威编程指南 挑战练习 25章 深度优化 PhotoGallery 应用

你可能已经注意到了,提交搜索时, RecyclerView 要等好一会才能刷新显示搜索结果.请接受挑战,让搜索过程更流畅一些.用户一提交搜索,就隐藏软键盘,收起 SearchView 视图(回到只显示搜索按钮的初始状态).再来个挑战.用户一提交搜索,就初始化 RecyclerView ,显示一个搜索结果加载状态界面(使用状态指示器).下载到JSON数据之后,就删除状态指示器.也就是说,一旦开始下载图片, 就不应显示加载状态了 1.提交搜索,隐藏软键盘,收起SearchView: 将SearchV