MVP+RxJava+Dagger打造的Android Album

这个Demo类似Android的图库一样能扫描手机目录的大部分的图片,查看,管理,操作图片。这个Demo的组成是以MVP作为App的主要框架, Rxjava, Dagger作为辅助工具。

App的展示:

需要说明一下,我这个Album Demo只是我这个AllDemo
的一个子Demo,里面还包括了几个Demo的。而整个AllDemo也是采用MVP框架的。

这个Album Demo所涉及的代码文件有这些:


首先来说下ImageLoader和一些功能类。
这个类主要用来加载手机内的绝大部分图片,这不包括全部,原因有些其他App的图片是私有的。
loadDeviceImages方法用来加载手机图片,并返回Observable对象,这是RxJava的一个对象。想了解更多RxJava可以到官方wiki查看,毕竟我还没到熟悉程度,还在学习当中。

/**     * load device images     * @return Observable>     */    private Observable> loadDeviceImages() {        return new Observable>() {            @Override            protected void subscribeActual(Observer<? super List> observer) {                Cursor cursor = mContext.getContentResolver().query(                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,                        columnIndexs, null, null, MediaStore.Images.Media.DATE_ADDED);                if (cursor == null) {                    observer.onError(new NullPointerException());                }                // save all Image temporary                List temp = new ArrayList<>(cursor.getCount());                // 用于缓存加载的图片                mCacheDirty = true;                if (mCacheFolders == null) {                    mCacheFolders = new LinkedHashMap<>();                }                if (cursor.moveToLast()) {                    do {                        long id = cursor.getLong(cursor.getColumnIndex(columnIndexs[0]));                        String name = cursor.getString(cursor.getColumnIndex(columnIndexs[1]));                        String path = cursor.getString(cursor.getColumnIndex(columnIndexs[2]));                        String bucket = cursor.getString(cursor.getColumnIndex(columnIndexs[3]));                        File file = new File(path);                        if (file.exists()) {                            Image image = new Image(id, name, path, false);                            temp.add(image);                            Folder folder = mCacheFolders.get(bucket);                            if (folder == null) {                                folder = new Folder(bucket);                                mCacheFolders.put(bucket, folder);                            }                            folder.getImages().add(image);                        }                    } while (cursor.moveToPrevious());                }                cursor.close();                List folders = new ArrayList<>(mCacheFolders.values());                observer.onNext(folders);            }        };    }

该方法用到的是Observable.concat的操作方法,该方法用了两个参数方法,’loadCacheImages()’和’loadDeviceImages()’
而concat首先判断前一个是否返回null,如果返回null,再取第二个’loadDeviceImages()’返回值,如果又是null,
则取first,初始化List。然而,这样可以做到缓存的作用。

public Single> loadImages() {    return Observable.concat(loadCacheImages(), loadDeviceImages())            .first(new ArrayList());}
public interface CameraModule {    Intent getCameraIntent(Context context);    void getImage(Context context, Intent intent, ImageCaptureReadyListener listener);}

CameraModule是一个接口。’getCameraIntent()’返回调用相机的一个intent, ‘getImage()’在调用
相机,拍照完照片后,在Activity的’onActivityResult()’方法调用,把拍照完的照片文件加入到media content里面。

如果不这么做,在调用'loadDeviceImages()'时,执行下面代码时获取不了那张图片的。所以需要注意。

Cursor cursor = mContext.getContentResolver().query(        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,        columnIndexs, null, null, MediaStore.Images.Media.DATE_ADDED);

DefaultCameraModule是CameraModule接口的实现类。

ImageCaptureReadyListener是一个监听接口,在调用CameraModule的’getImage()’方法时,在scanFile
完成后调用。

下面要讲下这个Album Demo的MVP框架
AlbumContract类是定义了V和P的方法,所有关于UI显示都写在这个V上,所有有关逻辑方面的都写在这个P上。
M就是我们数据的Model,比如这里的Image, Folder类。其实可以通过AlbumContract类的一些方法可以看出,
这个Demo所具有的一些功能表面,这也是MVP的好处,功能清晰,分明。如果对于整个项目来说,每一个功能及UI最好
写到一个包里面。
它们之间的关系如下图:

这里忘记要说的是,这个Demo只用了一个MainActivity,所有的界面都是用了Fragment。当然每个Fragment
都继承了一个基类的,基类都在base包。

希望大家可以看下AlbumFragment和AlbumPresenter对Contract的方法的实现。

下面就是要讲下用到的Dagger注入工具
AlbumModule和AlbumComponent是Dagger需要的类,具体还是看看官方文档。
Dagger比如要做一道菜,Module是所需要的配料,和材料,Compoenent犹如把各个配料和材料搞在一起或装在一起,
待放入锅里或煲里。对于Dagger自己还没有深入的了解,所以也是在实践和研究当中。因此这块暂时不多说,上来
先看代码,主要看怎么用先。等我有了深入了解,再来分享下囖。

这个AllDemo项目还在不断完善当中,里面有些UI,工具类,也有参考了他人的代码,自己也是新人吧,希望各路
大神可以给下建议和修改。毕竟自己写的代码还不是很优雅的,还要继续的提升。

更多相关文章

  1. android三种菜单介绍
  2. [Android] 问题记录 - Cupcake & Donut, Sdcard 正确使用方法
  3. android下播放器视频输出方法总结
  4. 【QQ登录】Android_SDK使用说明
  5. Android手动回收bitmap,引发Canvas: trying to use a recycled b
  6. Android系列之网络(三)----使用HttpClient发送HTTP请求(分别通过GET
  7. android真实项目教程(一)——App应用框架搭建_by_CJJ
  8. 关于Android的TimePicker和DatePicker一些简单的使用问题
  9. Android热补丁动态修复技术(四):完善框架①

随机推荐

  1. Android图片代码换色,背景换色
  2. android网络连接使用GET方式请求服务器时
  3. Android实现底部弹出列表选择器
  4. Android工程中R.java文件突然消失
  5. Android客户端采用Http 协议Post方式请求
  6. Android的垃圾回收机制(android refbase类
  7. android中轮播图的实现
  8. OpenCV自学笔记31. Android 上使用jni和o
  9. 自定义Android(安卓)Toasts风格
  10. Android开发——了解android项目目录结构