├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── styles.xml
│ │ │ │ └── dimens.xml
│ │ │ ├── drawable-xhdpi
│ │ │ │ ├── cha.png
│ │ │ │ ├── toux2.png
│ │ │ │ ├── addphoto.png
│ │ │ │ ├── ic_wrong.png
│ │ │ │ ├── ic_success.png
│ │ │ │ ├── ic_wifi_off.png
│ │ │ │ ├── no_content_tip.png
│ │ │ │ ├── ic_empty_picture.png
│ │ │ │ ├── ic_image_loading.png
│ │ │ │ └── loading_progress.png
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── drawable-mdpi
│ │ │ │ └── ic_arrow_back.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── anim
│ │ │ │ ├── fade_in.xml
│ │ │ │ ├── fade_out.xml
│ │ │ │ ├── act_fade_in_center.xml
│ │ │ │ └── act_fade_out_center.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── drawable
│ │ │ │ ├── selector_orange_maincolor.xml
│ │ │ │ ├── selector_guide_bg.xml
│ │ │ │ └── ic_launcher_background.xml
│ │ │ ├── layout
│ │ │ │ ├── item_pager_image.xml
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── act_image_pager.xml
│ │ │ │ ├── item_grid_photo.xml
│ │ │ │ └── activity_push.xml
│ │ │ └── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── barnettwong
│ │ │ │ ├── MyApplication.java
│ │ │ │ └── pushcommunity
│ │ │ │ ├── view
│ │ │ │ ├── NoScrollGridView.java
│ │ │ │ └── ViewPagerFixed.java
│ │ │ │ ├── util
│ │ │ │ ├── ViewHolderUtil.java
│ │ │ │ ├── GlideRoundTransformUtil.java
│ │ │ │ ├── GlideCircleTransfromUtil.java
│ │ │ │ └── ImageLoaderUtils.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── bean
│ │ │ │ └── PageBean.java
│ │ │ │ ├── adapter
│ │ │ │ ├── BaseAblistViewAdapter.java
│ │ │ │ └── NinePicturesAdapter.java
│ │ │ │ ├── PushCommunityActivity.java
│ │ │ │ └── BigImagePagerActivity.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── barnettwong
│ │ │ └── pushcommunity
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── barnettwong
│ │ └── pushcommunity
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── photoPicker
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── values
│ │ │ ├── ids.xml
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ ├── dimens.xml
│ │ │ └── styles.xml
│ │ ├── drawable-hdpi
│ │ │ ├── ic_album.png
│ │ │ ├── ic_back.png
│ │ │ ├── ic_checked.png
│ │ │ ├── ic_uncheck.png
│ │ │ ├── ic_take_photo.png
│ │ │ └── ic_folder_selected.png
│ │ ├── drawable-mdpi
│ │ │ ├── ic_album.png
│ │ │ ├── ic_back.png
│ │ │ ├── ic_checked.png
│ │ │ ├── ic_uncheck.png
│ │ │ ├── ic_take_photo.png
│ │ │ └── ic_folder_selected.png
│ │ ├── drawable-xhdpi
│ │ │ ├── ic_back.png
│ │ │ ├── ic_album.png
│ │ │ ├── ic_checked.png
│ │ │ ├── ic_uncheck.png
│ │ │ ├── ic_take_photo.png
│ │ │ └── ic_folder_selected.png
│ │ ├── drawable-xxhdpi
│ │ │ ├── ic_album.png
│ │ │ ├── ic_back.png
│ │ │ ├── ic_checked.png
│ │ │ ├── ic_uncheck.png
│ │ │ ├── ic_take_photo.png
│ │ │ └── ic_folder_selected.png
│ │ ├── drawable-xxxhdpi
│ │ │ ├── ic_album.png
│ │ │ ├── ic_back.png
│ │ │ ├── ic_checked.png
│ │ │ ├── ic_uncheck.png
│ │ │ ├── ic_take_photo.png
│ │ │ └── ic_folder_selected.png
│ │ ├── values-v21
│ │ │ └── styles.xml
│ │ ├── values-v19
│ │ │ └── styles.xml
│ │ ├── values-w820dp
│ │ │ └── dimens.xml
│ │ ├── xml
│ │ │ └── file_paths.xml
│ │ └── layout
│ │ │ ├── item_img_sel_take_photo.xml
│ │ │ ├── item_img_sel.xml
│ │ │ ├── fragment_img_sel.xml
│ │ │ ├── activity_img_sel.xml
│ │ │ └── item_img_sel_folder.xml
│ │ ├── java
│ │ └── com
│ │ │ └── yuyh
│ │ │ └── library
│ │ │ └── imgsel
│ │ │ ├── common
│ │ │ ├── OnItemClickListener.java
│ │ │ ├── OnFolderChangeListener.java
│ │ │ ├── Constant.java
│ │ │ └── Callback.java
│ │ │ ├── ImageLoader.java
│ │ │ ├── bean
│ │ │ ├── Folder.java
│ │ │ └── Image.java
│ │ │ ├── widget
│ │ │ ├── SquareRelativeLayout.java
│ │ │ └── DividerGridItemDecoration.java
│ │ │ ├── utils
│ │ │ ├── StatusBarCompat.java
│ │ │ ├── LogUtils.java
│ │ │ └── FileUtils.java
│ │ │ ├── adapter
│ │ │ ├── FolderListAdapter.java
│ │ │ └── ImageListAdapter.java
│ │ │ ├── ImgSelConfig.java
│ │ │ ├── ImgSelActivity.java
│ │ │ └── ImgSelFragment.java
│ │ └── AndroidManifest.xml
├── proguard-rules.pro
├── build.gradle
└── readme.md
├── settings.gradle
├── screenshot
├── 1.png
├── 2.png
└── 3.png
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── gradle.properties
├── README.md
├── gradlew.bat
└── gradlew
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/photoPicker/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | include ':photoPicker'
3 |
--------------------------------------------------------------------------------
/screenshot/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/screenshot/1.png
--------------------------------------------------------------------------------
/screenshot/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/screenshot/2.png
--------------------------------------------------------------------------------
/screenshot/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/screenshot/3.png
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | PushCommunity
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/cha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/drawable-xhdpi/cha.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/toux2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/drawable-xhdpi/toux2.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/addphoto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/drawable-xhdpi/addphoto.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_wrong.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/drawable-xhdpi/ic_wrong.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/drawable-xhdpi/ic_success.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_arrow_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/drawable-mdpi/ic_arrow_back.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_wifi_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/drawable-xhdpi/ic_wifi_off.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/no_content_tip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/drawable-xhdpi/no_content_tip.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-hdpi/ic_album.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-hdpi/ic_album.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-hdpi/ic_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-hdpi/ic_back.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-mdpi/ic_album.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-mdpi/ic_album.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-mdpi/ic_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-mdpi/ic_back.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xhdpi/ic_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xhdpi/ic_back.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_empty_picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/drawable-xhdpi/ic_empty_picture.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_image_loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/drawable-xhdpi/ic_image_loading.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/loading_progress.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/drawable-xhdpi/loading_progress.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-hdpi/ic_checked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-hdpi/ic_checked.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-hdpi/ic_uncheck.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-hdpi/ic_uncheck.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-mdpi/ic_checked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-mdpi/ic_checked.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-mdpi/ic_uncheck.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-mdpi/ic_uncheck.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xhdpi/ic_album.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xhdpi/ic_album.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xhdpi/ic_checked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xhdpi/ic_checked.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xhdpi/ic_uncheck.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xhdpi/ic_uncheck.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xxhdpi/ic_album.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xxhdpi/ic_album.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xxhdpi/ic_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xxhdpi/ic_back.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xxxhdpi/ic_album.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xxxhdpi/ic_album.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xxxhdpi/ic_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xxxhdpi/ic_back.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-hdpi/ic_take_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-hdpi/ic_take_photo.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-mdpi/ic_take_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-mdpi/ic_take_photo.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xxhdpi/ic_checked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xxhdpi/ic_checked.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xxhdpi/ic_uncheck.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xxhdpi/ic_uncheck.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xxxhdpi/ic_checked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xxxhdpi/ic_checked.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xxxhdpi/ic_uncheck.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xxxhdpi/ic_uncheck.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xhdpi/ic_take_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xhdpi/ic_take_photo.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xxhdpi/ic_take_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xxhdpi/ic_take_photo.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xxxhdpi/ic_take_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xxxhdpi/ic_take_photo.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-hdpi/ic_folder_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-hdpi/ic_folder_selected.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-mdpi/ic_folder_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-mdpi/ic_folder_selected.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xhdpi/ic_folder_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xhdpi/ic_folder_selected.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xxhdpi/ic_folder_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xxhdpi/ic_folder_selected.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/drawable-xxxhdpi/ic_folder_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Winstonokk/PublishCommunity-master/HEAD/photoPicker/src/main/res/drawable-xxxhdpi/ic_folder_selected.png
--------------------------------------------------------------------------------
/photoPicker/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches/build_file_checksums.ser
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | .DS_Store
9 | /build
10 | /captures
11 | .externalNativeBuild
12 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/photoPicker/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #22000000
4 | #008577
5 | #ffffff
6 |
--------------------------------------------------------------------------------
/photoPicker/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | library
3 |
4 |
5 | Hello blank fragment
6 |
7 |
--------------------------------------------------------------------------------
/photoPicker/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/photoPicker/src/main/res/values-v19/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_orange_maincolor.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/common/OnItemClickListener.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.common;
2 |
3 | import com.yuyh.library.imgsel.bean.Image;
4 |
5 | /**
6 | * @author yuyh.
7 | * @date 2016/8/5.
8 | */
9 | public interface OnItemClickListener {
10 |
11 | void onClick(int position, Image image);
12 | }
13 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/common/OnFolderChangeListener.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.common;
2 |
3 | import com.yuyh.library.imgsel.bean.Folder;
4 |
5 | /**
6 | * @author yuyh.
7 | * @date 2016/8/5.
8 | */
9 | public interface OnFolderChangeListener {
10 |
11 | void onChange(int position, Folder folder);
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 | #008577
8 | #00000000
9 |
10 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/ImageLoader.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel;
2 |
3 | import android.content.Context;
4 | import android.widget.ImageView;
5 |
6 | import java.io.Serializable;
7 |
8 | /**
9 | * @author yuyh.
10 | * @date 2016/8/5.
11 | */
12 | public interface ImageLoader extends Serializable {
13 | void displayImage(Context context, String path, ImageView imageView);
14 | }
--------------------------------------------------------------------------------
/photoPicker/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/photoPicker/src/main/res/xml/file_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/common/Constant.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.common;
2 |
3 | import com.yuyh.library.imgsel.ImgSelConfig;
4 |
5 | import java.util.ArrayList;
6 |
7 | /**
8 | * @author yuyh.
9 | * @date 2016/8/5.
10 | */
11 | public class Constant {
12 |
13 | public static ImgSelConfig config;
14 |
15 | public static int screenWidth = 0;
16 |
17 | public static ArrayList imageList = new ArrayList<>();
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_pager_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/common/Callback.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.common;
2 |
3 | import java.io.File;
4 | import java.io.Serializable;
5 |
6 | /**
7 | * @author yuyh.
8 | * @date 2016/8/5.
9 | */
10 | public interface Callback extends Serializable {
11 |
12 | void onSingleImageSelected(String path);
13 |
14 | void onImageSelected(String path);
15 |
16 | void onImageUnselected(String path);
17 |
18 | void onCameraShot(File imageFile);
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
--------------------------------------------------------------------------------
/photoPicker/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/test/java/com/barnettwong/pushcommunity/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/act_fade_in_center.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/act_fade_out_center.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/MyApplication.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.content.res.Resources;
6 |
7 | public class MyApplication extends Application {
8 |
9 | private static MyApplication baseApplication;
10 |
11 | @Override
12 | public void onCreate() {
13 | super.onCreate();
14 | baseApplication = this;
15 | }
16 |
17 | public static Context getAppContext() {
18 | return baseApplication;
19 | }
20 | public static Resources getAppResources() {
21 | return baseApplication.getResources();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 | 6dp
7 | 6dp
8 |
9 |
10 | 10sp
11 | 12sp
12 | 14sp
13 | 16sp
14 | 20sp
15 | 24sp
16 |
17 |
18 |
--------------------------------------------------------------------------------
/photoPicker/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\AndroidDev\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
15 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/photoPicker/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | version = "1.1.0" // 版本号
3 |
4 | android {
5 | compileSdkVersion 28
6 | buildToolsVersion '28.0.2'
7 | resourcePrefix "imgsel"
8 |
9 | defaultConfig {
10 | minSdkVersion 15
11 | targetSdkVersion 28
12 | versionCode 5
13 | versionName "1.1.0"
14 | }
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
19 | }
20 | }
21 | }
22 |
23 | dependencies {
24 | api fileTree(include: ['*.jar'], dir: 'libs')
25 | api 'com.android.support:appcompat-v7:28.0.0'
26 | api 'com.android.support:support-v4:28.0.0'
27 | api 'com.android.support:recyclerview-v7:28.0.0'
28 | api 'com.yuyh.easyadapter:library:1.0.0'
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/bean/Folder.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.bean;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Folder bean
7 | * Created by Yancy on 2015/12/2.
8 | */
9 | public class Folder {
10 |
11 | public String name;
12 | public String path;
13 | public Image cover;
14 | public List images;
15 |
16 | public boolean isAll = false;
17 |
18 | public Folder(){
19 |
20 | }
21 |
22 | public Folder(boolean isAll){
23 | this.isAll = isAll;
24 | }
25 |
26 | @Override
27 | public boolean equals(Object o) {
28 | try {
29 | Folder other = (Folder) o;
30 | return this.path.equalsIgnoreCase(other.path);
31 | } catch (ClassCastException e) {
32 | e.printStackTrace();
33 | }
34 | return super.equals(o);
35 | }
36 | }
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/bean/Image.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.bean;
2 |
3 | /**
4 | * Image bean
5 | * Created by Yancy on 2015/12/2.
6 | */
7 | public class Image {
8 |
9 | public String path;
10 | public String name;
11 | public long time;
12 |
13 | public boolean isCamera = false;
14 |
15 | public Image(String path, String name, long time) {
16 | this.path = path;
17 | this.name = name;
18 | this.time = time;
19 | }
20 |
21 | public Image(){
22 | isCamera = true;
23 | }
24 |
25 | @Override
26 | public boolean equals(Object o) {
27 | try {
28 | Image other = (Image) o;
29 | return this.path.equalsIgnoreCase(other.path);
30 | } catch (ClassCastException e) {
31 | e.printStackTrace();
32 | }
33 | return super.equals(o);
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/act_image_pager.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/barnettwong/pushcommunity/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.barnettwong.pushcommunity", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_guide_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
8 |
9 |
10 |
12 |
13 |
14 | -
15 |
18 |
19 |
20 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/photoPicker/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
12 |
13 |
18 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/photoPicker/src/main/res/layout/item_img_sel_take_photo.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/pushcommunity/view/NoScrollGridView.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity.view;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.GridView;
6 |
7 | /**
8 | * description:不会滚动的gridview
9 | */
10 | public class NoScrollGridView extends GridView {
11 | public NoScrollGridView(Context context, AttributeSet attrs) {
12 | super(context, attrs);
13 | }
14 | public NoScrollGridView(Context context) {
15 | super(context);
16 | }
17 | public NoScrollGridView(Context context, AttributeSet attrs, int defStyle) {
18 | super(context, attrs, defStyle);
19 | }
20 | @Override
21 | public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
22 | int expandSpec = MeasureSpec.makeMeasureSpec(
23 | Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
24 | super.onMeasure(widthMeasureSpec, expandSpec);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PublishCommunity-master
2 | 仿微博,QQ空间,论坛 ,九宫格图文混排发表说说,动态,帖子。
3 |
4 | 注意点:
5 | android6.0动态权限申请;Android7.0调用系统相机拍照、访问相册问题(申明FileProvider)。
6 |
7 |
8 | 
9 |
10 | MIT License
11 | ===================================
12 | Copyright 2017-2018, wangfeng19930909
13 |
14 | Licensed under the Apache License, Version 2.0 (the "License");
15 | you may not use this file except in compliance with the License.
16 | You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
17 | Unless required by applicable law or agreed to in writing, software
18 | distributed under the License is distributed on an "AS IS" BASIS,
19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 | See the License for the specific language governing permissions and
21 | limitations under the License.
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/pushcommunity/view/ViewPagerFixed.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity.view;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.MotionEvent;
6 |
7 | /**
8 | * des:修复viewpager
9 | */
10 | public class ViewPagerFixed extends android.support.v4.view.ViewPager {
11 |
12 | public ViewPagerFixed(Context context) {
13 | super(context);
14 | }
15 |
16 | public ViewPagerFixed(Context context, AttributeSet attrs) {
17 | super(context, attrs);
18 | }
19 |
20 | @Override
21 | public boolean onTouchEvent(MotionEvent ev) {
22 | try {
23 | return super.onTouchEvent(ev);
24 | } catch (IllegalArgumentException ex) {
25 | ex.printStackTrace();
26 | }
27 | return false;
28 | }
29 |
30 | @Override
31 | public boolean onInterceptTouchEvent(MotionEvent ev) {
32 | try {
33 | return super.onInterceptTouchEvent(ev);
34 | } catch (IllegalArgumentException ex) {
35 | ex.printStackTrace();
36 | }
37 | return false;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/photoPicker/src/main/res/layout/item_img_sel.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
20 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_grid_photo.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
15 |
16 |
21 |
22 |
23 |
30 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/widget/SquareRelativeLayout.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.RelativeLayout;
6 |
7 | public class SquareRelativeLayout extends RelativeLayout {
8 |
9 | public SquareRelativeLayout(Context context, AttributeSet attrs,
10 | int defStyle) {
11 | super(context, attrs, defStyle);
12 | }
13 |
14 | public SquareRelativeLayout(Context context, AttributeSet attrs) {
15 | super(context, attrs);
16 | }
17 |
18 | public SquareRelativeLayout(Context context) {
19 | super(context);
20 | }
21 |
22 | @Override
23 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
24 | setMeasuredDimension(getDefaultSize(0, widthMeasureSpec),
25 | getDefaultSize(0, heightMeasureSpec));
26 |
27 | int childWidthSize = getMeasuredWidth();
28 | // 高度和宽度一样
29 | heightMeasureSpec = widthMeasureSpec = MeasureSpec.makeMeasureSpec(
30 | childWidthSize, MeasureSpec.EXACTLY);
31 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/pushcommunity/util/ViewHolderUtil.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity.util;
2 |
3 | import android.util.SparseArray;
4 | import android.view.View;
5 |
6 | public class ViewHolderUtil {
7 | // I added a generic return type to reduce the casting noise in client code
8 | @SuppressWarnings("unchecked")
9 | public static T get(View view, int id) {
10 | SparseArray viewHolder = (SparseArray) view.getTag();
11 | if (viewHolder == null) {
12 | viewHolder = new SparseArray();
13 | view.setTag(viewHolder);
14 | }
15 | View childView = viewHolder.get(id);
16 | if (childView == null) {
17 | childView = view.findViewById(id);
18 | viewHolder.put(id, childView);
19 | }
20 | return (T) childView;
21 | }
22 |
23 |
24 |
25 | /*
26 | * 在getview里面的用法
27 | *
28 | * @Override public View getView(int position, View convertView, ViewGroup
29 | * parent) {
30 | *
31 | * if (convertView == null) { convertView = LayoutInflater.from(context)
32 | * .inflate(R.layout.banana_phone, parent, false); }
33 | *
34 | * ImageView bananaView = ViewHolder.get(convertView, R.id.banana);
35 | * TextView phoneView = ViewHolder.get(convertView, R.id.phone);
36 | *
37 | * BananaPhone bananaPhone = getItem(position);
38 | * phoneView.setText(bananaPhone.getPhone());
39 | * bananaView.setImageResource(bananaPhone.getBanana());
40 | *
41 | * return convertView;
42 | * }
43 | */
44 |
45 |
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/photoPicker/src/main/res/layout/fragment_img_sel.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
9 |
10 |
17 |
18 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/photoPicker/readme.md:
--------------------------------------------------------------------------------
1 | 使用方法:
2 | /**
3 | * 开启图片选择器
4 | */
5 | private void choosePhoto() {
6 | ImgSelConfig config = new ImgSelConfig.Builder(loader)
7 | // 是否多选
8 | .multiSelect(true)
9 | // 确定按钮背景色
10 | .btnBgColor(Color.TRANSPARENT)
11 | .titleBgColor(ContextCompat.getColor(this,R.color.main_color))
12 | // 使用沉浸式状态栏
13 | .statusBarColor(ContextCompat.getColor(this,R.color.main_color))
14 | // 返回图标ResId
15 | .backResId(R.drawable.ic_arrow_back)
16 | .title("图片")
17 | // 第一个是否显示相机
18 | .needCamera(true)
19 | // 最大选择图片数量
20 | .maxNum(9-ninePicturesAdapter.getPhotoCount())
21 | .build();
22 | ImgSelActivity.startActivity(this, config, REQUEST_CODE);
23 | }
24 | private ImageLoader loader = new ImageLoader() {
25 | @Override
26 | public void displayImage(Context context, String path, ImageView imageView) {
27 | ImageLoaderUtils.display(context,imageView,path);
28 | }
29 | };
30 |
31 | @Override
32 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
33 | super.onActivityResult(requestCode, resultCode, data);
34 | if (requestCode == REQUEST_CODE && resultCode == RESULT_OK && data != null) {
35 | List pathList = data.getStringArrayListExtra(ImgSelActivity.INTENT_RESULT);
36 |
37 | }
38 | }
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "com.barnettwong.pushcommunity"
7 | minSdkVersion 15
8 | targetSdkVersion 28
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(dir: 'libs', include: ['*.jar'])
23 | implementation 'com.android.support:appcompat-v7:28.0.0'
24 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
25 | testImplementation 'junit:junit:4.12'
26 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
27 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
28 |
29 | implementation 'com.github.bumptech.glide:glide:3.6.1'//显示图片框架
30 | implementation('com.commit451:PhotoView:1.2.4') {//图片缩放
31 | exclude module: 'support-v4'
32 | }
33 | //工具类开源库
34 | implementation 'com.blankj:utilcode:1.19.0'
35 | implementation 'com.tbruyelle.rxpermissions:rxpermissions:0.7.0@aar'
36 | //retrofit和rxjava
37 | implementation 'com.squareup.retrofit2:retrofit:2.2.0'
38 | implementation 'com.squareup.okhttp3:logging-interceptor:3.4.2'
39 |
40 | implementation 'io.reactivex:rxjava:1.2.3'
41 | implementation 'io.reactivex:rxandroid:1.2.1'
42 |
43 | implementation 'com.squareup.retrofit2:converter-gson:2.2.0'
44 | implementation 'com.squareup.retrofit2:adapter-rxjava:2.2.0'
45 |
46 | implementation project(':photoPicker')
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/pushcommunity/util/GlideRoundTransformUtil.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity.util;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapShader;
6 | import android.graphics.Canvas;
7 | import android.graphics.Paint;
8 |
9 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
10 | import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
11 |
12 | /**
13 | * description:glide转换圆角图片
14 | */
15 | public class GlideRoundTransformUtil extends BitmapTransformation {
16 | public GlideRoundTransformUtil(Context context) {
17 | super(context);
18 | }
19 |
20 | @Override
21 | protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
22 | return circleCrop(pool, toTransform);
23 | }
24 |
25 | private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
26 | if (source == null) return null;
27 |
28 | int size = Math.min(source.getWidth(), source.getHeight());
29 | int x = (source.getWidth() - size) / 2;
30 | int y = (source.getHeight() - size) / 2;
31 |
32 | // TODO this could be acquired from the pool too
33 | Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
34 |
35 | Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
36 | if (result == null) {
37 | result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
38 | }
39 |
40 | Canvas canvas = new Canvas(result);
41 | Paint paint = new Paint();
42 | paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
43 | paint.setAntiAlias(true);
44 | float r = size / 2f;
45 | canvas.drawCircle(r, r, r, paint);
46 | return result;
47 | }
48 |
49 | @Override
50 | public String getId() {
51 | return getClass().getName();
52 | }
53 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/pushcommunity/util/GlideCircleTransfromUtil.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity.util;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapShader;
6 | import android.graphics.Canvas;
7 | import android.graphics.Paint;
8 |
9 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
10 | import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
11 |
12 | /**
13 | * description:glide转圆形图片
14 | */
15 | public class GlideCircleTransfromUtil extends BitmapTransformation {
16 | public GlideCircleTransfromUtil(Context context) {
17 | super(context);
18 | }
19 |
20 | @Override
21 | protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
22 | return circleCrop(pool, toTransform);
23 | }
24 |
25 | private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
26 | if (source == null) return null;
27 |
28 | int size = Math.min(source.getWidth(), source.getHeight());
29 | int x = (source.getWidth() - size) / 2;
30 | int y = (source.getHeight() - size) / 2;
31 |
32 | // TODO this could be acquired from the pool too
33 | Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
34 |
35 | Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
36 | if (result == null) {
37 | result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
38 | }
39 |
40 | Canvas canvas = new Canvas(result);
41 | Paint paint = new Paint();
42 | paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
43 | paint.setAntiAlias(true);
44 | float r = size / 2f;
45 | canvas.drawCircle(r, r, r, paint);
46 | return result;
47 | }
48 |
49 | @Override
50 | public String getId() {
51 | return getClass().getName();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/pushcommunity/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity;
2 |
3 | import android.Manifest;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.View;
9 |
10 | import com.tbruyelle.rxpermissions.RxPermissions;
11 |
12 | import rx.functions.Action1;
13 |
14 | public class MainActivity extends AppCompatActivity {
15 |
16 | @Override
17 | protected void onCreate(@Nullable Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 | setContentView(R.layout.activity_main);
20 |
21 | findViewById(R.id.btn_go).setOnClickListener(new View.OnClickListener() {
22 | @Override
23 | public void onClick(View v) {
24 | //同时请求多个权限
25 | RxPermissions.getInstance(MainActivity.this)
26 | .request(Manifest.permission.CAMERA,
27 | Manifest.permission.READ_EXTERNAL_STORAGE,
28 | Manifest.permission.WRITE_EXTERNAL_STORAGE)//多个权限用","隔开
29 | .subscribe(new Action1() {
30 | @Override
31 | public void call(Boolean aBoolean) {
32 | if (aBoolean) {
33 | //当所有权限都允许之后,返回true
34 | Intent intent=new Intent(MainActivity.this,PushCommunityActivity.class);
35 | startActivity(intent);
36 | } else {
37 | //只要有一个权限禁止,返回false,
38 | //下一次申请只申请没通过申请的权限
39 | finish();
40 | }
41 | }
42 | });
43 | }
44 | });
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/photoPicker/src/main/res/layout/activity_img_sel.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
22 |
23 |
31 |
32 |
48 |
49 |
50 |
51 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/utils/StatusBarCompat.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.utils;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.graphics.Color;
7 | import android.os.Build;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 |
11 | public class StatusBarCompat {
12 | private static final int INVALID_VAL = -1;
13 | private static final int COLOR_DEFAULT = Color.parseColor("#20000000");
14 |
15 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
16 | public static void compat(Activity activity, int statusColor) {
17 |
18 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
19 | if (statusColor != INVALID_VAL) {
20 | activity.getWindow().setStatusBarColor(statusColor);
21 | }
22 | return;
23 | }
24 |
25 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
26 | int color = COLOR_DEFAULT;
27 | ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
28 | if (statusColor != INVALID_VAL) {
29 | color = statusColor;
30 | }
31 | View statusBarView = contentView.getChildAt(0);
32 | //改变颜色时避免重复添加statusBarView
33 | if (statusBarView != null && statusBarView.getMeasuredHeight() == getStatusBarHeight(activity)) {
34 | statusBarView.setBackgroundColor(color);
35 | return;
36 | }
37 | statusBarView = new View(activity);
38 | ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
39 | getStatusBarHeight(activity));
40 | statusBarView.setBackgroundColor(color);
41 | contentView.addView(statusBarView, lp);
42 | }
43 |
44 | }
45 |
46 | public static void compat(Activity activity) {
47 | compat(activity, INVALID_VAL);
48 | }
49 |
50 |
51 | public static int getStatusBarHeight(Context context) {
52 | int result = 0;
53 | int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
54 | if (resourceId > 0) {
55 | result = context.getResources().getDimensionPixelSize(resourceId);
56 | }
57 | return result;
58 | }
59 | }
--------------------------------------------------------------------------------
/photoPicker/src/main/res/layout/item_img_sel_folder.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
15 |
16 |
22 |
23 |
28 |
29 |
35 |
36 |
37 |
44 |
45 |
46 |
47 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
67 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/pushcommunity/bean/PageBean.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity.bean;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | /**
7 | * 分页信息 默认一页10条
8 | */
9 | public class PageBean implements Parcelable {
10 | private int page=0;
11 | private int rows=10;
12 | private int totalCount;
13 | private int totalPage;
14 | private boolean refresh=true;
15 |
16 |
17 | public int getLoadPage() {
18 | if(refresh){
19 | return page=1;
20 | }
21 | return ++page;
22 | }
23 |
24 | public int getPage() {
25 | return page;
26 | }
27 |
28 | public void setPage(int page) {
29 | this.page = page;
30 | }
31 |
32 | public int getRows() {
33 | return rows;
34 | }
35 |
36 | public void setRows(int rows) {
37 | this.rows = rows;
38 | }
39 |
40 | public int getTotalCount() {
41 | return totalCount;
42 | }
43 |
44 | public void setTotalCount(int totalCount) {
45 | this.totalCount = totalCount;
46 | }
47 |
48 | public int getTotalPage() {
49 | return totalPage;
50 | }
51 |
52 | public void setTotalPage(int totalPage) {
53 | this.totalPage = totalPage;
54 | }
55 |
56 | public boolean isRefresh() {
57 | return refresh;
58 | }
59 |
60 | public void setRefresh(boolean refresh) {
61 | this.refresh = refresh;
62 | }
63 |
64 | @Override
65 | public int describeContents() {
66 | return 0;
67 | }
68 |
69 | @Override
70 | public void writeToParcel(Parcel dest, int flags) {
71 | dest.writeInt(this.page);
72 | dest.writeInt(this.rows);
73 | dest.writeInt(this.totalCount);
74 | dest.writeInt(this.totalPage);
75 | dest.writeByte(refresh ? (byte) 1 : (byte) 0);
76 | }
77 |
78 | public PageBean() {
79 | }
80 |
81 | protected PageBean(Parcel in) {
82 | this.page = in.readInt();
83 | this.rows = in.readInt();
84 | this.totalCount = in.readInt();
85 | this.totalPage = in.readInt();
86 | this.refresh = in.readByte() != 0;
87 | }
88 |
89 | public static final Creator CREATOR = new Creator() {
90 | @Override
91 | public PageBean createFromParcel(Parcel source) {
92 | return new PageBean(source);
93 | }
94 |
95 | @Override
96 | public PageBean[] newArray(int size) {
97 | return new PageBean[size];
98 | }
99 | };
100 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_push.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
16 |
17 |
27 |
28 |
29 |
33 |
34 |
46 |
47 |
52 |
53 |
65 |
66 |
76 |
77 |
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/pushcommunity/adapter/BaseAblistViewAdapter.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import com.barnettwong.pushcommunity.bean.PageBean;
9 |
10 | import java.util.ArrayList;
11 | import java.util.List;
12 |
13 | /**
14 | * des:基础AblistView适配器
15 | */
16 | public class BaseAblistViewAdapter extends android.widget.BaseAdapter {
17 |
18 |
19 |
20 | protected Context mContext;
21 | protected LayoutInflater mInflater;
22 | protected List data = new ArrayList();
23 | protected PageBean pageBean;
24 | public BaseAblistViewAdapter(Context context){
25 | mContext = context;
26 | mInflater = LayoutInflater.from(mContext);
27 | pageBean=new PageBean();
28 | }
29 |
30 | /**
31 | * 设置数据源
32 | * @param d
33 | */
34 | public void setData(List d){
35 | data = d;
36 | }
37 |
38 | public void reset(List d) {
39 | if (d== null)return;
40 | data.clear();
41 | data.addAll(d);
42 | notifyDataSetChanged();
43 | }
44 |
45 | public List getData(){
46 | return data;
47 | }
48 |
49 | public void add(T d) {
50 | if (d == null) return;
51 | if (data == null) data = new ArrayList<>();
52 | data.add(d);
53 | notifyDataSetChanged();
54 | }
55 |
56 | public void addAllAt(int position,List d) {
57 | if (d == null) return;
58 | if (data == null) data = new ArrayList<>();
59 | data.addAll(position,d);
60 | notifyDataSetChanged();
61 | }
62 | public void addAt(int position,T d) {
63 | if (d == null) return;
64 | if (data == null) data = new ArrayList<>();
65 | data.add(position,d);
66 | notifyDataSetChanged();
67 | }
68 |
69 | public void addAll(List d) {
70 | if (d == null) return;
71 | if (data == null) data = new ArrayList<>();
72 | data.addAll(d);
73 | notifyDataSetChanged();
74 | }
75 |
76 | public void remove(int position) {
77 | if (data == null) return;
78 | data.remove(position);
79 | notifyDataSetChanged();
80 | }
81 |
82 |
83 | /**
84 | * 清空所有数据
85 | */
86 | public void clearAll(){
87 | data.clear();
88 | }
89 |
90 | @Override
91 | public int getCount() {
92 | return data.size();
93 | }
94 |
95 | @Override
96 | public T getItem(int position) {
97 | return data.get(position);
98 | }
99 |
100 | @Override
101 | public long getItemId(int position) {
102 | return 0;
103 | }
104 |
105 | @Override
106 | public View getView(int position, View convertView, ViewGroup parent) {
107 | return null;
108 | }
109 |
110 | /**
111 | * 分页
112 | * @return
113 | */
114 | public PageBean getPageBean() {
115 | return pageBean;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/adapter/FolderListAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.widget.ImageView;
6 |
7 | import com.yuyh.easyadapter.abslistview.EasyLVAdapter;
8 | import com.yuyh.easyadapter.abslistview.EasyLVHolder;
9 | import com.yuyh.library.imgsel.ImgSelConfig;
10 | import com.yuyh.library.imgsel.R;
11 | import com.yuyh.library.imgsel.bean.Folder;
12 | import com.yuyh.library.imgsel.common.OnFolderChangeListener;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * @author yuyh.
18 | * @date 2016/8/5.
19 | */
20 | public class FolderListAdapter extends EasyLVAdapter {
21 |
22 | private Context context;
23 | private List folderList;
24 | private ImgSelConfig config;
25 |
26 | private int selected = 0;
27 | private OnFolderChangeListener listener;
28 |
29 | public FolderListAdapter(Context context, List folderList, ImgSelConfig config) {
30 | super(context, folderList, R.layout.item_img_sel_folder);
31 | this.context = context;
32 | this.folderList = folderList;
33 | this.config = config;
34 | }
35 |
36 | @Override
37 | public void convert(EasyLVHolder holder, final int position, Folder folder) {
38 | if (position == 0) {
39 | holder.setText(R.id.tvFolderName, "所有图片")
40 | .setText(R.id.tvImageNum, "共" + getTotalImageSize() + "张");
41 | ImageView ivFolder = holder.getView(R.id.ivFolder);
42 | if (folderList.size() > 0) {
43 | config.loader.displayImage(context, folder.cover.path, ivFolder);
44 | }
45 | } else {
46 | holder.setText(R.id.tvFolderName, folder.name)
47 | .setText(R.id.tvImageNum, "共" + folder.images.size() + "张");
48 | ImageView ivFolder = holder.getView(R.id.ivFolder);
49 | if (folderList.size() > 0) {
50 | config.loader.displayImage(context, folder.cover.path, ivFolder);
51 | }
52 | }
53 |
54 | if (selected == position) {
55 | holder.setVisible(R.id.indicator, true);
56 | } else {
57 | holder.setVisible(R.id.indicator, false);
58 | }
59 |
60 | holder.getConvertView().setOnClickListener(new View.OnClickListener() {
61 | @Override
62 | public void onClick(View v) {
63 | setSelectIndex(position);
64 | }
65 | });
66 | }
67 |
68 | public void setData(List folders) {
69 | folderList.clear();
70 | if (folders != null && folders.size() > 0) {
71 | folderList.addAll(folders);
72 | }
73 | notifyDataSetChanged();
74 | }
75 |
76 | private int getTotalImageSize() {
77 | int result = 0;
78 | if (folderList != null && folderList.size() > 0) {
79 | for (Folder folder : folderList) {
80 | result += folder.images.size();
81 | }
82 | }
83 | return result;
84 | }
85 |
86 | public void setSelectIndex(int position) {
87 | if (selected == position)
88 | return;
89 | if(listener != null)
90 | listener.onChange(position, folderList.get(position));
91 | selected = position;
92 | notifyDataSetChanged();
93 | }
94 |
95 | public int getSelectIndex() {
96 | return selected;
97 | }
98 |
99 | public void setOnFloderChangeListener(OnFolderChangeListener listener) {
100 | this.listener = listener;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/pushcommunity/util/ImageLoaderUtils.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity.util;
2 |
3 | import android.content.Context;
4 | import android.widget.ImageView;
5 |
6 | import com.barnettwong.pushcommunity.R;
7 | import com.bumptech.glide.Glide;
8 | import com.bumptech.glide.load.DecodeFormat;
9 | import com.bumptech.glide.load.engine.DiskCacheStrategy;
10 |
11 | import java.io.File;
12 |
13 | /**
14 | * Description : 图片加载工具类 使用glide框架封装
15 | */
16 | public class ImageLoaderUtils {
17 |
18 | public static void display(Context context, ImageView imageView, String url, int placeholder, int error) {
19 | if (imageView == null) {
20 | throw new IllegalArgumentException("argument error");
21 | }
22 | Glide.with(context).load(url).placeholder(placeholder)
23 | .error(error).crossFade().into(imageView);
24 | }
25 |
26 | public static void display(Context context, ImageView imageView, String url) {
27 | if (imageView == null) {
28 | throw new IllegalArgumentException("argument error");
29 | }
30 | Glide.with(context).load(url)
31 | .diskCacheStrategy(DiskCacheStrategy.ALL)
32 | .centerCrop()
33 | .placeholder(R.drawable.ic_image_loading)
34 | .error(R.drawable.ic_empty_picture)
35 | .crossFade().into(imageView);
36 | }
37 |
38 | public static void display(Context context, ImageView imageView, File url) {
39 | if (imageView == null) {
40 | throw new IllegalArgumentException("argument error");
41 | }
42 | Glide.with(context).load(url)
43 | .diskCacheStrategy(DiskCacheStrategy.ALL)
44 | .centerCrop()
45 | .placeholder(R.drawable.ic_image_loading)
46 | .error(R.drawable.ic_empty_picture)
47 | .crossFade().into(imageView);
48 | }
49 | public static void displaySmallPhoto(Context context, ImageView imageView, String url) {
50 | if (imageView == null) {
51 | throw new IllegalArgumentException("argument error");
52 | }
53 | Glide.with(context).load(url).asBitmap()
54 | .diskCacheStrategy(DiskCacheStrategy.ALL)
55 | .placeholder(R.drawable.ic_image_loading)
56 | .error(R.drawable.ic_empty_picture)
57 | .thumbnail(0.5f)
58 | .into(imageView);
59 | }
60 | public static void displayBigPhoto(Context context, ImageView imageView, String url) {
61 | if (imageView == null) {
62 | throw new IllegalArgumentException("argument error");
63 | }
64 | Glide.with(context).load(url).asBitmap()
65 | .format(DecodeFormat.PREFER_ARGB_8888)
66 | .diskCacheStrategy(DiskCacheStrategy.ALL)
67 | .placeholder(R.drawable.ic_image_loading)
68 | .error(R.drawable.ic_empty_picture)
69 | .into(imageView);
70 | }
71 | public static void display(Context context, ImageView imageView, int url) {
72 | if (imageView == null) {
73 | throw new IllegalArgumentException("argument error");
74 | }
75 | Glide.with(context).load(url)
76 | .diskCacheStrategy(DiskCacheStrategy.ALL)
77 | .centerCrop()
78 | .placeholder(R.drawable.ic_image_loading)
79 | .error(R.drawable.ic_empty_picture)
80 | .crossFade().into(imageView);
81 | }
82 | public static void displayRound(Context context, ImageView imageView, String url) {
83 | if (imageView == null) {
84 | throw new IllegalArgumentException("argument error");
85 | }
86 | Glide.with(context).load(url)
87 | .diskCacheStrategy(DiskCacheStrategy.ALL)
88 | .error(R.drawable.toux2)
89 | .centerCrop().transform(new GlideRoundTransformUtil(context)).into(imageView);
90 | }
91 | public static void displayRound(Context context, ImageView imageView, int resId) {
92 | if (imageView == null) {
93 | throw new IllegalArgumentException("argument error");
94 | }
95 | Glide.with(context).load(resId)
96 | .diskCacheStrategy(DiskCacheStrategy.ALL)
97 | .error(R.drawable.toux2)
98 | .centerCrop().transform(new GlideRoundTransformUtil(context)).into(imageView);
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/adapter/ImageListAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.adapter;
2 |
3 | import android.content.Context;
4 | import android.os.Build;
5 | import android.view.View;
6 | import android.view.ViewTreeObserver;
7 | import android.widget.FrameLayout;
8 | import android.widget.ImageView;
9 | import android.widget.RelativeLayout;
10 |
11 | import com.yuyh.easyadapter.recyclerview.EasyRVAdapter;
12 | import com.yuyh.easyadapter.recyclerview.EasyRVHolder;
13 | import com.yuyh.library.imgsel.ImgSelConfig;
14 | import com.yuyh.library.imgsel.R;
15 | import com.yuyh.library.imgsel.bean.Image;
16 | import com.yuyh.library.imgsel.common.OnItemClickListener;
17 |
18 | import java.util.ArrayList;
19 | import java.util.List;
20 |
21 | /**
22 | * @author yuyh.
23 | * @date 2016/8/5.
24 | */
25 | public class ImageListAdapter extends EasyRVAdapter {
26 |
27 | private boolean showCamera;
28 | private boolean mutiSelect;
29 |
30 | private ImgSelConfig config;
31 | private Context context;
32 |
33 | private List selectedImageList = new ArrayList<>();
34 | private OnItemClickListener listener;
35 |
36 | public ImageListAdapter(Context context, List list, ImgSelConfig config) {
37 | super(context, list, R.layout.item_img_sel, R.layout.item_img_sel_take_photo);
38 | this.context = context;
39 | this.config = config;
40 | }
41 |
42 | @Override
43 | protected void onBindData(EasyRVHolder viewHolder, final int position, final Image item) {
44 |
45 | viewHolder.getItemView().setOnClickListener(new View.OnClickListener() {
46 | @Override
47 | public void onClick(View v) {
48 | if (listener != null)
49 | listener.onClick(position, item);
50 | }
51 | });
52 |
53 | if (position == 0 && showCamera) {
54 | ImageView iv = viewHolder.getView(R.id.ivTakePhoto);
55 | iv.setImageResource(R.drawable.ic_take_photo);
56 | return;
57 | }
58 |
59 | final ImageView iv = viewHolder.getView(R.id.ivImage);
60 | final FrameLayout frameLayout=viewHolder.getView(R.id.pi_picture_choose_item_select);
61 | config.loader.displayImage(context, item.path, iv);
62 |
63 | iv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
64 | @Override
65 | public void onGlobalLayout() {
66 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
67 | iv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
68 | } else {
69 | iv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
70 | }
71 |
72 | RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) iv.getLayoutParams();
73 | params.height = params.width;
74 | iv.setLayoutParams(params);
75 | iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
76 | }
77 | });
78 |
79 | if (mutiSelect) {
80 | viewHolder.setVisible(R.id.ivPhotoCheaked, true);
81 | if (selectedImageList.contains(item)) {
82 | viewHolder.setImageResource(R.id.ivPhotoCheaked, R.drawable.ic_checked);
83 | viewHolder.setVisible(R.id.pi_picture_choose_item_select,View.VISIBLE);
84 | } else {
85 | viewHolder.setImageResource(R.id.ivPhotoCheaked, R.drawable.ic_uncheck);
86 | viewHolder.setVisible(R.id.pi_picture_choose_item_select,View.GONE);
87 | }
88 | } else {
89 | viewHolder.setVisible(R.id.ivPhotoCheaked, false);
90 | }
91 | }
92 |
93 | public void setShowCamera(boolean showCamera) {
94 | this.showCamera = showCamera;
95 | }
96 |
97 | public void setMutiSelect(boolean mutiSelect) {
98 | this.mutiSelect = mutiSelect;
99 | }
100 |
101 | @Override
102 | public int getItemViewType(int position) {
103 | if (position == 0 && showCamera) {
104 | return 1;
105 | }
106 | return 0;
107 | }
108 |
109 | public void setOnItemClickListener(OnItemClickListener listener) {
110 | this.listener = listener;
111 | }
112 |
113 |
114 | public void select(Image image,int position) {
115 | if (selectedImageList.contains(image)) {
116 | selectedImageList.remove(image);
117 | } else {
118 | selectedImageList.add(image);
119 | }
120 | notifyItemChanged(position);
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/pushcommunity/PushCommunityActivity.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.graphics.Color;
6 | import android.os.Bundle;
7 | import android.support.v4.content.ContextCompat;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.text.TextUtils;
10 | import android.view.View;
11 | import android.widget.EditText;
12 | import android.widget.ImageView;
13 | import android.widget.TextView;
14 |
15 | import com.barnettwong.pushcommunity.adapter.NinePicturesAdapter;
16 | import com.barnettwong.pushcommunity.util.ImageLoaderUtils;
17 | import com.barnettwong.pushcommunity.view.NoScrollGridView;
18 | import com.blankj.utilcode.util.ToastUtils;
19 | import com.yuyh.library.imgsel.ImageLoader;
20 | import com.yuyh.library.imgsel.ImgSelActivity;
21 | import com.yuyh.library.imgsel.ImgSelConfig;
22 |
23 | import java.util.List;
24 |
25 | public class PushCommunityActivity extends AppCompatActivity {
26 | private EditText etContent;
27 | private NoScrollGridView gridview;
28 | private TextView tvPublish;
29 |
30 | private NinePicturesAdapter ninePicturesAdapter;
31 | private int REQUEST_CODE = 120;
32 |
33 | @Override
34 | protected void onCreate(Bundle savedInstanceState) {
35 | super.onCreate(savedInstanceState);
36 | setContentView(R.layout.activity_push);
37 |
38 | initView();
39 | }
40 |
41 | private void initView() {
42 | etContent=findViewById(R.id.et_content);
43 | gridview=findViewById(R.id.gridview);
44 | tvPublish=findViewById(R.id.tv_publish);
45 |
46 | ninePicturesAdapter = new NinePicturesAdapter(this, 9, new NinePicturesAdapter.OnClickAddListener() {
47 | @Override
48 | public void onClickAdd(int positin) {
49 | choosePhoto();
50 | }
51 | });
52 | gridview.setAdapter(ninePicturesAdapter);
53 |
54 | tvPublish.setOnClickListener(new View.OnClickListener() {
55 | @Override
56 | public void onClick(View v) {
57 | if (!TextUtils.isEmpty(etContent.getText().toString())) {
58 | //将发表内容提交后台
59 | ToastUtils.showShort("发表成功");
60 | finish();
61 | } else {
62 | ToastUtils.showShort("发表内容不能为空!");
63 | }
64 | }
65 | });
66 | }
67 |
68 | /**
69 | * 开启图片选择器
70 | */
71 | private void choosePhoto() {
72 | ImgSelConfig config = new ImgSelConfig.Builder(loader)
73 | // 是否多选
74 | .multiSelect(true)
75 | // 确定按钮背景色
76 | .btnBgColor(Color.TRANSPARENT)
77 | .titleBgColor(ContextCompat.getColor(this, R.color.main_color))
78 | // 使用沉浸式状态栏
79 | .statusBarColor(ContextCompat.getColor(this, R.color.main_color))
80 | // 返回图标ResId
81 | .backResId(R.drawable.ic_arrow_back)
82 | .title("图片")
83 | // 第一个是否显示相机
84 | .needCamera(true)
85 | // 最大选择图片数量
86 | .maxNum(9 - ninePicturesAdapter.getPhotoCount())
87 | .build();
88 | ImgSelActivity.startActivity(this, config, REQUEST_CODE);
89 | }
90 |
91 | private ImageLoader loader = new ImageLoader() {
92 | @Override
93 | public void displayImage(Context context, String path, ImageView imageView) {
94 | ImageLoaderUtils.display(context, imageView, path);
95 | }
96 | };
97 |
98 | @Override
99 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
100 | super.onActivityResult(requestCode, resultCode, data);
101 | if (requestCode == REQUEST_CODE && resultCode == RESULT_OK && data != null) {
102 | List pathList = data.getStringArrayListExtra(ImgSelActivity.INTENT_RESULT);
103 | if (ninePicturesAdapter != null) {
104 | ninePicturesAdapter.addAll(pathList);
105 | }
106 | }
107 | }
108 |
109 | /**
110 | * 获取到拼接好的图片
111 | *
112 | * @return
113 | */
114 | private String getPictureString() {
115 | //拼接图片链接
116 | List strings = ninePicturesAdapter.getData();
117 | if (strings != null && strings.size() > 0) {
118 | StringBuilder allUrl = new StringBuilder();
119 | for (int i = 0; i < strings.size(); i++) {
120 | if (!TextUtils.isEmpty(strings.get(i))) {
121 | allUrl.append(strings.get(i) + ";");
122 | }
123 | }
124 | if (!TextUtils.isEmpty(allUrl)) {
125 | String url = allUrl.toString();
126 | url = url.substring(0, url.lastIndexOf(";"));
127 | return url;
128 | } else {
129 | return "";
130 | }
131 | } else {
132 | return "";
133 | }
134 | }
135 |
136 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/pushcommunity/adapter/NinePicturesAdapter.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity.adapter;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.text.TextUtils;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.ImageView;
10 |
11 | import com.barnettwong.pushcommunity.BigImagePagerActivity;
12 | import com.barnettwong.pushcommunity.R;
13 | import com.barnettwong.pushcommunity.util.ImageLoaderUtils;
14 | import com.barnettwong.pushcommunity.util.ViewHolderUtil;
15 |
16 | import java.util.List;
17 |
18 | /**
19 | * des:9宫图适配器
20 | */
21 | public class NinePicturesAdapter extends BaseAblistViewAdapter {
22 | private boolean showAdd = true;
23 | private int picturnNum = 0;
24 | private boolean isDelete = false;//当前是否显示删除按钮
25 | private OnClickAddListener onClickAddListener;
26 | private boolean isAdd=true;//当前是否显示添加按钮
27 |
28 |
29 | public NinePicturesAdapter(Context context, int picturnNum, OnClickAddListener onClickAddListener) {
30 | super(context);
31 | this.picturnNum = picturnNum;
32 | this.onClickAddListener = onClickAddListener;
33 | showAdd();
34 | }
35 |
36 | @Override
37 | public View getView(final int position, View convertView, ViewGroup parent) {
38 | if (convertView == null) {
39 | convertView = LayoutInflater.from(mContext).inflate(R.layout.item_grid_photo, parent, false);
40 | }
41 | final ImageView imageView = ViewHolderUtil.get(convertView, R.id.img_photo);
42 | ImageView imgDelete = ViewHolderUtil.get(convertView, R.id.img_delete);
43 | final String url = getData().get(position);
44 | //显示图片
45 | if (TextUtils.isEmpty(url) && showAdd) {
46 | ImageLoaderUtils.display(mContext, imageView, R.drawable.addphoto);
47 | imgDelete.setVisibility(View.GONE);
48 | } else {
49 | imgDelete.setVisibility(View.VISIBLE);
50 | ImageLoaderUtils.display(mContext, imageView, url);
51 | }
52 |
53 | autoHideShowAdd();
54 |
55 | imageView.setOnClickListener(new View.OnClickListener() {
56 | @Override
57 | public void onClick(View view) {
58 | //再次选择图片
59 | if (TextUtils.isEmpty(url)) {
60 | if (onClickAddListener != null) {
61 | onClickAddListener.onClickAdd(position);
62 | }
63 | } else {
64 | //放大查看图片
65 | BigImagePagerActivity.startImagePagerActivity((Activity) mContext, getData(), position);
66 | }
67 | }
68 | });
69 | //删除按钮
70 | imgDelete.setOnClickListener(new View.OnClickListener() {
71 | @Override
72 | public void onClick(View view) {
73 | remove(position);
74 | if (!isDelete && getCount() < 1) {
75 | add("");
76 | isDelete = true;
77 | }
78 | notifyDataSetChanged();
79 | }
80 | });
81 | return convertView;
82 | }
83 |
84 | @Override
85 | public void setData(List d) {
86 | boolean hasAdd=false;
87 | for (int i = 0; i < d.size(); i++) {
88 | if(TextUtils.isEmpty(d.get(i))){
89 | hasAdd=true;
90 | break;
91 | }
92 | }
93 | super.setData(d);
94 | if(!hasAdd){
95 | showAdd();
96 | }
97 | }
98 |
99 | @Override
100 | public void addAll(List d) {
101 | if(isAdd){
102 | HideAdd();
103 | }
104 | super.addAll(d);
105 | showAdd();
106 | }
107 |
108 | /**
109 | * 移除add按钮
110 | */
111 | public void autoHideShowAdd(){
112 | int lastPosition=getData().size()-1;
113 | if(lastPosition==picturnNum&&getData().get(lastPosition)!=null&& TextUtils.isEmpty(getData().get(lastPosition))){
114 | getData().remove(lastPosition);
115 | isAdd=false;
116 | notifyDataSetChanged();
117 | }else if(!isAdd){
118 | showAdd();
119 | }
120 | }
121 | /**
122 | * 移除add按钮
123 | */
124 | public void HideAdd(){
125 | int lastPosition=getData().size()-1;
126 | if(getData().get(lastPosition)!=null&& TextUtils.isEmpty(getData().get(lastPosition))){
127 | getData().remove(lastPosition);
128 | isAdd=false;
129 | notifyDataSetChanged();
130 | }
131 | }
132 | /**
133 | * 显示add按钮
134 | */
135 | public void showAdd(){
136 | if(getData().size() \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/ImgSelConfig.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel;
2 |
3 | import android.graphics.Color;
4 | import android.os.Environment;
5 |
6 | import com.yuyh.library.imgsel.utils.FileUtils;
7 |
8 | import java.io.Serializable;
9 |
10 | /**
11 | * @author yuyh.
12 | * @date 2016/8/5.
13 | */
14 | public class ImgSelConfig {
15 |
16 | /**
17 | * 是否需要裁剪
18 | */
19 | public boolean needCrop;
20 |
21 | /**
22 | * 是否多选
23 | */
24 | public boolean multiSelect;
25 |
26 | /**
27 | * 最多选择图片数
28 | */
29 | public int maxNum = 9;
30 |
31 | /**
32 | * 第一个item是否显示相机
33 | */
34 | public boolean needCamera;
35 |
36 | public int statusBarColor = -1;
37 |
38 | /**
39 | * 返回图标资源
40 | */
41 | public int backResId = -1;
42 |
43 | /**
44 | * 标题
45 | */
46 | public String title;
47 |
48 | /**
49 | * 标题颜色
50 | */
51 | public int titleColor;
52 |
53 | /**
54 | * titlebar背景色
55 | */
56 | public int titleBgColor;
57 |
58 | /**
59 | * 确定按钮文字颜色
60 | */
61 | public int btnTextColor;
62 |
63 | /**
64 | * 确定按钮背景色
65 | */
66 | public int btnBgColor;
67 |
68 | /**
69 | * 拍照存储路径
70 | */
71 | public String filePath;
72 |
73 | /**
74 | * 自定义图片加载器
75 | */
76 | public ImageLoader loader;
77 |
78 | /**
79 | * 裁剪输出大小
80 | */
81 | public int aspectX = 1;
82 | public int aspectY = 1;
83 | public int outputX = 500;
84 | public int outputY = 500;
85 |
86 | public ImgSelConfig(Builder builder) {
87 | this.needCrop = builder.needCrop;
88 | this.multiSelect = builder.multiSelect;
89 | this.maxNum = builder.maxNum;
90 | this.needCamera = builder.needCamera;
91 | this.statusBarColor = builder.statusBarColor;
92 | this.backResId = builder.backResId;
93 | this.title = builder.title;
94 | this.titleBgColor = builder.titleBgColor;
95 | this.titleColor = builder.titleColor;
96 | this.btnBgColor = builder.btnBgColor;
97 | this.btnTextColor = builder.btnTextColor;
98 | this.filePath = builder.filePath;
99 | this.loader = builder.loader;
100 | this.aspectX = builder.aspectX;
101 | this.aspectY = builder.aspectY;
102 | this.outputX = builder.outputX;
103 | this.outputY = builder.outputY;
104 | }
105 |
106 | public static class Builder implements Serializable {
107 |
108 | private boolean needCrop = false;
109 | private boolean multiSelect = true;
110 | private int maxNum = 9;
111 | private boolean needCamera = true;
112 | public int statusBarColor = -1;
113 | private int backResId = -1;
114 | private String title = "图片";
115 | private int titleColor;
116 | private int titleBgColor;
117 | private int btnTextColor;
118 | private int btnBgColor;
119 | private String filePath;
120 | private ImageLoader loader;
121 |
122 | private int aspectX = 1;
123 | private int aspectY = 1;
124 | private int outputX = 400;
125 | private int outputY = 400;
126 |
127 | public Builder(ImageLoader loader) {
128 | this.loader = loader;
129 |
130 | if (FileUtils.isSdCardAvailable())
131 | filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Camera";
132 | else
133 | filePath = Environment.getRootDirectory().getAbsolutePath() + "/Camera";
134 |
135 | titleBgColor = Color.BLACK;
136 | titleColor = Color.WHITE;
137 |
138 | btnBgColor = Color.TRANSPARENT;
139 | btnTextColor = Color.WHITE;
140 |
141 | FileUtils.createDir(filePath);
142 | }
143 |
144 | public Builder needCrop(boolean needCrop) {
145 | this.needCrop = needCrop;
146 | return this;
147 | }
148 |
149 | public Builder multiSelect(boolean multiSelect) {
150 | this.multiSelect = multiSelect;
151 | return this;
152 | }
153 |
154 | public Builder maxNum(int maxNum) {
155 | this.maxNum = maxNum;
156 | return this;
157 | }
158 |
159 | public Builder needCamera(boolean needCamera) {
160 | this.needCamera = needCamera;
161 | return this;
162 | }
163 |
164 | public Builder statusBarColor(int statusBarColor){
165 | this.statusBarColor = statusBarColor;
166 | return this;
167 | }
168 |
169 | public Builder backResId(int backResId){
170 | this.backResId = backResId;
171 | return this;
172 | }
173 |
174 | public Builder title(String title) {
175 | this.title = title;
176 | return this;
177 | }
178 |
179 | public Builder titleColor(int titleColor) {
180 | this.titleColor = titleColor;
181 | return this;
182 | }
183 |
184 | public Builder titleBgColor(int titleBgColor) {
185 | this.titleBgColor = titleBgColor;
186 | return this;
187 | }
188 |
189 | public Builder btnTextColor(int btnTextColor) {
190 | this.btnTextColor = btnTextColor;
191 | return this;
192 | }
193 |
194 | public Builder btnBgColor(int btnBgColor) {
195 | this.btnBgColor = btnBgColor;
196 | return this;
197 | }
198 |
199 | private Builder filePath(String filePath) {
200 | this.filePath = filePath;
201 | return this;
202 | }
203 |
204 | public Builder cropSize(int aspectX, int aspectY, int outputX, int outputY) {
205 | this.aspectX = aspectX;
206 | this.aspectY = aspectY;
207 | this.outputX = outputX;
208 | this.outputY = outputY;
209 | return this;
210 | }
211 |
212 | public ImgSelConfig build() {
213 | return new ImgSelConfig(this);
214 | }
215 | }
216 | }
217 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/utils/LogUtils.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.utils;
2 |
3 | import android.content.Context;
4 | import android.util.Log;
5 |
6 | import java.io.BufferedWriter;
7 | import java.io.File;
8 | import java.io.FileWriter;
9 | import java.io.IOException;
10 | import java.text.SimpleDateFormat;
11 | import java.util.Calendar;
12 | import java.util.Date;
13 |
14 | /**
15 | * Log工具类,可控制Log输出开关、保存Log到文件、过滤输出等级
16 | *
17 | * @author yuyh.
18 | * @date 16/4/9.
19 | */
20 | public class LogUtils {
21 | private static Boolean LOG_SWITCH = true; // 日志文件总开关
22 | private static Boolean LOG_TO_FILE = false; // 日志写入文件开关
23 | private static String LOG_TAG = "TAG"; // 默认的tag
24 | private static char LOG_TYPE = 'v';// 输入日志类型,v代表输出所有信息,w则只输出警告...
25 | private static int LOG_SAVE_DAYS = 7;// sd卡中日志文件的最多保存天数
26 |
27 | private final static SimpleDateFormat LOG_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 日志的输出格式
28 | private final static SimpleDateFormat FILE_SUFFIX = new SimpleDateFormat("yyyy-MM-dd");// 日志文件格式
29 | private static String LOG_FILE_PATH; // 日志文件保存路径
30 | private static String LOG_FILE_NAME;// 日志文件保存名称
31 |
32 | public static void init(Context context) { // 在Application中初始化
33 | LOG_FILE_PATH = FileUtils.createRootPath(context);
34 | LOG_FILE_NAME = "Log";
35 | }
36 |
37 | /**************************** Warn *********************************/
38 | public static void w(Object msg) {
39 | w(LOG_TAG, msg);
40 | }
41 |
42 | public static void w(String tag, Object msg) {
43 | w(tag, msg, null);
44 | }
45 |
46 | public static void w(String tag, Object msg, Throwable tr) {
47 | log(tag, msg.toString(), tr, 'w');
48 | }
49 |
50 | /*************************** Error ********************************/
51 | public static void e(Object msg) {
52 | e(LOG_TAG, msg);
53 | }
54 |
55 | public static void e(String tag, Object msg) {
56 | e(tag, msg, null);
57 | }
58 |
59 | public static void e(String tag, Object msg, Throwable tr) {
60 | log(tag, msg.toString(), tr, 'e');
61 | }
62 |
63 | /*************************** Debug ********************************/
64 | public static void d(Object msg) {
65 | d(LOG_TAG, msg);
66 | }
67 |
68 | public static void d(String tag, Object msg) {// 调试信息
69 | d(tag, msg, null);
70 | }
71 |
72 | public static void d(String tag, Object msg, Throwable tr) {
73 | log(tag, msg.toString(), tr, 'd');
74 | }
75 |
76 | /**************************** Info *********************************/
77 | public static void i(Object msg) {
78 | i(LOG_TAG, msg);
79 | }
80 |
81 | public static void i(String tag, Object msg) {
82 | i(tag, msg, null);
83 | }
84 |
85 | public static void i(String tag, Object msg, Throwable tr) {
86 | log(tag, msg.toString(), tr, 'i');
87 | }
88 |
89 | /************************** Verbose ********************************/
90 | public static void v(Object msg) {
91 | v(LOG_TAG, msg);
92 | }
93 |
94 | public static void v(String tag, Object msg) {
95 | v(tag, msg, null);
96 | }
97 |
98 | public static void v(String tag, Object msg, Throwable tr) {
99 | log(tag, msg.toString(), tr, 'v');
100 | }
101 |
102 | /**
103 | * 根据tag, msg和等级,输出日志
104 | *
105 | * @param tag
106 | * @param msg
107 | * @param level
108 | */
109 | private static void log(String tag, String msg, Throwable tr, char level) {
110 | if (LOG_SWITCH) {
111 | if ('e' == level && ('e' == LOG_TYPE || 'v' == LOG_TYPE)) { // 输出错误信息
112 | Log.e(tag, msg, tr);
113 | } else if ('w' == level && ('w' == LOG_TYPE || 'v' == LOG_TYPE)) {
114 | Log.w(tag, msg, tr);
115 | } else if ('d' == level && ('d' == LOG_TYPE || 'v' == LOG_TYPE)) {
116 | Log.d(tag, msg, tr);
117 | } else if ('i' == level && ('d' == LOG_TYPE || 'v' == LOG_TYPE)) {
118 | Log.i(tag, msg, tr);
119 | } else {
120 | Log.v(tag, msg, tr);
121 | }
122 | if (LOG_TO_FILE)
123 | log2File(String.valueOf(level), tag, msg + tr == null ? "" : "\n" + Log.getStackTraceString(tr));
124 | }
125 | }
126 |
127 | /**
128 | * 打开日志文件并写入日志
129 | *
130 | * @return
131 | **/
132 | private synchronized static void log2File(String mylogtype, String tag, String text) {
133 | Date nowtime = new Date();
134 | String date = FILE_SUFFIX.format(nowtime);
135 | String dateLogContent = LOG_FORMAT.format(nowtime) + ":" + mylogtype + ":" + tag + ":" + text; // 日志输出格式
136 | File destDir = new File(LOG_FILE_PATH);
137 | if (!destDir.exists()) {
138 | destDir.mkdirs();
139 | }
140 | File file = new File(LOG_FILE_PATH, LOG_FILE_NAME + date);
141 | try {
142 | FileWriter filerWriter = new FileWriter(file, true);
143 | BufferedWriter bufWriter = new BufferedWriter(filerWriter);
144 | bufWriter.write(dateLogContent);
145 | bufWriter.newLine();
146 | bufWriter.close();
147 | filerWriter.close();
148 | } catch (IOException e) {
149 | e.printStackTrace();
150 | }
151 | }
152 |
153 | /**
154 | * 删除指定的日志文件
155 | */
156 | public static void delFile() {// 删除日志文件
157 | String needDelFiel = FILE_SUFFIX.format(getDateBefore());
158 | File file = new File(LOG_FILE_PATH, needDelFiel + LOG_FILE_NAME);
159 | if (file.exists()) {
160 | file.delete();
161 | }
162 | }
163 |
164 | /**
165 | * 得到LOG_SAVE_DAYS天前的日期
166 | *
167 | * @return
168 | */
169 | private static Date getDateBefore() {
170 | Date nowtime = new Date();
171 | Calendar now = Calendar.getInstance();
172 | now.setTime(nowtime);
173 | now.set(Calendar.DATE, now.get(Calendar.DATE) - LOG_SAVE_DAYS);
174 | return now.getTime();
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/widget/DividerGridItemDecoration.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.widget;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Rect;
7 | import android.graphics.drawable.Drawable;
8 | import android.support.v7.widget.GridLayoutManager;
9 | import android.support.v7.widget.RecyclerView;
10 | import android.support.v7.widget.RecyclerView.LayoutManager;
11 | import android.support.v7.widget.RecyclerView.State;
12 | import android.support.v7.widget.StaggeredGridLayoutManager;
13 | import android.view.View;
14 |
15 | public class DividerGridItemDecoration extends RecyclerView.ItemDecoration
16 | {
17 |
18 | private static final int[] ATTRS = new int[] { android.R.attr.listDivider };
19 | private Drawable mDivider;
20 |
21 | public DividerGridItemDecoration(Context context)
22 | {
23 | final TypedArray a = context.obtainStyledAttributes(ATTRS);
24 | mDivider = a.getDrawable(0);
25 | a.recycle();
26 | }
27 |
28 | @Override
29 | public void onDraw(Canvas c, RecyclerView parent, State state)
30 | {
31 |
32 | drawHorizontal(c, parent);
33 | drawVertical(c, parent);
34 |
35 | }
36 |
37 | private int getSpanCount(RecyclerView parent)
38 | {
39 | // 列数
40 | int spanCount = -1;
41 | LayoutManager layoutManager = parent.getLayoutManager();
42 | if (layoutManager instanceof GridLayoutManager)
43 | {
44 |
45 | spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
46 | } else if (layoutManager instanceof StaggeredGridLayoutManager)
47 | {
48 | spanCount = ((StaggeredGridLayoutManager) layoutManager)
49 | .getSpanCount();
50 | }
51 | return spanCount;
52 | }
53 |
54 | public void drawHorizontal(Canvas c, RecyclerView parent)
55 | {
56 | int childCount = parent.getChildCount();
57 | for (int i = 0; i < childCount; i++)
58 | {
59 | final View child = parent.getChildAt(i);
60 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
61 | .getLayoutParams();
62 | final int left = child.getLeft() - params.leftMargin;
63 | final int right = child.getRight() + params.rightMargin
64 | + mDivider.getIntrinsicWidth();
65 | final int top = child.getBottom() + params.bottomMargin;
66 | final int bottom = top + mDivider.getIntrinsicHeight();
67 | mDivider.setBounds(left, top, right, bottom);
68 | mDivider.draw(c);
69 | }
70 | }
71 |
72 | public void drawVertical(Canvas c, RecyclerView parent)
73 | {
74 | final int childCount = parent.getChildCount();
75 | for (int i = 0; i < childCount; i++)
76 | {
77 | final View child = parent.getChildAt(i);
78 |
79 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
80 | .getLayoutParams();
81 | final int top = child.getTop() - params.topMargin;
82 | final int bottom = child.getBottom() + params.bottomMargin;
83 | final int left = child.getRight() + params.rightMargin;
84 | final int right = left + mDivider.getIntrinsicWidth();
85 |
86 | mDivider.setBounds(left, top, right, bottom);
87 | mDivider.draw(c);
88 | }
89 | }
90 |
91 | private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
92 | int childCount)
93 | {
94 | LayoutManager layoutManager = parent.getLayoutManager();
95 | if (layoutManager instanceof GridLayoutManager)
96 | {
97 | if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
98 | {
99 | return true;
100 | }
101 | } else if (layoutManager instanceof StaggeredGridLayoutManager)
102 | {
103 | int orientation = ((StaggeredGridLayoutManager) layoutManager)
104 | .getOrientation();
105 | if (orientation == StaggeredGridLayoutManager.VERTICAL)
106 | {
107 | if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
108 | {
109 | return true;
110 | }
111 | } else
112 | {
113 | childCount = childCount - childCount % spanCount;
114 | if (pos >= childCount)// 如果是最后一列,则不需要绘制右边
115 | return true;
116 | }
117 | }
118 | return false;
119 | }
120 |
121 | private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,
122 | int childCount)
123 | {
124 | LayoutManager layoutManager = parent.getLayoutManager();
125 | if (layoutManager instanceof GridLayoutManager)
126 | {
127 | childCount = childCount - childCount % spanCount;
128 | if (pos >= childCount)// 如果是最后一行,则不需要绘制底部
129 | return true;
130 | } else if (layoutManager instanceof StaggeredGridLayoutManager)
131 | {
132 | int orientation = ((StaggeredGridLayoutManager) layoutManager)
133 | .getOrientation();
134 | // StaggeredGridLayoutManager 且纵向滚动
135 | if (orientation == StaggeredGridLayoutManager.VERTICAL)
136 | {
137 | childCount = childCount - childCount % spanCount;
138 | // 如果是最后一行,则不需要绘制底部
139 | if (pos >= childCount)
140 | return true;
141 | } else
142 | // StaggeredGridLayoutManager 且横向滚动
143 | {
144 | // 如果是最后一行,则不需要绘制底部
145 | if ((pos + 1) % spanCount == 0)
146 | {
147 | return true;
148 | }
149 | }
150 | }
151 | return false;
152 | }
153 |
154 | @Override
155 | public void getItemOffsets(Rect outRect, int itemPosition,
156 | RecyclerView parent)
157 | {
158 | int spanCount = getSpanCount(parent);
159 | int childCount = parent.getAdapter().getItemCount();
160 | if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部
161 | {
162 | outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
163 | } else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边
164 | {
165 | outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
166 | } else
167 | {
168 | outRect.set(0, 0, mDivider.getIntrinsicWidth(),
169 | mDivider.getIntrinsicHeight());
170 | }
171 | }
172 | }
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/ImgSelActivity.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel;
2 |
3 | import android.Manifest;
4 | import android.app.Activity;
5 | import android.content.Intent;
6 | import android.content.pm.PackageManager;
7 | import android.net.Uri;
8 | import android.os.Build;
9 | import android.os.Bundle;
10 | import android.provider.MediaStore;
11 | import android.support.annotation.NonNull;
12 | import android.support.v4.app.ActivityCompat;
13 | import android.support.v4.app.Fragment;
14 | import android.support.v4.app.FragmentActivity;
15 | import android.support.v4.content.ContextCompat;
16 | import android.view.View;
17 | import android.view.WindowManager;
18 | import android.widget.Button;
19 | import android.widget.ImageView;
20 | import android.widget.RelativeLayout;
21 | import android.widget.TextView;
22 | import android.widget.Toast;
23 |
24 | import com.yuyh.library.imgsel.common.Callback;
25 | import com.yuyh.library.imgsel.common.Constant;
26 | import com.yuyh.library.imgsel.utils.FileUtils;
27 | import com.yuyh.library.imgsel.utils.StatusBarCompat;
28 |
29 | import java.io.File;
30 | import java.util.ArrayList;
31 |
32 | public class ImgSelActivity extends FragmentActivity implements View.OnClickListener, Callback {
33 |
34 | public static final String INTENT_RESULT = "result";
35 | private static final int IMAGE_CROP_CODE = 1;
36 | private static final int STORAGE_REQUEST_CODE = 1;
37 |
38 | private ImgSelConfig config;
39 |
40 | private RelativeLayout rlTitleBar;
41 | private TextView tvTitle;
42 | private Button btnConfirm;
43 | private ImageView ivBack;
44 | private String cropImagePath;
45 |
46 | private ArrayList result = new ArrayList<>();
47 |
48 | public static void startActivity(Activity activity, ImgSelConfig config, int RequestCode) {
49 | Intent intent = new Intent(activity, ImgSelActivity.class);
50 | Constant.config = config;
51 | activity.startActivityForResult(intent, RequestCode);
52 | }
53 |
54 | public static void startActivity(Fragment fragment, ImgSelConfig config, int RequestCode){
55 | Intent intent = new Intent(fragment.getActivity(), ImgSelActivity.class);
56 | Constant.config = config;
57 | fragment.startActivityForResult(intent, RequestCode);
58 | }
59 |
60 | @Override
61 | protected void onCreate(Bundle savedInstanceState) {
62 | super.onCreate(savedInstanceState);
63 | setContentView(R.layout.activity_img_sel);
64 | Constant.imageList.clear();
65 | config = Constant.config;
66 |
67 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
68 | != PackageManager.PERMISSION_GRANTED) {
69 | //申请权限
70 | ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
71 | STORAGE_REQUEST_CODE);
72 | } else {
73 | getSupportFragmentManager().beginTransaction()
74 | .add(R.id.fmImageList, ImgSelFragment.instance(config), null)
75 | .commit();
76 | }
77 |
78 | initView();
79 | if (!FileUtils.isSdCardAvailable()) {
80 | Toast.makeText(this, "SD卡不可用", Toast.LENGTH_SHORT).show();
81 | }
82 | }
83 |
84 | private void initView() {
85 | rlTitleBar = (RelativeLayout) findViewById(R.id.rlTitleBar);
86 | tvTitle = (TextView) findViewById(R.id.tvTitle);
87 | btnConfirm = (Button) findViewById(R.id.btnConfirm);
88 | btnConfirm.setOnClickListener(this);
89 | ivBack = (ImageView) findViewById(R.id.ivBack);
90 | ivBack.setOnClickListener(this);
91 |
92 | if (config != null) {
93 | if (config.backResId != -1) {
94 | ivBack.setImageResource(config.backResId);
95 | }
96 |
97 | if (config.statusBarColor != -1) {
98 | StatusBarCompat.compat(this, config.statusBarColor);
99 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
100 | && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
101 | //透明状态栏
102 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
103 | }
104 | }
105 | rlTitleBar.setBackgroundColor(config.titleBgColor);
106 | tvTitle.setTextColor(config.titleColor);
107 | tvTitle.setText(config.title);
108 | btnConfirm.setBackgroundColor(config.btnBgColor);
109 | btnConfirm.setTextColor(config.btnTextColor);
110 | }
111 | }
112 |
113 | @Override
114 | public void onClick(View v) {
115 | int id = v.getId();
116 | if (id == R.id.btnConfirm) {
117 | if (Constant.imageList != null && !Constant.imageList.isEmpty()) {
118 | exit();
119 | }
120 | } else if (id == R.id.ivBack) {
121 | finish();
122 | }
123 | }
124 |
125 | @Override
126 | public void onSingleImageSelected(String path) {
127 | if (config.needCrop) {
128 | crop(path);
129 | } else {
130 | Constant.imageList.add(path);
131 | exit();
132 | }
133 | }
134 |
135 | @Override
136 | public void onImageSelected(String path) {
137 | btnConfirm.setText("确定(" + Constant.imageList.size() + "/" + config.maxNum + ")");
138 |
139 | }
140 |
141 | @Override
142 | public void onImageUnselected(String path) {
143 | btnConfirm.setText("确定(" + Constant.imageList.size() + "/" + config.maxNum + ")");
144 | }
145 |
146 | @Override
147 | public void onCameraShot(File imageFile) {
148 | if (imageFile != null) {
149 | if (config.needCrop) {
150 | crop(imageFile.getAbsolutePath());
151 | } else {
152 | Constant.imageList.add(imageFile.getAbsolutePath());
153 | exit();
154 | }
155 | }
156 | }
157 |
158 | private void crop(String imagePath) {
159 | File file = new File(FileUtils.createRootPath(this) + "/" + System.currentTimeMillis() + ".jpg");
160 |
161 | cropImagePath = file.getAbsolutePath();
162 | Intent intent = new Intent("com.android.camera.action.CROP");
163 | intent.setDataAndType(Uri.fromFile(new File(imagePath)), "image/*");
164 | intent.putExtra("crop", "true");
165 | intent.putExtra("aspectX", config.aspectX);
166 | intent.putExtra("aspectY", config.aspectY);
167 | intent.putExtra("outputX", config.outputX);
168 | intent.putExtra("outputY", config.outputY);
169 | intent.putExtra("return-data", false);
170 | intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
171 | startActivityForResult(intent, IMAGE_CROP_CODE);
172 | }
173 |
174 | @Override
175 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
176 | if (requestCode == IMAGE_CROP_CODE && resultCode == RESULT_OK) {
177 | Constant.imageList.add(cropImagePath);
178 | exit();
179 | }
180 | super.onActivityResult(requestCode, resultCode, data);
181 | }
182 |
183 | public void exit() {
184 | Intent intent = new Intent();
185 | result.clear();
186 | result.addAll(Constant.imageList);
187 | intent.putStringArrayListExtra(INTENT_RESULT, result);
188 | setResult(RESULT_OK, intent);
189 | Constant.imageList.clear();
190 | finish();
191 | }
192 |
193 | @Override
194 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
195 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
196 | switch (requestCode){
197 | case STORAGE_REQUEST_CODE:
198 | if(grantResults.length >= 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
199 | getSupportFragmentManager().beginTransaction()
200 | .add(R.id.fmImageList, ImgSelFragment.instance(config), null)
201 | .commitAllowingStateLoss();
202 | } else {
203 | Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
204 | }
205 | break;
206 | default:break;
207 | }
208 | }
209 | }
210 |
--------------------------------------------------------------------------------
/app/src/main/java/com/barnettwong/pushcommunity/BigImagePagerActivity.java:
--------------------------------------------------------------------------------
1 | package com.barnettwong.pushcommunity;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.os.Parcelable;
8 | import android.support.annotation.Nullable;
9 | import android.support.v4.view.PagerAdapter;
10 | import android.support.v4.view.ViewPager;
11 | import android.support.v7.app.AppCompatActivity;
12 | import android.view.Gravity;
13 | import android.view.KeyEvent;
14 | import android.view.LayoutInflater;
15 | import android.view.View;
16 | import android.view.ViewGroup;
17 | import android.widget.FrameLayout;
18 | import android.widget.LinearLayout;
19 | import android.widget.ProgressBar;
20 |
21 | import com.barnettwong.pushcommunity.view.ViewPagerFixed;
22 | import com.bumptech.glide.Glide;
23 | import com.bumptech.glide.load.engine.DiskCacheStrategy;
24 | import com.bumptech.glide.load.resource.drawable.GlideDrawable;
25 | import com.bumptech.glide.request.RequestListener;
26 | import com.bumptech.glide.request.target.Target;
27 |
28 | import java.util.ArrayList;
29 | import java.util.List;
30 |
31 | import uk.co.senab.photoview.PhotoView;
32 | import uk.co.senab.photoview.PhotoViewAttacher;
33 |
34 | /**
35 | * 查看大图 glide
36 | */
37 | public class BigImagePagerActivity extends AppCompatActivity {
38 | public static final String INTENT_IMGURLS = "imgurls";
39 | public static final String INTENT_POSITION = "position";
40 | private List guideViewList = new ArrayList();
41 | private LinearLayout guideGroup;
42 |
43 | public static void startImagePagerActivity(Activity activity, List imgUrls, int position){
44 | Intent intent = new Intent(activity, BigImagePagerActivity.class);
45 | intent.putStringArrayListExtra(INTENT_IMGURLS, new ArrayList(imgUrls));
46 | intent.putExtra(INTENT_POSITION, position);
47 | activity.startActivity(intent);
48 | activity.overridePendingTransition(R.anim.fade_in,
49 | R.anim.fade_out);
50 | }
51 |
52 | @Override
53 | protected void onCreate(@Nullable Bundle savedInstanceState) {
54 | super.onCreate(savedInstanceState);
55 | setContentView(R.layout.act_image_pager);
56 |
57 | //设置透明状态栏
58 | // SetTranslanteBar();
59 |
60 | ViewPager viewPager = (ViewPagerFixed) findViewById(R.id.pager);
61 | guideGroup = (LinearLayout) findViewById(R.id.guideGroup);
62 |
63 | int startPos = getIntent().getIntExtra(INTENT_POSITION, 0);
64 | ArrayList imgUrls = getIntent().getStringArrayListExtra(INTENT_IMGURLS);
65 |
66 | ImageAdapter mAdapter = new ImageAdapter(this);
67 | mAdapter.setDatas(imgUrls);
68 | viewPager.setAdapter(mAdapter);
69 | viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
70 |
71 | @Override
72 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
73 |
74 | }
75 |
76 | @Override
77 | public void onPageSelected(int position) {
78 | for(int i=0; i imgUrls) {
113 | if(imgUrls!=null && imgUrls.size()>0){
114 | guideViewList.clear();
115 | for (int i=0; i datas = new ArrayList();
131 | private LayoutInflater inflater;
132 | private Context context;
133 |
134 | public void setDatas(List datas) {
135 | if(datas != null )
136 | this.datas = datas;
137 | }
138 |
139 | public ImageAdapter(Context context){
140 | this.context = context;
141 | this.inflater = LayoutInflater.from(context);
142 |
143 | }
144 |
145 | @Override
146 | public int getCount() {
147 | if(datas == null) return 0;
148 | return datas.size();
149 | }
150 |
151 |
152 | @Override
153 | public Object instantiateItem(ViewGroup container, final int position) {
154 | View view = inflater.inflate(R.layout.item_pager_image, container, false);
155 | if(view != null){
156 | final PhotoView imageView = (PhotoView) view.findViewById(R.id.image);
157 |
158 | //单击图片退出
159 | imageView.setOnPhotoTapListener(new PhotoViewAttacher.OnPhotoTapListener() {
160 | @Override
161 | public void onPhotoTap(View view, float x, float y) {
162 | BigImagePagerActivity.this.finish();
163 | BigImagePagerActivity.this.overridePendingTransition(R.anim.act_fade_in_center,
164 | R.anim.act_fade_out_center);
165 | }
166 | });
167 |
168 | //loading
169 | final ProgressBar loading = new ProgressBar(context);
170 | FrameLayout.LayoutParams loadingLayoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
171 | ViewGroup.LayoutParams.WRAP_CONTENT);
172 | loadingLayoutParams.gravity = Gravity.CENTER;
173 | loading.setLayoutParams(loadingLayoutParams);
174 | ((FrameLayout)view).addView(loading);
175 |
176 | final String imgurl = datas.get(position);
177 |
178 | loading.setVisibility(View.VISIBLE);
179 | Glide.with(context).load(imgurl)
180 | .diskCacheStrategy(DiskCacheStrategy.ALL)
181 | .error(R.drawable.ic_empty_picture)
182 | .thumbnail(0.1f)
183 | .listener(new RequestListener() {
184 | @Override
185 | public boolean onException(Exception e, String model, Target target, boolean isFirstResource) {
186 | loading.setVisibility(View.GONE);
187 | return false;
188 | }
189 |
190 | @Override
191 | public boolean onResourceReady(GlideDrawable resource, String model, Target target, boolean isFromMemoryCache, boolean isFirstResource) {
192 | loading.setVisibility(View.GONE);
193 | return false;
194 | }
195 | })
196 | .into(imageView);
197 |
198 | container.addView(view, 0);
199 | }
200 | return view;
201 | }
202 |
203 | @Override
204 | public void destroyItem(ViewGroup container, int position, Object object) {
205 | container.removeView((View) object);
206 | }
207 |
208 | @Override
209 | public boolean isViewFromObject(View view, Object object) {
210 | return view.equals(object);
211 | }
212 |
213 | @Override
214 | public void restoreState(Parcelable state, ClassLoader loader) {
215 | }
216 |
217 | @Override
218 | public Parcelable saveState() {
219 | return null;
220 | }
221 |
222 |
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/utils/FileUtils.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel.utils;
2 |
3 | import android.content.Context;
4 | import android.content.res.AssetManager;
5 | import android.os.Environment;
6 |
7 | import java.io.BufferedReader;
8 | import java.io.File;
9 | import java.io.FileInputStream;
10 | import java.io.FileOutputStream;
11 | import java.io.FileReader;
12 | import java.io.IOException;
13 | import java.io.InputStream;
14 | import java.io.InputStreamReader;
15 | import java.nio.channels.FileChannel;
16 | import java.text.DecimalFormat;
17 |
18 | /**
19 | * @author yuyh.
20 | * @date 16/4/9.
21 | */
22 | public class FileUtils {
23 |
24 | private static final String TAG = FileUtils.class.getSimpleName();
25 |
26 | /**
27 | * 创建根缓存目录
28 | *
29 | * @return
30 | */
31 | public static String createRootPath(Context context) {
32 | String cacheRootPath = "";
33 | if (isSdCardAvailable()) {
34 | // /sdcard/Android/data//cache
35 | cacheRootPath = context.getExternalCacheDir().getPath();
36 | } else {
37 | // /data/data//cache
38 | cacheRootPath = context.getCacheDir().getPath();
39 | }
40 | return cacheRootPath;
41 | }
42 |
43 | public static boolean isSdCardAvailable() {
44 | return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
45 | }
46 |
47 | /**
48 | * 递归创建文件夹
49 | *
50 | * @param dirPath
51 | * @return 创建失败返回""
52 | */
53 | public static String createDir(String dirPath) {
54 | try {
55 | File file = new File(dirPath);
56 | if (file.getParentFile().exists()) {
57 | LogUtils.i("----- 创建文件夹" + file.getAbsolutePath());
58 | file.mkdir();
59 | return file.getAbsolutePath();
60 | } else {
61 | createDir(file.getParentFile().getAbsolutePath());
62 | LogUtils.i("----- 创建文件夹" + file.getAbsolutePath());
63 | file.mkdir();
64 | }
65 | } catch (Exception e) {
66 | e.printStackTrace();
67 | }
68 | return dirPath;
69 | }
70 |
71 | /**
72 | * 递归创建文件夹
73 | *
74 | * @param file
75 | * @return 创建失败返回""
76 | */
77 | public static String createFile(File file) {
78 | try {
79 | if (file.getParentFile().exists()) {
80 | LogUtils.i("----- 创建文件" + file.getAbsolutePath());
81 | file.createNewFile();
82 | return file.getAbsolutePath();
83 | } else {
84 | createDir(file.getParentFile().getAbsolutePath());
85 | file.createNewFile();
86 | LogUtils.i("----- 创建文件" + file.getAbsolutePath());
87 | }
88 | } catch (Exception e) {
89 | e.printStackTrace();
90 | }
91 | return "";
92 | }
93 |
94 | public static String getImageCachePath(String path){
95 | return createDir(path);
96 | }
97 |
98 | /**
99 | * 获取图片缓存目录
100 | *
101 | * @return 创建失败, 返回""
102 | */
103 | public static String getImageCachePath(Context context) {
104 | String path = createDir(createRootPath(context) + File.separator + "img" + File.separator);
105 | return path;
106 | }
107 |
108 | /**
109 | * 获取图片裁剪缓存目录
110 | *
111 | * @return 创建失败, 返回""
112 | */
113 | public static String getImageCropCachePath(Context context) {
114 | String path = createDir(createRootPath(context) + File.separator + "imgCrop" + File.separator);
115 | return path;
116 | }
117 |
118 | /**
119 | * 将内容写入文件
120 | *
121 | * @param filePath eg:/mnt/sdcard/demo.txt
122 | * @param content 内容
123 | */
124 | public static void writeFileSdcard(String filePath, String content, boolean isAppend) {
125 | try {
126 | FileOutputStream fout = new FileOutputStream(filePath, isAppend);
127 | byte[] bytes = content.getBytes();
128 | fout.write(bytes);
129 | fout.close();
130 | } catch (Exception e) {
131 | e.printStackTrace();
132 | }
133 | }
134 |
135 | /**
136 | * 打开Asset下的文件
137 | *
138 | * @param context
139 | * @param fileName
140 | * @return
141 | */
142 | public static InputStream openAssetFile(Context context, String fileName) {
143 | AssetManager am = context.getAssets();
144 | InputStream is = null;
145 | try {
146 | is = am.open(fileName);
147 | } catch (IOException e) {
148 | e.printStackTrace();
149 | }
150 | return is;
151 | }
152 |
153 | /**
154 | * 获取Raw下的文件内容
155 | *
156 | * @param context
157 | * @param resId
158 | * @return 文件内容
159 | */
160 | public static String getFileFromRaw(Context context, int resId) {
161 | if (context == null) {
162 | return null;
163 | }
164 |
165 | StringBuilder s = new StringBuilder();
166 | try {
167 | InputStreamReader in = new InputStreamReader(context.getResources().openRawResource(resId));
168 | BufferedReader br = new BufferedReader(in);
169 | String line;
170 | while ((line = br.readLine()) != null) {
171 | s.append(line);
172 | }
173 | return s.toString();
174 | } catch (IOException e) {
175 | e.printStackTrace();
176 | return null;
177 | }
178 | }
179 |
180 | /**
181 | * 文件拷贝
182 | *
183 | * @param src 源文件
184 | * @param desc 目的文件
185 | */
186 | public static void fileChannelCopy(File src, File desc) {
187 | FileInputStream fi = null;
188 | FileOutputStream fo = null;
189 | try {
190 | fi = new FileInputStream(src);
191 | fo = new FileOutputStream(desc);
192 | FileChannel in = fi.getChannel();//得到对应的文件通道
193 | FileChannel out = fo.getChannel();//得到对应的文件通道
194 | in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道
195 | } catch (IOException e) {
196 | e.printStackTrace();
197 | } finally {
198 | try {
199 | if (fo != null) fo.close();
200 | if (fi != null) fi.close();
201 | } catch (IOException e) {
202 | e.printStackTrace();
203 | }
204 | }
205 | }
206 |
207 | /**
208 | * 转换文件大小
209 | *
210 | * @param fileLen 单位B
211 | * @return
212 | */
213 | public static String formatFileSizeToString(long fileLen) {
214 | DecimalFormat df = new DecimalFormat("#.00");
215 | String fileSizeString = "";
216 | if (fileLen < 1024) {
217 | fileSizeString = df.format((double) fileLen) + "B";
218 | } else if (fileLen < 1048576) {
219 | fileSizeString = df.format((double) fileLen / 1024) + "K";
220 | } else if (fileLen < 1073741824) {
221 | fileSizeString = df.format((double) fileLen / 1048576) + "M";
222 | } else {
223 | fileSizeString = df.format((double) fileLen / 1073741824) + "G";
224 | }
225 | return fileSizeString;
226 | }
227 |
228 | /**
229 | * 删除指定文件
230 | *
231 | * @param file
232 | * @return
233 | * @throws IOException
234 | */
235 | public static boolean deleteFile(File file) throws IOException {
236 | return deleteFileOrDirectory(file);
237 | }
238 |
239 | /**
240 | * 删除指定文件,如果是文件夹,则递归删除
241 | *
242 | * @param file
243 | * @return
244 | * @throws IOException
245 | */
246 | public static boolean deleteFileOrDirectory(File file) throws IOException {
247 | try {
248 | if (file != null && file.isFile()) {
249 | return file.delete();
250 | }
251 | if (file != null && file.isDirectory()) {
252 | File[] childFiles = file.listFiles();
253 | // 删除空文件夹
254 | if (childFiles == null || childFiles.length == 0) {
255 | return file.delete();
256 | }
257 | // 递归删除文件夹下的子文件
258 | for (int i = 0; i < childFiles.length; i++) {
259 | deleteFileOrDirectory(childFiles[i]);
260 | }
261 | return file.delete();
262 | }
263 | } catch (Exception e) {
264 | e.printStackTrace();
265 | }
266 | return false;
267 | }
268 |
269 | /***
270 | * 获取文件扩展名
271 | *
272 | * @param filename 文件名
273 | * @return
274 | */
275 | public static String getExtensionName(String filename) {
276 | if ((filename != null) && (filename.length() > 0)) {
277 | int dot = filename.lastIndexOf('.');
278 | if ((dot > -1) && (dot < (filename.length() - 1))) {
279 | return filename.substring(dot + 1);
280 | }
281 | }
282 | return filename;
283 | }
284 |
285 | /**
286 | * 获取文件内容
287 | *
288 | * @param path
289 | * @return
290 | */
291 | public static String getFileOutputString(String path) {
292 | try {
293 | BufferedReader bufferedReader = new BufferedReader(new FileReader(path), 8192);
294 | StringBuilder sb = new StringBuilder();
295 | String line = null;
296 | while ((line = bufferedReader.readLine()) != null) {
297 | sb.append("\n").append(line);
298 | }
299 | bufferedReader.close();
300 | return sb.toString();
301 | } catch (IOException e) {
302 | e.printStackTrace();
303 | }
304 | return null;
305 | }
306 | }
307 |
--------------------------------------------------------------------------------
/photoPicker/src/main/java/com/yuyh/library/imgsel/ImgSelFragment.java:
--------------------------------------------------------------------------------
1 | package com.yuyh.library.imgsel;
2 |
3 |
4 | import android.app.Activity;
5 | import android.content.Intent;
6 | import android.database.Cursor;
7 | import android.graphics.Color;
8 | import android.graphics.drawable.ColorDrawable;
9 | import android.net.Uri;
10 | import android.os.Build;
11 | import android.os.Bundle;
12 | import android.provider.MediaStore;
13 | import android.support.annotation.Nullable;
14 | import android.support.v4.app.Fragment;
15 | import android.support.v4.app.LoaderManager;
16 | import android.support.v4.content.CursorLoader;
17 | import android.support.v4.content.FileProvider;
18 | import android.support.v4.content.Loader;
19 | import android.support.v7.widget.GridLayoutManager;
20 | import android.support.v7.widget.ListPopupWindow;
21 | import android.support.v7.widget.RecyclerView;
22 | import android.view.LayoutInflater;
23 | import android.view.View;
24 | import android.view.ViewGroup;
25 | import android.view.WindowManager;
26 | import android.widget.Button;
27 | import android.widget.Toast;
28 |
29 | import com.yuyh.library.imgsel.adapter.FolderListAdapter;
30 | import com.yuyh.library.imgsel.adapter.ImageListAdapter;
31 | import com.yuyh.library.imgsel.bean.Folder;
32 | import com.yuyh.library.imgsel.bean.Image;
33 | import com.yuyh.library.imgsel.common.Callback;
34 | import com.yuyh.library.imgsel.common.Constant;
35 | import com.yuyh.library.imgsel.common.OnFolderChangeListener;
36 | import com.yuyh.library.imgsel.common.OnItemClickListener;
37 | import com.yuyh.library.imgsel.utils.FileUtils;
38 | import com.yuyh.library.imgsel.utils.LogUtils;
39 | import com.yuyh.library.imgsel.widget.DividerGridItemDecoration;
40 |
41 | import java.io.File;
42 | import java.util.ArrayList;
43 | import java.util.List;
44 |
45 |
46 | public class ImgSelFragment extends Fragment implements View.OnClickListener {
47 |
48 | private RecyclerView rvImageList;
49 | private Button btnAlbumSelected;
50 | private View rlBottom;
51 |
52 | private ImgSelConfig config;
53 | private Callback callback;
54 | private List folderList = new ArrayList<>();
55 | private List imageList = new ArrayList<>();
56 |
57 | private ListPopupWindow folderPopupWindow;
58 |
59 | private ImageListAdapter imageListAdapter;
60 | private FolderListAdapter folderListAdapter;
61 |
62 | private boolean hasFolderGened = false;
63 | private static final int LOADER_ALL = 0;
64 | private static final int LOADER_CATEGORY = 1;
65 | private static final int REQUEST_CAMERA = 5;
66 |
67 | private File tempFile;
68 |
69 | public static ImgSelFragment instance(ImgSelConfig config) {
70 | ImgSelFragment fragment = new ImgSelFragment();
71 | Bundle bundle = new Bundle();
72 | fragment.setArguments(bundle);
73 | return fragment;
74 | }
75 |
76 | @Override
77 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
78 | View view = inflater.inflate(R.layout.fragment_img_sel, container, false);
79 | rvImageList = (RecyclerView) view.findViewById(R.id.rvImageList);
80 | btnAlbumSelected = (Button) view.findViewById(R.id.btnAlbumSelected);
81 | btnAlbumSelected.setOnClickListener(this);
82 | rlBottom = view.findViewById(R.id.rlBottom);
83 | return view;
84 | }
85 |
86 | @Override
87 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
88 | super.onViewCreated(view, savedInstanceState);
89 |
90 | config = Constant.config;
91 | try {
92 | callback = (Callback) getActivity();
93 | } catch (Exception e) {
94 |
95 | }
96 |
97 | rvImageList.setLayoutManager(new GridLayoutManager(rvImageList.getContext(), 3));
98 | rvImageList.addItemDecoration(new DividerGridItemDecoration(rvImageList.getContext()));
99 | if (config.needCamera)
100 | imageList.add(new Image());
101 |
102 | imageListAdapter = new ImageListAdapter(getActivity(), imageList, config);
103 | imageListAdapter.setShowCamera(config.needCamera);
104 | imageListAdapter.setMutiSelect(config.multiSelect);
105 | rvImageList.setAdapter(imageListAdapter);
106 | imageListAdapter.setOnItemClickListener(new OnItemClickListener() {
107 | @Override
108 | public void onClick(int position, Image image) {
109 | if (config.needCamera && position == 0) {
110 | showCameraAction();
111 | } else {
112 | if (image != null) {
113 | if (config.multiSelect) {
114 | if (Constant.imageList.contains(image.path)) {
115 | Constant.imageList.remove(image.path);
116 | if (callback != null) {
117 | callback.onImageUnselected(image.path);
118 | }
119 | } else {
120 | if (config.maxNum <= Constant.imageList.size()) {
121 | Toast.makeText(getActivity(), "最多选择" + config.maxNum + "张图片", Toast.LENGTH_SHORT).show();
122 | return;
123 | }
124 |
125 | Constant.imageList.add(image.path);
126 | if (callback != null) {
127 | callback.onImageSelected(image.path);
128 | }
129 | }
130 | imageListAdapter.select(image,position);
131 | } else {
132 | if (callback != null) {
133 | callback.onSingleImageSelected(image.path);
134 | }
135 | }
136 | }
137 | }
138 | }
139 | });
140 |
141 | folderListAdapter = new FolderListAdapter(getActivity(), folderList, config);
142 |
143 | getActivity().getSupportLoaderManager().initLoader(LOADER_ALL, null, mLoaderCallback);
144 | }
145 |
146 | private LoaderManager.LoaderCallbacks mLoaderCallback = new LoaderManager.LoaderCallbacks() {
147 |
148 | private final String[] IMAGE_PROJECTION = {
149 | MediaStore.Images.Media.DATA,
150 | MediaStore.Images.Media.DISPLAY_NAME,
151 | MediaStore.Images.Media.DATE_ADDED,
152 | MediaStore.Images.Media._ID};
153 |
154 | @Override
155 | public Loader onCreateLoader(int id, Bundle args) {
156 | if (id == LOADER_ALL) {
157 | CursorLoader cursorLoader = new CursorLoader(getActivity(),
158 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION,
159 | null, null, IMAGE_PROJECTION[2] + " DESC");
160 | return cursorLoader;
161 | } else if (id == LOADER_CATEGORY) {
162 | CursorLoader cursorLoader = new CursorLoader(getActivity(),
163 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION,
164 | IMAGE_PROJECTION[0] + " like '%" + args.getString("path") + "%'", null, IMAGE_PROJECTION[2] + " DESC");
165 | return cursorLoader;
166 | }
167 | return null;
168 | }
169 |
170 | @Override
171 | public void onLoadFinished(Loader loader, Cursor data) {
172 | if (data != null) {
173 | int count = data.getCount();
174 | if (count > 0) {
175 | List tempImageList = new ArrayList<>();
176 | data.moveToFirst();
177 | do {
178 | String path = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[0]));
179 | String name = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[1]));
180 | long dateTime = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[2]));
181 | Image image = new Image(path, name, dateTime);
182 | if (!image.path.endsWith("gif"))
183 | tempImageList.add(image);
184 | if (!hasFolderGened) {
185 | File imageFile = new File(path);
186 | File folderFile = imageFile.getParentFile();
187 | Folder folder = new Folder();
188 | folder.name = folderFile.getName();
189 | folder.path = folderFile.getAbsolutePath();
190 | folder.cover = image;
191 | if (!folderList.contains(folder)) {
192 | List imageList = new ArrayList<>();
193 | imageList.add(image);
194 | folder.images = imageList;
195 | folderList.add(folder);
196 | } else {
197 | Folder f = folderList.get(folderList.indexOf(folder));
198 | f.images.add(image);
199 | }
200 | }
201 |
202 | } while (data.moveToNext());
203 |
204 | imageList.clear();
205 | if (config.needCamera)
206 | imageList.add(new Image());
207 | imageList.addAll(tempImageList);
208 |
209 |
210 | imageListAdapter.notifyDataSetChanged();
211 |
212 | if (Constant.imageList != null && Constant.imageList.size() > 0) {
213 | //adapter.setDefaultSelected(resultList);
214 | }
215 |
216 | folderListAdapter.notifyDataSetChanged();
217 |
218 | hasFolderGened = true;
219 | }
220 | }
221 | }
222 |
223 | @Override
224 | public void onLoaderReset(Loader loader) {
225 |
226 | }
227 | };
228 |
229 | private void createPopupFolderList(int width, int height) {
230 | folderPopupWindow = new ListPopupWindow(getActivity());
231 | folderPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
232 | folderPopupWindow.setAdapter(folderListAdapter);
233 | folderPopupWindow.setContentWidth(width);
234 | folderPopupWindow.setWidth(width);
235 | folderPopupWindow.setHeight(height);
236 | folderPopupWindow.setAnchorView(rlBottom);
237 | folderPopupWindow.setModal(true);
238 | folderListAdapter.setOnFloderChangeListener(new OnFolderChangeListener() {
239 | @Override
240 | public void onChange(int position, Folder folder) {
241 | folderPopupWindow.dismiss();
242 | if (position == 0) {
243 | getActivity().getSupportLoaderManager().restartLoader(LOADER_ALL, null, mLoaderCallback);
244 | btnAlbumSelected.setText("所有图片");
245 | } else {
246 | imageList.clear();
247 | if (config.needCamera)
248 | imageList.add(new Image());
249 | imageList.addAll(folder.images);
250 | imageListAdapter.notifyDataSetChanged();
251 |
252 | btnAlbumSelected.setText(folder.name);
253 | }
254 | }
255 | });
256 | }
257 |
258 | @Override
259 | public void onClick(View v) {
260 | if (v.getId() == btnAlbumSelected.getId()) {
261 | if (folderPopupWindow == null) {
262 | WindowManager wm = getActivity().getWindowManager();
263 | int width = wm.getDefaultDisplay().getWidth();
264 | createPopupFolderList(width / 3 * 2, width / 3 * 2);
265 | }
266 |
267 | if (folderPopupWindow.isShowing()) {
268 | folderPopupWindow.dismiss();
269 | } else {
270 | folderPopupWindow.show();
271 | int index = folderListAdapter.getSelectIndex();
272 | index = index == 0 ? index : index - 1;
273 | folderPopupWindow.getListView().setSelection(index);
274 | }
275 | }
276 | }
277 |
278 | private void showCameraAction() {
279 | if (config.maxNum <= Constant.imageList.size()) {
280 | Toast.makeText(getActivity(), "最多选择" + config.maxNum + "张图片", Toast.LENGTH_SHORT).show();
281 | return;
282 | }
283 | Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
284 | if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
285 | tempFile = new File(FileUtils.createRootPath(getActivity()) + "/" + System.currentTimeMillis() + ".jpg");
286 | LogUtils.e(tempFile.getAbsolutePath());
287 | FileUtils.createFile(tempFile);
288 |
289 | Uri photoUri;
290 | //Android7.0调用系统相机拍照、访问相册问题
291 | if (Build.VERSION.SDK_INT >= 24) {
292 | photoUri = FileProvider.getUriForFile(getContext(),"com.yuyh.library.imgsel.fileProvider", tempFile);
293 | } else {
294 | photoUri = Uri.fromFile(tempFile);
295 | }
296 | cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
297 | startActivityForResult(cameraIntent, REQUEST_CAMERA);
298 | } else {
299 | Toast.makeText(getActivity(), "打开相机失败", Toast.LENGTH_SHORT).show();
300 | }
301 | }
302 |
303 | @Override
304 | public void onActivityResult(int requestCode, int resultCode, Intent data) {
305 | if (requestCode == REQUEST_CAMERA) {
306 | if (resultCode == Activity.RESULT_OK) {
307 | if (tempFile != null) {
308 | if (callback != null) {
309 | callback.onCameraShot(tempFile);
310 | }
311 | }
312 | } else {
313 | if (tempFile != null && tempFile.exists()) {
314 | tempFile.delete();
315 | }
316 | }
317 | }
318 | super.onActivityResult(requestCode, resultCode, data);
319 | }
320 | }
321 |
--------------------------------------------------------------------------------