3.1.6 SlideshowPage
处理幻灯片动画显示。
其类图如下。
1)SlideshowView
负责处理幻灯片播放的view。
1.1)SlideshowAnimation
其继承自Animation,负责具体幻灯片切换的显示。这里用到两个对象,mPrevAnimation负责上一张图片动画显示,mCurrentAnimation负责当前图片动画显示,显示动画效果就是扩大,淡入淡出。
Animation类的基本用法如下:
1)使用前需要设置每张图片显示周期,使用setDuration()。
2)开始播放,使用start()。
3)calculate()返回单张图片是否在一个周期显示完毕。
1.2)FloatAnimation
与SlideshowAnimation配合,未研究。
1.3)BitmapTexture
存放显示的图片。这里也用到两个对象,mPrevTexture负责存放上一张图片数据,mCurrentTexture负责存放当前图片数据。
2)Slide
负责存放具体相片数据。
3)ShuffleSource
负责生成随机的图片序列。用于随机幻灯片显示图片。
4)SequentialSource
负责生成顺序的图片序列。用于顺序幻灯片显示图片。
3.1.7 PhotoDataAdapter
Photodataadapter属于photopage的数据层,负责在图片数据更新时请求刷新UI。
1)渲染显示各个界面元素的原理
Photopage界面上,显示的元素种类分为三种。完整画面显示的图片,位于图片下方的缩略图图片,可能出现的GIF图片。
Photopage界面上一般存在多个元素,一个完整图片以及很多张缩略图图片,要同时刷新这么多元素,只能多线程,而涉及的线程那么多,最好就是用线程池来管理。简单说,在需要渲染界面元素时,就将该渲染任务丢入线程池中,线程池中若有空闲线程就分配来处理之,没有则该任务挂起,等待一定时间。同时线程池容许存放的任务数有上限。如下图表示线程池处理渲染的原理图。
这里的发起更新图片请求通过updateImageRequests()来实现。
2)数据层与UI层的桥梁
该类保存了一个PhotoView,看其函数调用,很多都是notify开头的,可见该对象主要在这里扮演桥梁的角色。一旦数据更新了,就会经由它通知UI层进行更新,或是一旦UI层变化了了,就经由它通知数据层更新。
各种代码片段如下。
通知UI层更新。
通知数据层更新。
3)ReloadTask
继承自thread。该线程是是与SourceListener共同配合,处理当前显示图片检测到路径不存在时的情形。诸如,在文件管理器或是图库删除此图片时,就会进行该处理,通知界面各元素更新。
4)各种图片元素表示相关类
ImageEntry 类用于表示当前显示的图片。其结构如下:
private static class ImageEntry {
public int requestedBits = 0;
public int rotation;
public BitmapRegionDecoder fullImage;
public Bitmap screenNail;
public Future<Bitmap> screenNailTask;
public Future<BitmapRegionDecoder> fullImageTask;
public boolean failToLoad = false;
// the below members are added for Gif animation
public GifDecoder gifDecoder;
public Future<GifDecoder> gifDecoderTask;
public Bitmap currentGifFrame;
}
FullImageListener用于侦听全屏显示的图片的更新。
ScreenNailListener用于侦听缩略图显示的图片的更新。
ScreenNailJob用于缩略图更新时的具体处理,与ScreenNailListener配合使用。
GifDecoderListener用于侦听GIF图片的更新。
GifAnimation类用于表示当前显示的GIF图片,其结构如下:
private static class GifAnimation {
public ImageEntry entry;
public GifDecoder gifDecoder;
public int animatedIndex;
public int currentFrame;
public int totalFrameCount;
}
GifAnimationRunnable是负责GIF解码显示的runnale类。
5)图片缓存处理相关
要想在图片切换时速度加快,就应该建立一套缓存机制。Gallery 4.0主要通过在保存当前显示图片临近图片元素来实现。如前面所说,图片元素包括,完整画面显示的图片,位于图片下方的缩略图图片,可能出现的GIF图片。对于缩略图图片,IMAGE_CACHE_SIZE限定保存个数,这里是5,其余两种元素各保留一个。
保存图片元素使用ImageFetch,其类定义如下。
private static class ImageFetch {
int indexOffset;
int imageBit;
public ImageFetch(int offset, int bit) {
indexOffset = offset;
imageBit = bit;
}
}
6)图片裁切相关数据处理
相关类是TileImageViewAdapter。
7)DataManager
Mediaset以及mediaitem都用一个64bit的id来标识。高32bit用来标识其与父集的关系,低32bit用来标识本身,其作为私有id。对于mediaset,该私有id是唯一的。对于mediaitem,该私有id在其父集中是唯一的,全局来说并非唯一的。
父集的概念,应该就是文件夹的概念。Mediaitem不能作为其他元素的父集,而mediaset可以作为mediaitem的父集。
Datamanager用于管理mediaset以及mediaitem组成的树状数据结构的类。
8)DataListener
幻灯片播放时图片数据改变等时的侦听者。