├── .gitignore
├── snapshot
├── change.jpg
├── features.jpg
├── pick_gridview.jpg
├── pick_viewpager.jpg
└── pick_viewpager_zoomout.jpg
├── source
├── libs
│ ├── photoview.jar
│ ├── android-support-v4.jar
│ ├── nineoldandroids-2.4.0.jar
│ └── universal-image-loader-1.9.3.jar
├── res
│ ├── drawable-ldpi
│ │ └── no_media.jpg
│ ├── drawable-xxhdpi
│ │ ├── failed.png
│ │ ├── checkbox_up.png
│ │ ├── icon_delete.png
│ │ ├── take_photo.jpg
│ │ ├── checkbox_selected.png
│ │ ├── icon_back_normal.png
│ │ └── icon_back_selected.png
│ ├── color
│ │ └── btn_text_color.xml
│ ├── drawable
│ │ ├── icon_back.xml
│ │ └── on_focus_checkbox.xml
│ ├── values
│ │ ├── dimen.xml
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── attrs.xml
│ └── layout
│ │ ├── bottom_bar.xml
│ │ ├── image_picker.xml
│ │ ├── gallery_item.xml
│ │ ├── title_bar.xml
│ │ └── view_pager.xml
├── src
│ └── com
│ │ ├── jfeinstein
│ │ └── jazzyviewpager
│ │ │ ├── PhotoViewListener.java
│ │ │ ├── OutlineContainer.java
│ │ │ ├── JazzyPagerAdapter.java
│ │ │ └── JazzyViewPager.java
│ │ └── habzy
│ │ └── image
│ │ ├── viewpager
│ │ └── wrap
│ │ │ ├── ViewPagerListener.java
│ │ │ └── ViewPagerDialogFragment.java
│ │ ├── models
│ │ ├── ItemModel.java
│ │ └── ViewParams.java
│ │ ├── picker
│ │ ├── ViewPickerListener.java
│ │ ├── CustGridView.java
│ │ ├── GalleryAdapter.java
│ │ └── GridViewPicker.java
│ │ └── tools
│ │ └── ImageTools.java
├── AndroidManifest.xml
├── .classpath
├── project.properties
├── proguard-project.txt
└── .project
├── sample
├── ic_launcher-web.png
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ ├── icon_1_select_un.png
│ │ ├── icon_1_selected.png
│ │ ├── icon_take_photo.png
│ │ ├── bg_btn_done_clicked.png
│ │ ├── bg_btn_done_normal.png
│ │ ├── icon_1_back_clicked.png
│ │ ├── icon_1_back_normal.png
│ │ ├── icon_2_delete_clicked.png
│ │ ├── icon_2_delete_normal.png
│ │ └── image_view_loading_default.9.png
│ ├── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── drawable
│ │ ├── icon_1_back.xml
│ │ ├── bg_1_done.xml
│ │ ├── icon_1_delete.xml
│ │ └── on_1_checkbox.xml
│ ├── values-w820dp
│ │ └── dimens.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── layout
│ │ ├── titlebar.xml
│ │ ├── gallery.xml
│ │ └── activity_main.xml
├── .classpath
├── project.properties
├── proguard-project.txt
├── .project
├── AndroidManifest.xml
└── src
│ └── com
│ └── habzy
│ └── image
│ └── picker
│ └── sample
│ ├── ViewPickerActivity.java
│ └── MainActivity.java
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | */bin/*
2 | */gen/*
3 | */.settings/*
4 |
--------------------------------------------------------------------------------
/snapshot/change.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/snapshot/change.jpg
--------------------------------------------------------------------------------
/snapshot/features.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/snapshot/features.jpg
--------------------------------------------------------------------------------
/source/libs/photoview.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/source/libs/photoview.jar
--------------------------------------------------------------------------------
/sample/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/sample/ic_launcher-web.png
--------------------------------------------------------------------------------
/snapshot/pick_gridview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/snapshot/pick_gridview.jpg
--------------------------------------------------------------------------------
/snapshot/pick_viewpager.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/snapshot/pick_viewpager.jpg
--------------------------------------------------------------------------------
/snapshot/pick_viewpager_zoomout.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/snapshot/pick_viewpager_zoomout.jpg
--------------------------------------------------------------------------------
/source/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/source/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/source/libs/nineoldandroids-2.4.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/source/libs/nineoldandroids-2.4.0.jar
--------------------------------------------------------------------------------
/source/res/drawable-ldpi/no_media.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/source/res/drawable-ldpi/no_media.jpg
--------------------------------------------------------------------------------
/source/res/drawable-xxhdpi/failed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/source/res/drawable-xxhdpi/failed.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/sample/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/source/res/drawable-xxhdpi/checkbox_up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/source/res/drawable-xxhdpi/checkbox_up.png
--------------------------------------------------------------------------------
/source/res/drawable-xxhdpi/icon_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/source/res/drawable-xxhdpi/icon_delete.png
--------------------------------------------------------------------------------
/source/res/drawable-xxhdpi/take_photo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/source/res/drawable-xxhdpi/take_photo.jpg
--------------------------------------------------------------------------------
/source/libs/universal-image-loader-1.9.3.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/source/libs/universal-image-loader-1.9.3.jar
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/icon_1_select_un.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/sample/res/drawable-xxhdpi/icon_1_select_un.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/icon_1_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/sample/res/drawable-xxhdpi/icon_1_selected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/icon_take_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/sample/res/drawable-xxhdpi/icon_take_photo.png
--------------------------------------------------------------------------------
/source/res/drawable-xxhdpi/checkbox_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/source/res/drawable-xxhdpi/checkbox_selected.png
--------------------------------------------------------------------------------
/source/res/drawable-xxhdpi/icon_back_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/source/res/drawable-xxhdpi/icon_back_normal.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/bg_btn_done_clicked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/sample/res/drawable-xxhdpi/bg_btn_done_clicked.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/bg_btn_done_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/sample/res/drawable-xxhdpi/bg_btn_done_normal.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/icon_1_back_clicked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/sample/res/drawable-xxhdpi/icon_1_back_clicked.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/icon_1_back_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/sample/res/drawable-xxhdpi/icon_1_back_normal.png
--------------------------------------------------------------------------------
/source/res/drawable-xxhdpi/icon_back_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/source/res/drawable-xxhdpi/icon_back_selected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/icon_2_delete_clicked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/sample/res/drawable-xxhdpi/icon_2_delete_clicked.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/icon_2_delete_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/sample/res/drawable-xxhdpi/icon_2_delete_normal.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/image_view_loading_default.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habzy/GridImagePicker/HEAD/sample/res/drawable-xxhdpi/image_view_loading_default.9.png
--------------------------------------------------------------------------------
/sample/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #FF33E5B5
5 | #AA33E5B5
6 |
7 |
--------------------------------------------------------------------------------
/source/src/com/jfeinstein/jazzyviewpager/PhotoViewListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Habzy Huang
3 | */
4 | package com.jfeinstein.jazzyviewpager;
5 |
6 | public interface PhotoViewListener {
7 | void onPhotoClicked();
8 | }
9 |
--------------------------------------------------------------------------------
/sample/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/source/res/color/btn_text_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/source/src/com/habzy/image/viewpager/wrap/ViewPagerListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Habzy Huang
3 | */
4 | package com.habzy.image.viewpager.wrap;
5 |
6 | public interface ViewPagerListener {
7 |
8 | void onDone(int currentPosition);
9 |
10 | void onDismiss();
11 | }
12 |
--------------------------------------------------------------------------------
/source/res/drawable/icon_back.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/source/res/values/dimen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 80dp
5 | 80dp
6 | 4dp
7 | 24dp
8 | 24dp
9 |
10 |
--------------------------------------------------------------------------------
/source/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/sample/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/source/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #FFFFFFFF
5 | #4e83a8
6 | #AA4e83a8
7 | #FF33E5B5
8 | #FFAAE5B5
9 | #00000000
10 |
11 |
--------------------------------------------------------------------------------
/sample/res/drawable/icon_1_back.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/source/src/com/habzy/image/models/ItemModel.java:
--------------------------------------------------------------------------------
1 | package com.habzy.image.models;
2 |
3 | import android.graphics.drawable.Drawable;
4 |
5 | public class ItemModel {
6 |
7 | public String mPath;
8 | public String mThumbnail = null;
9 | public boolean isSeleted = false;
10 | public boolean isFunctionItem = false;
11 | public Drawable functionItemDrawale = null;
12 | public int tag;
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/sample/res/drawable/bg_1_done.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/source/res/drawable/on_focus_checkbox.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/sample/res/drawable/icon_1_delete.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/sample/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 | 64dp
9 |
10 |
11 |
--------------------------------------------------------------------------------
/sample/res/drawable/on_1_checkbox.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/sample/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sample/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Picker
5 | Pick Only One(View Only)
6 | Pick From Gallery (Fixed Height, View Only)
7 | Pick Multiple(Wrap Content)
8 | Select Images
9 | Done
10 |
11 |
--------------------------------------------------------------------------------
/source/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/sample/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
16 |
17 |
--------------------------------------------------------------------------------
/sample/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/sample/res/layout/titlebar.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
--------------------------------------------------------------------------------
/source/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-15
15 | android.library=true
16 |
--------------------------------------------------------------------------------
/sample/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-15
15 | android.library.reference.1=../source
16 |
--------------------------------------------------------------------------------
/source/res/layout/bottom_bar.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
15 |
16 |
--------------------------------------------------------------------------------
/source/src/com/habzy/image/picker/ViewPickerListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Habzy Huang
3 | */
4 | package com.habzy.image.picker;
5 |
6 | import com.habzy.image.models.ItemModel;
7 |
8 | public interface ViewPickerListener {
9 |
10 | /**
11 | * When cancel the intent of picking images.
12 | */
13 | void onCanceled();
14 |
15 | /**
16 | * When finish the intent of picking images.
17 | * @param paths The images' paths which are picked.
18 | */
19 | void onDone(String[] paths);
20 |
21 | void onFunctionItemClicked(ItemModel item);
22 |
23 | /**
24 | * When picking images changed, such as delete images.
25 | */
26 | void onImageDataChanged();
27 | }
28 |
--------------------------------------------------------------------------------
/sample/res/layout/gallery.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
--------------------------------------------------------------------------------
/source/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Picker
5 | Settings
6 | Pick image
7 | OK
8 | Has picked the max allow size!
9 |
10 |
11 | - Standard
12 | - Tablet
13 | - CubeIn
14 | - CubeOut
15 | - FlipVertical
16 | - FlipHorizontal
17 | - Stack
18 | - ZoomIn
19 | - ZoomOut
20 | - RotateUp
21 | - RotateDown
22 | - Accordion
23 |
24 |
25 |
--------------------------------------------------------------------------------
/sample/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/source/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/source/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | GridImagePicker
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/sample/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | GridImagePicker-Sample
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/source/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/source/res/layout/image_picker.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
16 |
17 |
18 |
25 |
26 |
--------------------------------------------------------------------------------
/source/res/layout/gallery_item.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
15 |
16 |
25 |
26 |
--------------------------------------------------------------------------------
/source/res/layout/title_bar.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
13 |
21 |
22 |
31 |
32 |
--------------------------------------------------------------------------------
/source/src/com/habzy/image/picker/CustGridView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Habzy Huang
3 | */
4 | package com.habzy.image.picker;
5 |
6 | import android.content.Context;
7 | import android.util.AttributeSet;
8 | import android.widget.GridView;
9 |
10 | public class CustGridView extends GridView {
11 |
12 | private boolean isScrollable = true;
13 |
14 | public CustGridView(Context context, AttributeSet attrs, int defStyle) {
15 | super(context, attrs, defStyle);
16 | }
17 |
18 | public CustGridView(Context context, AttributeSet attrs) {
19 | super(context, attrs);
20 | }
21 |
22 | public CustGridView(Context context) {
23 | super(context);
24 | }
25 |
26 | @Override
27 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
28 | if (isScrollable) {
29 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
30 | } else {
31 | int expandSpec =
32 | MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
33 | super.onMeasure(widthMeasureSpec, expandSpec);
34 | }
35 | }
36 |
37 | public void setSrollable(boolean isScrollable) {
38 | this.isScrollable = isScrollable;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/source/res/layout/view_pager.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
14 |
18 |
19 |
25 |
26 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/sample/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | GridImagePicker
2 | =============
3 |
4 | View & Pick(Select) & Manager Images in GridView and ViewPager.
5 |
6 | Support features:
7 | =============
8 |
9 | >- View & pick(select) images in GridView.
10 | >- View & pick(select) images in ViewPager.
11 | >- Support view & picking image from local or network.
12 | >- Zoom out images when view image in full screen with ViewPager.
13 | >- Delete picked image.
14 | >- Muliple styles' animations when page changed in ViewPager.
15 | >- Customizable for all icons and buttons.
16 | >- Customizable for the NumClumns of GridView and auto-addjust the size of items.
17 | >- Provide taking photo event interface if needed.
18 |
19 | Snapshot
20 | ======
21 |
22 | ###Support display models:
23 | 
24 |
25 | ###View & pick images:
26 | 
27 |
28 | ###View & pick image in ViewPager:
29 |  ==> 
30 |
31 | ###Animation when change page:
32 | 
33 |
34 |
35 | Reference
36 | =============
37 |
38 | [MultipleImagePick](https://github.com/habzy/MultipleImagePick)
39 |
40 | [JazzyViewPager](https://github.com/jfeinstein10/JazzyViewPager)
41 |
42 | Library Dependence
43 | =============
44 |
45 | [Android-Universal-Image-Loader](https://github.com/nostra13/Android-Universal-Image-Loader)
46 |
47 | [PhotoView](https://github.com/habzy/PhotoView)
48 |
49 | [NineOldAndroids](http://nineoldandroids.com/) or [NineOldAndroids-Github](https://github.com/JakeWharton/NineOldAndroids)
50 |
--------------------------------------------------------------------------------
/sample/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
19 |
20 |
29 |
30 |
37 |
38 |
39 |
44 |
45 |
54 |
55 |
62 |
63 |
64 |
69 |
70 |
79 |
80 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/source/src/com/jfeinstein/jazzyviewpager/OutlineContainer.java:
--------------------------------------------------------------------------------
1 | package com.jfeinstein.jazzyviewpager;
2 |
3 | import com.habzy.image.picker.R;
4 | import com.habzy.image.tools.ImageTools;
5 |
6 | import android.content.Context;
7 | import android.graphics.Canvas;
8 | import android.graphics.Paint;
9 | import android.graphics.Paint.Style;
10 | import android.graphics.Rect;
11 | import android.graphics.drawable.Animatable;
12 | import android.util.AttributeSet;
13 | import android.view.animation.AnimationUtils;
14 | import android.view.animation.Interpolator;
15 | import android.widget.FrameLayout;
16 |
17 | public class OutlineContainer extends FrameLayout implements Animatable {
18 |
19 | private Paint mOutlinePaint;
20 |
21 | private boolean mIsRunning = false;
22 | private long mStartTime;
23 | private float mAlpha = 1.0f;
24 | private static final long ANIMATION_DURATION = 500;
25 | private static final long FRAME_DURATION = 1000 / 60;
26 | private final Interpolator mInterpolator = new Interpolator() {
27 | public float getInterpolation(float t) {
28 | t -= 1.0f;
29 | return t * t * t + 1.0f;
30 | }
31 | };
32 |
33 | public OutlineContainer(Context context) {
34 | super(context);
35 | init();
36 | }
37 |
38 | public OutlineContainer(Context context, AttributeSet attrs) {
39 | super(context, attrs);
40 | init();
41 | }
42 |
43 | public OutlineContainer(Context context, AttributeSet attrs, int defStyle) {
44 | super(context, attrs, defStyle);
45 | init();
46 | }
47 |
48 | private void init() {
49 | mOutlinePaint = new Paint();
50 | mOutlinePaint.setAntiAlias(true);
51 | mOutlinePaint.setStrokeWidth(ImageTools.dpToPx(getResources(), 2));
52 | mOutlinePaint.setColor(getResources().getColor(R.color.holo_blue));
53 | mOutlinePaint.setStyle(Style.STROKE);
54 |
55 | int padding = ImageTools.dpToPx(getResources(), 10);
56 | setPadding(padding, padding, padding, padding);
57 | }
58 |
59 | @Override
60 | protected void dispatchDraw(Canvas canvas) {
61 | super.dispatchDraw(canvas);
62 | int offset = ImageTools.dpToPx(getResources(), 5);
63 | if (mOutlinePaint.getColor() != JazzyViewPager.sOutlineColor) {
64 | mOutlinePaint.setColor(JazzyViewPager.sOutlineColor);
65 | }
66 | mOutlinePaint.setAlpha((int) (mAlpha * 255));
67 | Rect rect =
68 | new Rect(offset, offset, getMeasuredWidth() - offset, getMeasuredHeight() - offset);
69 | canvas.drawRect(rect, mOutlinePaint);
70 | }
71 |
72 | public void setOutlineAlpha(float alpha) {
73 | mAlpha = alpha;
74 | }
75 |
76 | @Override
77 | public boolean isRunning() {
78 | return mIsRunning;
79 | }
80 |
81 | @Override
82 | public void start() {
83 | if (mIsRunning)
84 | return;
85 | mIsRunning = true;
86 | mStartTime = AnimationUtils.currentAnimationTimeMillis();
87 | post(mUpdater);
88 | }
89 |
90 | @Override
91 | public void stop() {
92 | if (!mIsRunning)
93 | return;
94 | mIsRunning = false;
95 | }
96 |
97 | private final Runnable mUpdater = new Runnable() {
98 | @Override
99 | public void run() {
100 | long now = AnimationUtils.currentAnimationTimeMillis();
101 | long duration = now - mStartTime;
102 | if (duration >= ANIMATION_DURATION) {
103 | mAlpha = 0.0f;
104 | invalidate();
105 | stop();
106 | return;
107 | } else {
108 | mAlpha = mInterpolator.getInterpolation(1 - duration / (float) ANIMATION_DURATION);
109 | invalidate();
110 | }
111 | postDelayed(mUpdater, FRAME_DURATION);
112 | }
113 | };
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/sample/src/com/habzy/image/picker/sample/ViewPickerActivity.java:
--------------------------------------------------------------------------------
1 | package com.habzy.image.picker.sample;
2 |
3 | import java.util.ArrayList;
4 |
5 | import com.habzy.image.models.ItemModel;
6 | import com.habzy.image.models.ViewParams;
7 | import com.habzy.image.models.ViewParams.ShownStyle;
8 | import com.habzy.image.picker.GridViewPicker;
9 | import com.habzy.image.picker.ViewPickerListener;
10 | import com.habzy.image.tools.ImageTools;
11 |
12 | import android.content.Intent;
13 | import android.content.res.Resources;
14 | import android.os.Bundle;
15 | import android.support.v4.app.FragmentActivity;
16 | import android.util.Log;
17 | import android.view.Window;
18 | import android.widget.LinearLayout;
19 |
20 | public class ViewPickerActivity extends FragmentActivity {
21 | public static final String ACTION_MULTIPLE_PICK =
22 | "com.habzy.image.picker.sample.ACTION_MULTIPLE_PICK";
23 | public static final String ACTION_PICK = "com.habzy.image.picker.sample.ACTION_PICK";
24 |
25 | public static final String PATH_STRING = "all_path";
26 | private static final int ITEM_TAKE_PHOTO_TAG = 1;
27 | private static final String TAG = ViewPickerActivity.class.getSimpleName();
28 |
29 | private GridViewPicker mImagePicker;
30 | private LinearLayout mLayout;
31 |
32 | @Override
33 | public void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | requestWindowFeature(Window.FEATURE_NO_TITLE);
36 | setContentView(R.layout.gallery);
37 |
38 | ViewParams params = new ViewParams(getResources().getDisplayMetrics());
39 | initParams(params);
40 |
41 | mLayout = (LinearLayout) findViewById(R.id.picker_layout);
42 | mImagePicker = new GridViewPicker(mLayout, params, mViewPickerListener);
43 | mImagePicker.initialize(getSupportFragmentManager());
44 |
45 | ArrayList modelList = new ArrayList();
46 | ItemModel item = new ItemModel();
47 | item.isFunctionItem = true;
48 | item.functionItemDrawale = getResources().getDrawable(R.drawable.icon_take_photo);
49 | item.tag = ITEM_TAKE_PHOTO_TAG;
50 | modelList.add(item);
51 | modelList.addAll(ImageTools.getGalleryPhotos(getContentResolver()));
52 | mImagePicker.setImagePath(modelList);
53 | }
54 |
55 | private void initParams(ViewParams params) {
56 | String action = getIntent().getAction();
57 | if (action == null) {
58 | finish();
59 | }
60 | if (action.equalsIgnoreCase(ViewPickerActivity.ACTION_MULTIPLE_PICK)) {
61 | params.setShownStyle(ShownStyle.Pick_Multiple);
62 | } else if (action.equalsIgnoreCase(ViewPickerActivity.ACTION_PICK)) {
63 | params.setShownStyle(ShownStyle.Pick_Single);
64 | }
65 |
66 | Resources res = getResources();
67 | params.setCheckBoxDrawable(res.getDrawable(R.drawable.on_1_checkbox));
68 | params.setLoadingImageDrawable(res.getDrawable(R.drawable.image_view_loading_default));
69 | params.setBtnBackDrawable(res.getDrawable(R.drawable.icon_1_back));
70 | params.setBtnDoneBgDrawable(res.getDrawable(R.drawable.bg_1_done));
71 | params.setTitleSt(res.getString(R.string.pick_title));
72 | params.setDoneSt(res.getString(R.string.btn_done));
73 | params.setBarBgColorOpacity(res.getColor(R.color.bg_1_bar_opacity));
74 | params.setBarBgColorClarity(res.getColor(R.color.bg_1_bar_clarity));
75 | params.setMaxPickSize(20);
76 | }
77 |
78 | ViewPickerListener mViewPickerListener = new ViewPickerListener() {
79 |
80 | @Override
81 | public void onDone(String[] paths) {
82 | Intent data = new Intent().putExtra(PATH_STRING, paths);
83 | setResult(RESULT_OK, data);
84 | finish();
85 | }
86 |
87 | @Override
88 | public void onCanceled() {
89 | finish();
90 | }
91 |
92 | @Override
93 | public void onImageDataChanged() {}
94 |
95 | @Override
96 | public void onFunctionItemClicked(ItemModel item) {
97 | Log.d(TAG, "Fucntion item clicked: " + item.tag);
98 | }
99 |
100 | };
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/source/src/com/habzy/image/tools/ImageTools.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Habzy Huang
3 | */
4 | package com.habzy.image.tools;
5 |
6 | import java.io.File;
7 | import java.util.ArrayList;
8 | import java.util.Collections;
9 |
10 | import android.content.ContentResolver;
11 | import android.content.Context;
12 | import android.content.res.Resources;
13 | import android.database.Cursor;
14 | import android.graphics.Bitmap;
15 | import android.os.Environment;
16 | import android.provider.MediaStore;
17 | import android.util.TypedValue;
18 |
19 | import com.habzy.image.models.ItemModel;
20 | import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
21 | import com.nostra13.universalimageloader.cache.memory.impl.UsingFreqLimitedMemoryCache;
22 | import com.nostra13.universalimageloader.core.DisplayImageOptions;
23 | import com.nostra13.universalimageloader.core.ImageLoader;
24 | import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
25 | import com.nostra13.universalimageloader.core.assist.ImageScaleType;
26 | import com.nostra13.universalimageloader.utils.StorageUtils;
27 |
28 | public class ImageTools {
29 |
30 | private static ImageLoader instance = null;
31 |
32 | public static ImageLoader getImageLoaderInstance(Context context) {
33 | if (null == instance) {
34 | instance = getImageLoader(context);
35 | }
36 | return instance;
37 | }
38 |
39 | private static ImageLoader getImageLoader(Context context) {
40 | ImageLoader imageLoader = null;
41 | try {
42 | String CACHE_DIR =
43 | Environment.getExternalStorageDirectory().getAbsolutePath() + "/.temp_tmp";
44 | new File(CACHE_DIR).mkdirs();
45 |
46 | File cacheDir = StorageUtils.getOwnCacheDirectory(context, CACHE_DIR);
47 |
48 | DisplayImageOptions defaultOptions =
49 | new DisplayImageOptions.Builder().cacheOnDisk(true).cacheInMemory(true)
50 | .imageScaleType(ImageScaleType.EXACTLY)
51 | .bitmapConfig(Bitmap.Config.RGB_565).build();
52 | ImageLoaderConfiguration.Builder builder =
53 | new ImageLoaderConfiguration.Builder(context)
54 | .defaultDisplayImageOptions(defaultOptions).threadPoolSize(5)
55 | .diskCache(new UnlimitedDiscCache(cacheDir))
56 | .memoryCache(new UsingFreqLimitedMemoryCache(1024 * 1024 * 20));
57 |
58 | ImageLoaderConfiguration config = builder.build();
59 | imageLoader = ImageLoader.getInstance();
60 | imageLoader.init(config);
61 |
62 | } catch (Exception e) {
63 |
64 | }
65 | return imageLoader;
66 | }
67 |
68 | public static ArrayList getGalleryPhotos(ContentResolver resolver) {
69 | ArrayList galleryList = new ArrayList();
70 |
71 | try {
72 | final String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID};
73 | final String orderBy = MediaStore.Images.Media._ID;
74 |
75 | Cursor imagecursor =
76 | resolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null,
77 | null, orderBy);
78 |
79 | if (imagecursor != null && imagecursor.getCount() > 0) {
80 |
81 | while (imagecursor.moveToNext()) {
82 | ItemModel item = new ItemModel();
83 |
84 | int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.DATA);
85 |
86 | item.mPath = "file://" + imagecursor.getString(dataColumnIndex);
87 |
88 | galleryList.add(item);
89 | }
90 | }
91 | } catch (Exception e) {
92 | e.printStackTrace();
93 | }
94 |
95 | // show newest photo at beginning of the list
96 | Collections.reverse(galleryList);
97 | return galleryList;
98 | }
99 |
100 | public static int dpToPx(Resources res, int dp) {
101 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
102 | res.getDisplayMetrics());
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/source/src/com/jfeinstein/jazzyviewpager/JazzyPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.jfeinstein.jazzyviewpager;
2 |
3 | import java.util.ArrayList;
4 |
5 | import com.habzy.image.models.ItemModel;
6 | import com.habzy.image.models.ViewParams;
7 | import com.habzy.image.picker.R;
8 | import com.habzy.image.tools.ImageTools;
9 | import com.nostra13.universalimageloader.core.ImageLoader;
10 | import com.nostra13.universalimageloader.core.assist.FailReason;
11 | import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
12 |
13 | import uk.co.senab.photoview.PhotoView;
14 | import uk.co.senab.photoview.PhotoViewAttacher.OnPhotoTapListener;
15 | import android.support.v4.view.PagerAdapter;
16 | import android.view.View;
17 | import android.view.ViewGroup;
18 | import android.view.ViewGroup.LayoutParams;
19 |
20 | public class JazzyPagerAdapter extends PagerAdapter {
21 |
22 | private ImageLoader mImageLoader;
23 | ArrayList mModelList;
24 | private JazzyViewPager mJazzy;
25 | private PhotoViewListener mPhotoViewListener;
26 | private final ViewParams mParams;
27 |
28 | public JazzyPagerAdapter(JazzyViewPager jazzy, ViewParams params) {
29 | mImageLoader = ImageTools.getImageLoaderInstance(jazzy.getContext());
30 | mJazzy = jazzy;
31 | mParams = params;
32 | }
33 |
34 | @Override
35 | public Object instantiateItem(ViewGroup container, final int position) {
36 | final PhotoView photoView = new PhotoView(container.getContext());
37 | photoView.setClickable(true);
38 | photoView.setOnPhotoTapListener(mOnPhotoTapListener);
39 |
40 | mImageLoader.displayImage(mModelList.get(position).mPath, photoView,
41 | new SimpleImageLoadingListener() {
42 | @Override
43 | public void onLoadingStarted(String imageUri, View view) {
44 | if (null != mParams.getLoadingImageDrawable()) {
45 | photoView.setImageDrawable(mParams.getLoadingImageDrawable());
46 | } else {
47 | photoView.setImageResource(R.drawable.no_media);
48 | }
49 | super.onLoadingStarted(imageUri, view);
50 | }
51 |
52 | @Override
53 | public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
54 | if (null != mParams.getLoadingFailedDrawable()) {
55 | photoView.setImageDrawable(mParams.getLoadingFailedDrawable());
56 | } else {
57 | photoView.setImageResource(R.drawable.failed);
58 | }
59 | super.onLoadingFailed(imageUri, view, failReason);
60 | }
61 | });
62 |
63 | container.addView(photoView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
64 | mJazzy.setObjectForPosition(photoView, position);
65 | return photoView;
66 | }
67 |
68 | @Override
69 | public void destroyItem(ViewGroup container, int position, Object obj) {
70 | container.removeView(mJazzy.findViewFromObject(position));
71 | }
72 |
73 | @Override
74 | public int getCount() {
75 | return mModelList.size();
76 | }
77 |
78 | @Override
79 | public int getItemPosition(Object object) {
80 | return POSITION_NONE;
81 | }
82 |
83 | @Override
84 | public boolean isViewFromObject(View view, Object obj) {
85 | if (view instanceof OutlineContainer) {
86 | return ((OutlineContainer) view).getChildAt(0) == obj;
87 | } else {
88 | return view == obj;
89 | }
90 | }
91 |
92 | public void setImagePath(ArrayList galleryPhotos) {
93 | mModelList = galleryPhotos;
94 | }
95 |
96 | /**
97 | * @param photoViewListener the mPhotoViewListener to set
98 | */
99 | public void setPhotoViewListener(PhotoViewListener photoViewListener) {
100 | this.mPhotoViewListener = photoViewListener;
101 | }
102 |
103 | private OnPhotoTapListener mOnPhotoTapListener = new OnPhotoTapListener() {
104 |
105 | @Override
106 | public void onPhotoTap(View arg0, float arg1, float arg2) {
107 | if (null != mPhotoViewListener) {
108 | mPhotoViewListener.onPhotoClicked();
109 | }
110 | }
111 | };
112 | }
113 |
--------------------------------------------------------------------------------
/sample/src/com/habzy/image/picker/sample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.habzy.image.picker.sample;
2 |
3 | import java.util.ArrayList;
4 |
5 | import com.habzy.image.models.ItemModel;
6 | import com.habzy.image.models.ViewParams;
7 | import com.habzy.image.models.ViewParams.ShownStyle;
8 | import com.habzy.image.models.ViewParams.TransitionEffect;
9 | import com.habzy.image.picker.GridViewPicker;
10 | import com.habzy.image.picker.ViewPickerListener;
11 |
12 | import android.app.ActionBar;
13 | import android.app.Activity;
14 | import android.content.Intent;
15 | import android.os.Bundle;
16 | import android.support.v4.app.FragmentActivity;
17 | import android.view.View;
18 | import android.widget.Button;
19 | import android.widget.LinearLayout;
20 |
21 | public class MainActivity extends FragmentActivity {
22 |
23 | private LinearLayout mLayout1;
24 | private LinearLayout mLayout2;
25 | private LinearLayout mLayout3;
26 | private Button mBtnGalleryPick;
27 | private Button mBtnGalleryPickMul;
28 | private Button mBtnGalleryPickMul2;
29 |
30 | /*
31 | * The grid view to manage all images.
32 | */
33 | private GridViewPicker mImagePicker;
34 | /*
35 | * The grid view to manage all images.
36 | */
37 | private GridViewPicker mImagePicker2;
38 |
39 | /*
40 | * The grid view to manage all images.
41 | */
42 | private GridViewPicker mImagePicker3;
43 |
44 | private ActionBar mActionBar;
45 |
46 | @Override
47 | public void onCreate(Bundle savedInstanceState) {
48 | super.onCreate(savedInstanceState);
49 | setContentView(R.layout.activity_main);
50 | mActionBar = getActionBar();
51 | mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
52 | mActionBar.setCustomView(R.layout.titlebar);
53 |
54 | ViewParams params = new ViewParams(getResources().getDisplayMetrics());
55 | initParams(params);
56 |
57 | mLayout1 = (LinearLayout) findViewById(R.id.shown_layout1);
58 | mImagePicker = new GridViewPicker(mLayout1, params, mViewPickerListener);
59 | mImagePicker.initialize(getSupportFragmentManager());
60 |
61 | mLayout2 = (LinearLayout) findViewById(R.id.shown_layout2);
62 | mImagePicker2 = new GridViewPicker(mLayout2, params, mViewPickerListener);
63 | mImagePicker2.initialize(getSupportFragmentManager());
64 |
65 | ViewParams params2 = new ViewParams(getResources().getDisplayMetrics());
66 | initDeltableParams(params2);
67 | mLayout3 = (LinearLayout) findViewById(R.id.shown_layout3);
68 | mImagePicker3 = new GridViewPicker(mLayout3, params2, mViewPickerListener);
69 | mImagePicker3.initialize(getSupportFragmentManager());
70 | init();
71 | }
72 |
73 | private void initParams(ViewParams params) {
74 | ArrayList transitionEffects =
75 | new ArrayList();
76 | transitionEffects.add(ViewParams.TransitionEffect.CubeOut);
77 | transitionEffects.add(ViewParams.TransitionEffect.FlipHorizontal);
78 | transitionEffects.add(ViewParams.TransitionEffect.FlipVertical);
79 |
80 | params.setTransitionEffects(transitionEffects);
81 | params.setShownStyle(ShownStyle.ViewOnly);
82 | params.setNumClumns(5);
83 | params.setLoadingImageDrawable(getResources().getDrawable(
84 | R.drawable.image_view_loading_default));
85 | params.setBtnBackDrawable(getResources().getDrawable(R.drawable.icon_1_back));
86 | params.setDeleteItemDrawable(getResources().getDrawable(R.drawable.icon_1_delete));
87 | params.setBarBgColorOpacity(getResources().getColor(R.color.bg_1_bar_opacity));
88 | params.setBarBgColorClarity(getResources().getColor(R.color.bg_1_bar_clarity));
89 | }
90 |
91 | private void initDeltableParams(ViewParams params) {
92 | ArrayList transitionEffects =
93 | new ArrayList();
94 | transitionEffects.add(ViewParams.TransitionEffect.CubeOut);
95 | transitionEffects.add(ViewParams.TransitionEffect.FlipHorizontal);
96 | transitionEffects.add(ViewParams.TransitionEffect.FlipVertical);
97 |
98 | params.setTransitionEffects(transitionEffects);
99 | params.setShownStyle(ShownStyle.ViewAndDelete);
100 | params.setGridViewScrollEnable(false);
101 | params.setNumClumns(4);
102 | params.setLoadingImageDrawable(getResources().getDrawable(
103 | R.drawable.image_view_loading_default));
104 | params.setBtnBackDrawable(getResources().getDrawable(R.drawable.icon_1_back));
105 | params.setDeleteItemDrawable(getResources().getDrawable(R.drawable.icon_1_delete));
106 | params.setBarBgColorOpacity(getResources().getColor(R.color.bg_1_bar_opacity));
107 | params.setBarBgColorClarity(getResources().getColor(R.color.bg_1_bar_clarity));
108 | }
109 |
110 |
111 | private void init() {
112 |
113 | mBtnGalleryPick = (Button) findViewById(R.id.btnGalleryPick);
114 | mBtnGalleryPick.setOnClickListener(new View.OnClickListener() {
115 | @Override
116 | public void onClick(View v) {
117 | Intent i = new Intent(ViewPickerActivity.ACTION_PICK);
118 | startActivityForResult(i, 100);
119 |
120 | }
121 | });
122 |
123 | mBtnGalleryPickMul = (Button) findViewById(R.id.btnGalleryPickMul);
124 | mBtnGalleryPickMul.setOnClickListener(new View.OnClickListener() {
125 | @Override
126 | public void onClick(View v) {
127 | Intent i = new Intent(ViewPickerActivity.ACTION_MULTIPLE_PICK);
128 | startActivityForResult(i, 200);
129 | }
130 | });
131 |
132 | mBtnGalleryPickMul2 = (Button) findViewById(R.id.btnGalleryPickMul2);
133 | mBtnGalleryPickMul2.setOnClickListener(new View.OnClickListener() {
134 | @Override
135 | public void onClick(View v) {
136 | Intent i = new Intent(ViewPickerActivity.ACTION_MULTIPLE_PICK);
137 | startActivityForResult(i, 300);
138 | }
139 | });
140 |
141 | }
142 |
143 | @Override
144 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
145 | super.onActivityResult(requestCode, resultCode, data);
146 |
147 | if (resultCode == Activity.RESULT_OK) {
148 | String[] paths = data.getStringArrayExtra(ViewPickerActivity.PATH_STRING);
149 | ArrayList dataT = new ArrayList();
150 |
151 | for (String string : paths) {
152 | ItemModel item = new ItemModel();
153 | item.mPath = string;
154 | dataT.add(item);
155 | }
156 | if (requestCode == 100) {
157 | mImagePicker.setImagePath(dataT);
158 | } else if (requestCode == 200) {
159 | mImagePicker2.setImagePath(dataT);
160 | } else {
161 | mImagePicker3.setImagePath(dataT);
162 | }
163 | }
164 | }
165 |
166 | ViewPickerListener mViewPickerListener = new ViewPickerListener() {
167 |
168 | @Override
169 | public void onDone(String[] paths) {}
170 |
171 | @Override
172 | public void onCanceled() {}
173 |
174 |
175 | @Override
176 | public void onImageDataChanged() {}
177 |
178 | @Override
179 | public void onFunctionItemClicked(ItemModel item) {}
180 | };
181 |
182 | }
183 |
--------------------------------------------------------------------------------
/source/src/com/habzy/image/models/ViewParams.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Habzy Huang
3 | */
4 | package com.habzy.image.models;
5 |
6 | import java.util.ArrayList;
7 | import java.util.Random;
8 |
9 | import android.graphics.drawable.Drawable;
10 | import android.util.DisplayMetrics;
11 | import android.util.Log;
12 |
13 | public class ViewParams {
14 |
15 | public final static int DEFAULT_NUM_CLUMNS = 4;
16 | public final static float DEFAULT_ITEM_PADDING_DIP = 4;
17 | public final static int DEFAULT_MAX_PICK_SIZE = 9;
18 |
19 | public enum TransitionEffect {
20 | Standard, //
21 | Tablet, //
22 | CubeIn, // There may be some bugs in the model, need to fix JazzyViewPager.
23 | CubeOut, //
24 | FlipVertical, //
25 | FlipHorizontal, //
26 | Stack, //
27 | ZoomIn, //
28 | ZoomOut, //
29 | RotateUp, //
30 | RotateDown, //
31 | Accordion // I like this one. -- Habzy (:
32 | }
33 |
34 | public enum ShownStyle {
35 | Pick_Multiple, //
36 | Pick_Single, //
37 | ViewOnly, //
38 | ViewAndDelete //
39 | }
40 |
41 | private static final String TAG = ViewParams.class.getSimpleName();
42 | private final static TransitionEffect DEFAULT_TRANSITION_EFFECT = TransitionEffect.Accordion;
43 | private final static ShownStyle DEFAULT_SHOWN_MODEL = ShownStyle.Pick_Multiple;
44 |
45 | private final DisplayMetrics mMetics;
46 |
47 | private int mNumClumns = DEFAULT_NUM_CLUMNS;
48 |
49 | private ShownStyle mShownStyle = DEFAULT_SHOWN_MODEL;
50 | private boolean mIsGridViewScrollEnable = true;
51 |
52 | private Drawable mCheckBoxDrawable = null;
53 | private Drawable mLoadingImageDrawable = null;
54 | private Drawable mLoadingFailedDrawable = null;
55 | private Drawable mDeleteItemDrawable = null;
56 | private Drawable mBtnBackDrawable = null;
57 | private Drawable mBtnDoneBgDrawable = null;
58 | private float mItemPaddingDip = DEFAULT_ITEM_PADDING_DIP;
59 | private ArrayList mTransitionEffects =
60 | new ArrayList();
61 | private String mTitleSt = null;
62 | private String mDoneSt = null;
63 | private int mMaxPickSize = DEFAULT_MAX_PICK_SIZE;
64 | private String mToastForReachingMax = null;
65 | private int mBarBgColorOpacity = -1;
66 | private int mBarBgColorClarity = -1;
67 |
68 | public ViewParams(DisplayMetrics metrics) {
69 | this.mMetics = metrics;
70 | mTransitionEffects.add(DEFAULT_TRANSITION_EFFECT);
71 | }
72 |
73 | public int getNumClumns() {
74 | return mNumClumns;
75 | }
76 |
77 | public void setNumClumns(int numClumns) {
78 | if (numClumns > 0) {
79 | this.mNumClumns = numClumns;
80 | } else {
81 | Log.w(TAG, numClumns + " numClumns is not supported");
82 | }
83 | }
84 |
85 | /**
86 | * @return the mCheckBoxDrawable
87 | */
88 | public Drawable getCheckBoxDrawable() {
89 | return mCheckBoxDrawable;
90 | }
91 |
92 | /**
93 | * @param checkBoxDrawable the mCheckBoxDrawable to set
94 | */
95 | public void setCheckBoxDrawable(Drawable checkBoxDrawable) {
96 | this.mCheckBoxDrawable = checkBoxDrawable;
97 | }
98 |
99 | /**
100 | * @return the mLoadingImageDrawable
101 | */
102 | public Drawable getLoadingImageDrawable() {
103 | return mLoadingImageDrawable;
104 | }
105 |
106 | /**
107 | * @param loadingImageDrawable the mLoadingImageDrawable to set
108 | */
109 | public void setLoadingImageDrawable(Drawable loadingImageDrawable) {
110 | this.mLoadingImageDrawable = loadingImageDrawable;
111 | }
112 |
113 | /**
114 | * @return the density of this device.
115 | */
116 | public float getDensity() {
117 | return mMetics.density;
118 | }
119 |
120 | /**
121 | * @return the mItemPaddingDip
122 | */
123 | public float getItemPaddingDip() {
124 | return mItemPaddingDip;
125 | }
126 |
127 | /**
128 | * @param transitionEffects copy values to the mTransitionEffects
129 | */
130 | public void setTransitionEffects(ArrayList transitionEffects) {
131 | if (!transitionEffects.isEmpty()) {
132 | this.mTransitionEffects.clear();
133 | this.mTransitionEffects.addAll(transitionEffects);
134 | } else {
135 | Log.w(TAG, "Transition Effects can not be empty");
136 | }
137 | }
138 |
139 | /**
140 | * @return the random value in mTransitionEffects
141 | */
142 | public TransitionEffect getTransitionEffect() {
143 | int effectPosition = new Random().nextInt(mTransitionEffects.size());
144 | return mTransitionEffects.get(effectPosition);
145 | }
146 |
147 | /**
148 | * @return the mShownStyle
149 | */
150 | public ShownStyle getShownStyle() {
151 | return mShownStyle;
152 | }
153 |
154 | /**
155 | * @param shownStyle the mShownStyle to set
156 | */
157 | public void setShownStyle(ShownStyle shownStyle) {
158 | this.mShownStyle = shownStyle;
159 | }
160 |
161 | /**
162 | * @return the mDeleteItemDrawable
163 | */
164 | public Drawable getDeleteItemDrawable() {
165 | return mDeleteItemDrawable;
166 | }
167 |
168 | /**
169 | * @param deleteItemDrawable the mDeleteItemDrawable to set
170 | */
171 | public void setDeleteItemDrawable(Drawable deleteItemDrawable) {
172 | this.mDeleteItemDrawable = deleteItemDrawable;
173 | }
174 |
175 | public String getTitleSt() {
176 | return mTitleSt;
177 | }
178 |
179 | public void setTitleSt(String titleSt) {
180 | this.mTitleSt = titleSt;
181 | }
182 |
183 | public int getMaxPickSize() {
184 | return mMaxPickSize;
185 | }
186 |
187 | public void setMaxPickSize(int maxPickSize) {
188 | this.mMaxPickSize = maxPickSize;
189 | }
190 |
191 | public String getToastForReachingMax() {
192 | return mToastForReachingMax;
193 | }
194 |
195 | public void setToastForReachingMax(String toastForReachingMax) {
196 | this.mToastForReachingMax = toastForReachingMax;
197 | }
198 |
199 | public int getBarBgColorOpacity() {
200 | return mBarBgColorOpacity;
201 | }
202 |
203 | public void setBarBgColorOpacity(int barBgColorOpacity) {
204 | this.mBarBgColorOpacity = barBgColorOpacity;
205 | }
206 |
207 | /**
208 | * @return the mBarBgColorClarity
209 | */
210 | public int getBarBgColorClarity() {
211 | return mBarBgColorClarity;
212 | }
213 |
214 | /**
215 | * @param barBgColorClarity the mBarBgColorClarity to set
216 | */
217 | public void setBarBgColorClarity(int barBgColorClarity) {
218 | this.mBarBgColorClarity = barBgColorClarity;
219 | }
220 |
221 | /**
222 | * @return the mBtnBackDrawable
223 | */
224 | public Drawable getBtnBackDrawable() {
225 | return mBtnBackDrawable;
226 | }
227 |
228 | /**
229 | * @param btnBackDrawable the mBtnBackDrawable to set
230 | */
231 | public void setBtnBackDrawable(Drawable btnBackDrawable) {
232 | this.mBtnBackDrawable = btnBackDrawable;
233 | }
234 |
235 | /**
236 | * @return the mBtnDoneBgDrawable
237 | */
238 | public Drawable getBtnDoneBgDrawable() {
239 | return mBtnDoneBgDrawable;
240 | }
241 |
242 | /**
243 | * @param btnDoneBgDrawable the mBtnDoneBgDrawable to set
244 | */
245 | public void setBtnDoneBgDrawable(Drawable btnDoneBgDrawable) {
246 | this.mBtnDoneBgDrawable = btnDoneBgDrawable;
247 | }
248 |
249 | /**
250 | * @return the mDoneSt
251 | */
252 | public String getDoneSt() {
253 | return mDoneSt;
254 | }
255 |
256 | /**
257 | * @param doneSt the mDoneSt to set
258 | */
259 | public void setDoneSt(String doneSt) {
260 | this.mDoneSt = doneSt;
261 | }
262 |
263 | /**
264 | * @return the mIsGridViewScrollEnable
265 | */
266 | public boolean isGridViewScrollEnable() {
267 | return mIsGridViewScrollEnable;
268 | }
269 |
270 | /**
271 | * @param isGridViewScrollEnable the mIsGridViewScrollEnable to set
272 | */
273 | public void setGridViewScrollEnable(boolean isGridViewScrollEnable) {
274 | this.mIsGridViewScrollEnable = isGridViewScrollEnable;
275 | }
276 |
277 | public Drawable getLoadingFailedDrawable() {
278 | return mLoadingFailedDrawable;
279 | }
280 |
281 | public void setLoadingFailedDrawable(Drawable loadingFailedDrawable) {
282 | this.mLoadingFailedDrawable = loadingFailedDrawable;
283 | }
284 |
285 | }
286 |
--------------------------------------------------------------------------------
/source/src/com/habzy/image/picker/GalleryAdapter.java:
--------------------------------------------------------------------------------
1 | package com.habzy.image.picker;
2 |
3 | import java.util.ArrayList;
4 |
5 | import android.annotation.SuppressLint;
6 | import android.content.Context;
7 | import android.graphics.drawable.Drawable;
8 | import android.util.Log;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.View.OnClickListener;
12 | import android.view.ViewGroup;
13 | import android.view.ViewGroup.LayoutParams;
14 | import android.widget.BaseAdapter;
15 | import android.widget.ImageView;
16 | import android.widget.Toast;
17 |
18 | import com.habzy.image.models.ItemModel;
19 | import com.habzy.image.models.ViewParams;
20 | import com.habzy.image.models.ViewParams.ShownStyle;
21 | import com.nostra13.universalimageloader.core.ImageLoader;
22 | import com.nostra13.universalimageloader.core.assist.FailReason;
23 | import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
24 |
25 | public class GalleryAdapter extends BaseAdapter {
26 |
27 | private static final String TAG = GalleryAdapter.class.getName();
28 |
29 | private final ViewParams mParams;
30 | private final AdpterEventListener mEventListener;
31 |
32 | private ArrayList data = new ArrayList();
33 | private LayoutInflater mInfalter;
34 | private ImageLoader mImageLoader;
35 |
36 | public GalleryAdapter(Context context, ImageLoader imageLoader, ViewParams params,
37 | AdpterEventListener eventListener) {
38 | mInfalter = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
39 | this.mImageLoader = imageLoader;
40 | this.mParams = params;
41 | this.mEventListener = eventListener;
42 | }
43 |
44 | @Override
45 | public int getCount() {
46 | return data.size();
47 | }
48 |
49 | @Override
50 | public ItemModel getItem(int position) {
51 | return data.get(position);
52 | }
53 |
54 | @Override
55 | public long getItemId(int position) {
56 | return position;
57 | }
58 |
59 | public void selectAll(boolean selection) {
60 | for (int i = 0; i < data.size(); i++) {
61 | data.get(i).isSeleted = selection;
62 |
63 | }
64 | notifyDataSetChanged();
65 | }
66 |
67 | public boolean isAllSelected() {
68 | boolean isAllSelected = true;
69 |
70 | for (int i = 0; i < data.size(); i++) {
71 | if (!data.get(i).isSeleted) {
72 | isAllSelected = false;
73 | break;
74 | }
75 | }
76 |
77 | return isAllSelected;
78 | }
79 |
80 | public boolean isAnySelected() {
81 | boolean isAnySelected = false;
82 |
83 | for (int i = 0; i < data.size(); i++) {
84 | if (data.get(i).isSeleted) {
85 | isAnySelected = true;
86 | break;
87 | }
88 | }
89 |
90 | return isAnySelected;
91 | }
92 |
93 | public ArrayList getSelected() {
94 | ArrayList dataT = new ArrayList();
95 |
96 | for (int i = 0; i < data.size(); i++) {
97 | if (data.get(i).isSeleted) {
98 | dataT.add(data.get(i));
99 | }
100 | }
101 |
102 | return dataT;
103 | }
104 |
105 | public void addAll(ArrayList files) {
106 |
107 | try {
108 | this.data.clear();
109 | this.data.addAll(files);
110 |
111 | } catch (Exception e) {
112 | e.printStackTrace();
113 | }
114 |
115 | notifyDataSetChanged();
116 | }
117 |
118 | @SuppressLint("InflateParams")
119 | @Override
120 | public View getView(int position, View convertView, ViewGroup parent) {
121 |
122 | final ViewHolder holder;
123 | if (convertView == null) {
124 | convertView = mInfalter.inflate(R.layout.gallery_item, null);
125 | holder = new ViewHolder();
126 | holder.imgQueue = (ImageView) convertView.findViewById(R.id.imgQueue);
127 | holder.imgCheckBox = (ImageView) convertView.findViewById(R.id.imgQueueMultiSelected);
128 |
129 | convertView.setTag(holder);
130 | } else {
131 | holder = (ViewHolder) convertView.getTag();
132 | }
133 |
134 | LayoutParams params = holder.imgQueue.getLayoutParams();
135 | int parent_width = parent.getWidth();
136 | int item_padding_pix = (int) (mParams.getDensity() * mParams.getItemPaddingDip());
137 | params.width = parent_width / mParams.getNumClumns() - 2 * item_padding_pix;
138 | params.height = params.width;
139 | holder.imgQueue.setLayoutParams(params);
140 |
141 | if (mParams.getCheckBoxDrawable() != null) {
142 | Drawable cloneDrawable = mParams.getCheckBoxDrawable().getConstantState().newDrawable();
143 | holder.imgCheckBox.setImageDrawable(cloneDrawable);
144 | }
145 | if (mParams.getShownStyle() == ShownStyle.Pick_Multiple) {
146 | holder.imgCheckBox.setOnClickListener(mCheckboxListener);
147 | holder.imgCheckBox.setTag(position);
148 | holder.imgCheckBox.setVisibility(View.VISIBLE);
149 | } else {
150 | holder.imgCheckBox.setVisibility(View.GONE);
151 | }
152 |
153 | holder.imgQueue.setTag(position);
154 | try {
155 | mImageLoader.cancelDisplayTask(holder.imgQueue);
156 | if (data.get(position).isFunctionItem) {
157 | holder.imgCheckBox.setVisibility(View.GONE);
158 | if (null != data.get(position).functionItemDrawale) {
159 | holder.imgQueue.setImageDrawable(data.get(position).functionItemDrawale);
160 | } else {
161 | holder.imgQueue.setImageResource(R.drawable.take_photo);
162 | }
163 | } else {
164 | String path = null;
165 | if (null != data.get(position).mThumbnail) {
166 | path = data.get(position).mThumbnail;
167 | } else {
168 | path = data.get(position).mPath;
169 | }
170 | mImageLoader.displayImage(path, holder.imgQueue, new SimpleImageLoadingListener() {
171 | @Override
172 | public void onLoadingStarted(String imageUri, View view) {
173 | if (null != mParams.getLoadingImageDrawable()) {
174 | holder.imgQueue.setImageDrawable(mParams.getLoadingImageDrawable());
175 | } else {
176 | holder.imgQueue.setImageResource(R.drawable.no_media);
177 | }
178 | super.onLoadingStarted(imageUri, view);
179 | }
180 |
181 | @Override
182 | public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
183 | if (null != mParams.getLoadingFailedDrawable()) {
184 | holder.imgQueue.setImageDrawable(mParams.getLoadingFailedDrawable());
185 | } else {
186 | holder.imgQueue.setImageResource(R.drawable.failed);
187 | }
188 | super.onLoadingFailed(imageUri, view, failReason);
189 | }
190 | });
191 |
192 | if (mParams.getShownStyle() == ShownStyle.Pick_Multiple) {
193 | holder.imgCheckBox.setSelected(data.get(position).isSeleted);
194 | }
195 | }
196 |
197 | } catch (Exception e) {
198 | Log.e(TAG, e.getMessage());
199 | e.printStackTrace();
200 | }
201 | return convertView;
202 | }
203 |
204 | public class ViewHolder {
205 | ImageView imgQueue;
206 | ImageView imgCheckBox;
207 | }
208 |
209 | public void clearCache() {
210 | mImageLoader.clearDiskCache();
211 | mImageLoader.clearMemoryCache();
212 | }
213 |
214 | public void clear() {
215 | data.clear();
216 | notifyDataSetChanged();
217 | }
218 |
219 | private OnClickListener mCheckboxListener = new OnClickListener() {
220 |
221 | @Override
222 | public void onClick(View v) {
223 | int position = (Integer) v.getTag();
224 | if (data.get(position).isSeleted) {
225 | data.get(position).isSeleted = false;
226 | } else {
227 | if (getSelected().size() >= mParams.getMaxPickSize()) {
228 | if (null != mParams.getToastForReachingMax()) {
229 | Toast.makeText(v.getContext(), mParams.getToastForReachingMax(),
230 | Toast.LENGTH_SHORT).show();
231 | } else {
232 | Toast.makeText(v.getContext(), R.string.reached_max_size,
233 | Toast.LENGTH_SHORT).show();
234 | }
235 | return;
236 | }
237 | data.get(position).isSeleted = true;
238 | }
239 |
240 | v.setSelected(data.get(position).isSeleted);
241 | mEventListener.onItemSelectedStatusChange(position, data.get(position).isSeleted);
242 | }
243 | };
244 |
245 | public void updateStatus(int currentPosition, boolean isSelected) {
246 | data.get(currentPosition).isSeleted = isSelected;
247 | notifyDataSetChanged();
248 | }
249 |
250 | interface AdpterEventListener {
251 | void onItemSelectedStatusChange(int position, boolean isSelected);
252 | }
253 |
254 | }
255 |
--------------------------------------------------------------------------------
/source/src/com/habzy/image/viewpager/wrap/ViewPagerDialogFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Habzy Huang
3 | */
4 | package com.habzy.image.viewpager.wrap;
5 |
6 | import java.util.ArrayList;
7 |
8 | import com.habzy.image.models.ItemModel;
9 | import com.habzy.image.models.ViewParams;
10 | import com.habzy.image.models.ViewParams.ShownStyle;
11 | import com.habzy.image.picker.R;
12 | import com.jfeinstein.jazzyviewpager.JazzyViewPager;
13 | import com.jfeinstein.jazzyviewpager.PhotoViewListener;
14 |
15 | import android.annotation.SuppressLint;
16 | import android.content.DialogInterface;
17 | import android.os.Bundle;
18 | import android.support.annotation.Nullable;
19 | import android.support.v4.app.DialogFragment;
20 | import android.support.v4.view.ViewPager.OnPageChangeListener;
21 | import android.util.Log;
22 | import android.view.LayoutInflater;
23 | import android.view.View;
24 | import android.view.View.OnClickListener;
25 | import android.view.ViewGroup;
26 | import android.widget.Button;
27 | import android.widget.ImageView;
28 | import android.widget.RelativeLayout;
29 | import android.widget.TextView;
30 | import android.widget.Toast;
31 |
32 | public class ViewPagerDialogFragment extends DialogFragment {
33 |
34 | private static final String TAG = ViewPagerDialogFragment.class.getSimpleName();
35 | private JazzyViewPager mJazzy;
36 | private int mCurrentItem;
37 | private ArrayList mModelsList = new ArrayList();
38 | private ViewPagerListener mViewPagerEventListener;
39 | private RelativeLayout mPagerTitleBar;
40 | private RelativeLayout mPagerBottomBar;
41 | private Button mBtnBack;
42 | private TextView mTitle;
43 | private Button mBtnDone;
44 | private ImageView mBottonIcon;
45 | private ViewParams mParams;
46 | private boolean isFullScreen = false;
47 |
48 | public ViewPagerDialogFragment(ArrayList modelsList, ViewParams params,
49 | int currentItem) {
50 | mModelsList.addAll(modelsList);
51 | mCurrentItem = currentItem;
52 | removeFunctionItems();
53 | mParams = params;
54 | }
55 |
56 | private void removeFunctionItems() {
57 | for (int i = 0; i < mModelsList.size(); i++) {
58 | if (mModelsList.get(i).isFunctionItem) {
59 | if (mCurrentItem > i) {
60 | mCurrentItem = mCurrentItem - 1;
61 | }
62 | mModelsList.remove(i);
63 | i--;
64 | }
65 | }
66 | }
67 |
68 | @SuppressLint("InflateParams")
69 | @Override
70 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
71 | @Nullable Bundle savedInstanceState) {
72 | View view_pager = inflater.inflate(R.layout.view_pager, null);
73 | mJazzy = (JazzyViewPager) view_pager.findViewById(R.id.jazzy_pager);
74 | mPagerTitleBar = (RelativeLayout) view_pager.findViewById(R.id.pager_title_bar);
75 | mPagerBottomBar = (RelativeLayout) view_pager.findViewById(R.id.pager_bottom_bar);
76 |
77 | initViews();
78 |
79 | return view_pager;
80 | }
81 |
82 | private void initViews() {
83 | mJazzy.setImagePath(mModelsList, mParams);
84 | mJazzy.setCurrentItem(mCurrentItem);
85 | mJazzy.setPageMargin(0);
86 |
87 | mBtnBack = (Button) mPagerTitleBar.findViewById(R.id.picker_back);
88 | mBtnDone = (Button) mPagerTitleBar.findViewById(R.id.picker_done);
89 | mTitle = (TextView) (mPagerTitleBar.findViewById(R.id.picker_title));
90 | mBottonIcon = (ImageView) mPagerBottomBar.findViewById(R.id.bottom_icon);
91 |
92 | mJazzy.setOnPageChangeListener(mOnPageChangeListener);
93 | mJazzy.setPhotoViewListener(mPhotoViewListener);
94 | mBtnBack.setOnClickListener(mOnBackClickListener);
95 | mBtnDone.setOnClickListener(mOnDoneClickListener);
96 |
97 | mJazzy.setTransitionEffect(mParams.getTransitionEffect());
98 | if (-1 != mParams.getBarBgColorClarity()) {
99 | mPagerTitleBar.setBackgroundColor(mParams.getBarBgColorClarity());
100 | mPagerBottomBar.setBackgroundColor(mParams.getBarBgColorClarity());
101 | } else {
102 | mPagerTitleBar.setBackgroundResource(R.color.bg_bar_clarity);
103 | mPagerBottomBar.setBackgroundResource(R.color.bg_bar_clarity);
104 | }
105 |
106 | updateTitle();
107 |
108 | if (null != mParams.getBtnBackDrawable()) {
109 | mBtnBack.setBackgroundDrawable(mParams.getBtnBackDrawable());
110 | } else {
111 | mBtnBack.setBackgroundResource(R.drawable.icon_back);
112 | }
113 | if (null != mParams.getBtnDoneBgDrawable()) {
114 | mBtnDone.setBackgroundDrawable(mParams.getBtnDoneBgDrawable());
115 | } else {
116 | mBtnDone.setBackgroundResource(R.color.clarity);
117 | }
118 |
119 | switch (mParams.getShownStyle()) {
120 | case Pick_Multiple:
121 | mBottonIcon.setSelected(mModelsList.get(mCurrentItem).isSeleted);
122 | mBottonIcon.setOnClickListener(mOnCheckBoxClickedListener);
123 | if (mParams.getCheckBoxDrawable() != null) {
124 | mBottonIcon.setImageDrawable(mParams.getCheckBoxDrawable());
125 | }
126 | mPagerBottomBar.setVisibility(View.VISIBLE);
127 | break;
128 | case Pick_Single:
129 | mPagerBottomBar.setVisibility(View.GONE);
130 | break;
131 | case ViewOnly:
132 | mBtnDone.setVisibility(View.GONE);
133 | mPagerBottomBar.setVisibility(View.GONE);
134 | break;
135 | case ViewAndDelete:
136 | mBtnDone.setVisibility(View.GONE);
137 | mBottonIcon.setImageResource(R.drawable.icon_delete);
138 | mBottonIcon.setOnClickListener(mOnDeleteClickedListener);
139 | if (mParams.getDeleteItemDrawable() != null) {
140 | mBottonIcon.setImageDrawable(mParams.getDeleteItemDrawable());
141 | }
142 | mPagerBottomBar.setVisibility(View.VISIBLE);
143 | break;
144 | default:
145 | break;
146 | }
147 | }
148 |
149 | private void updateTitle() {
150 | mTitle.setText("" + (mCurrentItem + 1) + "/" + mModelsList.size());
151 | String doneSt = null;
152 | if (null != mParams.getDoneSt()) {
153 | doneSt = mParams.getDoneSt();
154 | } else {
155 | doneSt = mJazzy.getResources().getString(R.string.done);
156 | }
157 | switch (mParams.getShownStyle()) {
158 | case Pick_Multiple:
159 | mBtnDone.setText(doneSt + "(" + getSelectedSize() + "/" + mParams.getMaxPickSize()
160 | + ")");
161 | break;
162 | default:
163 | mBtnDone.setText(doneSt);
164 | break;
165 | }
166 | }
167 |
168 | private void fullScreen() {
169 | isFullScreen = !isFullScreen;
170 | if (isFullScreen) {
171 | mPagerTitleBar.setVisibility(View.GONE);
172 | mPagerBottomBar.setVisibility(View.GONE);
173 | } else {
174 | mPagerTitleBar.setVisibility(View.VISIBLE);
175 | switch (mParams.getShownStyle()) {
176 | case Pick_Multiple:
177 | mPagerBottomBar.setVisibility(View.VISIBLE);
178 | break;
179 | case Pick_Single:
180 | mPagerBottomBar.setVisibility(View.GONE);
181 | break;
182 | case ViewOnly:
183 | mPagerBottomBar.setVisibility(View.GONE);
184 | break;
185 | case ViewAndDelete:
186 | mPagerBottomBar.setVisibility(View.VISIBLE);
187 | break;
188 | default:
189 | break;
190 | }
191 | }
192 | }
193 |
194 | private OnClickListener mOnBackClickListener = new OnClickListener() {
195 |
196 | @Override
197 | public void onClick(View v) {
198 | mViewPagerEventListener.onDismiss();
199 | ViewPagerDialogFragment.this.dismiss();
200 | }
201 | };
202 |
203 | private OnClickListener mOnDoneClickListener = new OnClickListener() {
204 |
205 | @Override
206 | public void onClick(View v) {
207 | if (ShownStyle.Pick_Single == mParams.getShownStyle()) {
208 | mModelsList.get(mCurrentItem).isSeleted = true;
209 | }
210 | mViewPagerEventListener.onDone(mCurrentItem);
211 | ViewPagerDialogFragment.this.dismiss();
212 | }
213 | };
214 |
215 | private OnClickListener mOnCheckBoxClickedListener = new OnClickListener() {
216 |
217 | @Override
218 | public void onClick(View v) {
219 | int position = mJazzy.getCurrentItem();
220 | boolean isSelected = mModelsList.get(position).isSeleted;
221 | if (!isSelected && getSelectedSize() >= mParams.getMaxPickSize()) {
222 | if (null != mParams.getToastForReachingMax()) {
223 | Toast.makeText(v.getContext(), mParams.getToastForReachingMax(),
224 | Toast.LENGTH_SHORT).show();
225 | } else {
226 | Toast.makeText(v.getContext(), R.string.reached_max_size, Toast.LENGTH_SHORT)
227 | .show();
228 | }
229 | return;
230 | }
231 | mBottonIcon.setSelected(!isSelected);
232 | mModelsList.get(position).isSeleted = !isSelected;
233 | updateTitle();
234 | }
235 |
236 | };
237 |
238 | private int getSelectedSize() {
239 | int size = 0;
240 | for (int i = 0; i < mModelsList.size(); i++) {
241 | if (mModelsList.get(i).isSeleted) {
242 | size = size + 1;
243 | }
244 | }
245 | return size;
246 | }
247 |
248 | private OnClickListener mOnDeleteClickedListener = new OnClickListener() {
249 |
250 | @Override
251 | public void onClick(View v) {
252 | int position = mJazzy.getCurrentItem();
253 | mModelsList.get(position).isSeleted = true;
254 | if (mModelsList.size() == 1) {
255 | mModelsList.remove(position);
256 | mBtnBack.performClick();
257 | } else {
258 | mModelsList.remove(position);
259 | mJazzy.notifyChange();
260 | updateTitle();
261 | }
262 | }
263 |
264 | };
265 |
266 | private OnPageChangeListener mOnPageChangeListener = new OnPageChangeListener() {
267 |
268 | @Override
269 | public void onPageSelected(int position) {
270 | mCurrentItem = position;
271 | boolean isSelected = mModelsList.get(position).isSeleted;
272 | mBottonIcon.setSelected(isSelected);
273 | updateTitle();
274 | }
275 |
276 | @Override
277 | public void onPageScrolled(int arg0, float arg1, int arg2) {}
278 |
279 | @Override
280 | public void onPageScrollStateChanged(int arg0) {}
281 | };
282 |
283 | private PhotoViewListener mPhotoViewListener = new PhotoViewListener() {
284 |
285 | @Override
286 | public void onPhotoClicked() {
287 | Log.d(TAG, "=======FullScreen");
288 | fullScreen();
289 | }
290 | };
291 |
292 | public void setOnEventListener(ViewPagerListener viewPagerEventListener) {
293 | mViewPagerEventListener = viewPagerEventListener;
294 | }
295 |
296 | @Override
297 | public void onDismiss(DialogInterface dialog) {
298 | mViewPagerEventListener.onDismiss();
299 | super.onDismiss(dialog);
300 | }
301 |
302 | }
303 |
--------------------------------------------------------------------------------
/source/src/com/habzy/image/picker/GridViewPicker.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Habzy Huang
3 | */
4 | package com.habzy.image.picker;
5 |
6 | import java.util.ArrayList;
7 |
8 | import com.habzy.image.models.ItemModel;
9 | import com.habzy.image.models.ViewParams;
10 | import com.habzy.image.models.ViewParams.ShownStyle;
11 | import com.habzy.image.picker.GalleryAdapter.AdpterEventListener;
12 | import com.habzy.image.tools.ImageTools;
13 | import com.habzy.image.viewpager.wrap.ViewPagerListener;
14 | import com.habzy.image.viewpager.wrap.ViewPagerDialogFragment;
15 | import com.nostra13.universalimageloader.core.ImageLoader;
16 | import com.nostra13.universalimageloader.core.listener.PauseOnScrollListener;
17 | import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
18 |
19 | import android.annotation.SuppressLint;
20 | import android.app.DialogFragment;
21 | import android.content.Context;
22 | import android.os.Handler;
23 | import android.os.Looper;
24 | import android.support.v4.app.FragmentManager;
25 | import android.view.LayoutInflater;
26 | import android.view.MotionEvent;
27 | import android.view.View;
28 | import android.view.View.OnClickListener;
29 | import android.view.View.OnTouchListener;
30 | import android.view.ViewGroup;
31 | import android.widget.AdapterView;
32 | import android.widget.Button;
33 | import android.widget.ImageView;
34 | import android.widget.LinearLayout;
35 | import android.widget.TextView;
36 |
37 | public class GridViewPicker {
38 |
39 | protected static final String TAG = GridViewPicker.class.getName();
40 | private LayoutInflater mInfalter;
41 | private ViewGroup mTitleBar;
42 |
43 | private View mImagePicker;
44 | private CustGridView mGridGallery;
45 | private GalleryAdapter mAdapter;
46 | private ImageView mImgNoMedia;
47 |
48 | private ViewParams mParams;
49 |
50 | private Handler mHandler;
51 | private Context mContext;
52 |
53 | private Button mBtnDone;
54 | private LinearLayout mParentLayout;
55 | private ViewPickerListener mListener;
56 | private Button mBtnBack;
57 |
58 | private FragmentManager mFragmentManager; // Required
59 | private ImageLoader mImageLoader;
60 | private ArrayList mModelsList;
61 |
62 | private OnTouchListener mOnTouchListener;
63 |
64 | /**
65 | * @param parentView
66 | */
67 | public GridViewPicker(LinearLayout parentView, ViewParams params, ViewPickerListener listener) {
68 | mParentLayout = parentView;
69 | mParams = params;
70 | mListener = listener;
71 | mContext = parentView.getContext();
72 | mHandler = new Handler();
73 | }
74 |
75 | @SuppressLint("InflateParams")
76 | public void initialize(FragmentManager manager) {
77 | mFragmentManager = manager;
78 |
79 | mInfalter = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
80 | mTitleBar = (ViewGroup) mInfalter.inflate(R.layout.title_bar, null);
81 | mImagePicker = (View) mInfalter.inflate(R.layout.image_picker, null);
82 |
83 | init();
84 | mParentLayout.addView(mTitleBar);
85 | mParentLayout.addView(mImagePicker);
86 | updateViews();
87 | }
88 |
89 | public void setOnTouchListener(OnTouchListener listener) {
90 | mOnTouchListener = listener;
91 | }
92 |
93 | public void setImagePath(final ArrayList modelsList) {
94 | mModelsList = modelsList;
95 | new Thread() {
96 | // TODO Move to thread pools.
97 | @Override
98 | public void run() {
99 | Looper.prepare();
100 | mHandler.post(new Runnable() {
101 |
102 | @Override
103 | public void run() {
104 | if (checkImageStatus()) {
105 | mAdapter.clear();
106 | } else {
107 | mAdapter.addAll(mModelsList);
108 | }
109 | }
110 | });
111 | Looper.loop();
112 | };
113 |
114 | }.start();
115 | }
116 |
117 | private void init() {
118 | OnTouchListener touchListener = new OnTouchListener() {
119 | @Override
120 | public boolean onTouch(View v, MotionEvent event) {
121 | if (mOnTouchListener != null) {
122 | mOnTouchListener.onTouch(v, event);
123 | }
124 | return false;
125 | }
126 | };
127 |
128 | mGridGallery = (CustGridView) mImagePicker.findViewById(R.id.gridGallery);
129 | mGridGallery.setOnTouchListener(touchListener);
130 | mImgNoMedia = (ImageView) mImagePicker.findViewById(R.id.imgNoMedia);
131 | mImgNoMedia.setOnTouchListener(touchListener);
132 |
133 | mBtnDone = (Button) mTitleBar.findViewById(R.id.picker_done);
134 | mBtnDone.setOnClickListener(mDoneClickListener);
135 |
136 | mBtnBack = (Button) mTitleBar.findViewById(R.id.picker_back);
137 | mBtnBack.setOnClickListener(mBackClickListener);
138 | }
139 |
140 | private void updateViews() {
141 | mImageLoader = ImageTools.getImageLoaderInstance(mContext);
142 |
143 | mAdapter = new GalleryAdapter(mContext, mImageLoader, mParams, mAdapterEventListener);
144 | PauseOnScrollListener listener = new PauseOnScrollListener(mImageLoader, true, true);
145 | mGridGallery.setOnScrollListener(listener);
146 | mGridGallery.setOnItemClickListener(mItemClickListener);
147 | mGridGallery.setNumColumns(mParams.getNumClumns());
148 |
149 | mGridGallery.setSrollable(mParams.isGridViewScrollEnable());
150 |
151 | switch (mParams.getShownStyle()) {
152 | case Pick_Single:
153 | mBtnDone.setVisibility(View.GONE);
154 | mGridGallery.setFastScrollEnabled(true);
155 | // Go on whit multiple setting.
156 | case Pick_Multiple:
157 | mTitleBar.setVisibility(View.VISIBLE);
158 | if (null != mParams.getTitleSt()) {
159 | TextView title = (TextView) (mTitleBar.findViewById(R.id.picker_title));
160 | title.setText(mParams.getTitleSt());
161 | }
162 | if (-1 != mParams.getBarBgColorOpacity()) {
163 | mTitleBar.setBackgroundColor(mParams.getBarBgColorOpacity());
164 | } else {
165 | mTitleBar.setBackgroundResource(R.color.bg_bar_opacity);
166 | }
167 | if (null != mParams.getBtnBackDrawable()) {
168 | mBtnBack.setBackgroundDrawable(mParams.getBtnBackDrawable());
169 | } else {
170 | mBtnBack.setBackgroundResource(R.drawable.icon_back);
171 | }
172 | if (null != mParams.getBtnDoneBgDrawable()) {
173 | mBtnDone.setBackgroundDrawable(mParams.getBtnDoneBgDrawable());
174 | } else {
175 | mBtnDone.setBackgroundResource(R.color.clarity);
176 | }
177 | updateDoneString();
178 | break;
179 | default:
180 | mGridGallery.setFastScrollEnabled(true);
181 | mTitleBar.setVisibility(View.GONE);
182 | break;
183 | }
184 | mGridGallery.setAdapter(mAdapter);
185 | }
186 |
187 | private void updateDoneString() {
188 | String doneSt = null;
189 | if (null != mParams.getDoneSt()) {
190 | doneSt = mParams.getDoneSt();
191 | } else {
192 | doneSt = mParentLayout.getResources().getString(R.string.done);
193 | }
194 | switch (mParams.getShownStyle()) {
195 | case Pick_Multiple:
196 | mBtnDone.setText(doneSt + "(" + mAdapter.getSelected().size() + "/"
197 | + mParams.getMaxPickSize() + ")");
198 | break;
199 | default:
200 | mBtnDone.setText(doneSt);
201 | break;
202 | }
203 | }
204 |
205 | private boolean checkImageStatus() {
206 | boolean result = false;
207 | switch (mModelsList.size()) {
208 | case 1:
209 | if (ShownStyle.ViewOnly == mParams.getShownStyle()) {
210 | result = true;
211 | mImgNoMedia.setVisibility(View.VISIBLE);
212 | mImageLoader.displayImage(mModelsList.get(0).mPath, mImgNoMedia,
213 | new SimpleImageLoadingListener() {
214 | @Override
215 | public void onLoadingStarted(String imageUri, View view) {
216 | if (null != mParams.getLoadingImageDrawable()) {
217 | mImgNoMedia.setImageDrawable(mParams
218 | .getLoadingImageDrawable());
219 | } else {
220 | mImgNoMedia.setImageResource(R.drawable.no_media);
221 | }
222 | super.onLoadingStarted(imageUri, view);
223 | }
224 | });
225 | mImgNoMedia.setClickable(true);
226 | mImgNoMedia.setOnClickListener(mOnSingleImageClickListener);
227 | }
228 | break;
229 | case 0:
230 | if (ShownStyle.ViewAndDelete != mParams.getShownStyle()) {
231 | result = true;
232 | mImgNoMedia.setVisibility(View.VISIBLE);
233 | mImgNoMedia.setImageResource(R.drawable.no_media);
234 | mImgNoMedia.setClickable(false);
235 | }
236 | break;
237 | default:
238 | break;
239 | }
240 | if (!result) {
241 | mImgNoMedia.setVisibility(View.GONE);
242 | }
243 | return result;
244 | }
245 |
246 | View.OnClickListener mDoneClickListener = new View.OnClickListener() {
247 |
248 | @Override
249 | public void onClick(View v) {
250 | ArrayList selected = mAdapter.getSelected();
251 |
252 | String[] paths = new String[selected.size()];
253 | for (int i = 0; i < paths.length; i++) {
254 | paths[i] = selected.get(i).mPath;
255 | }
256 | mListener.onDone(paths);
257 |
258 | }
259 | };
260 |
261 | View.OnClickListener mBackClickListener = new View.OnClickListener() {
262 |
263 | @Override
264 | public void onClick(View v) {
265 | mListener.onCanceled();
266 | }
267 | };
268 |
269 | AdapterView.OnItemClickListener mItemClickListener = new AdapterView.OnItemClickListener() {
270 |
271 | @Override
272 | public void onItemClick(AdapterView> l, View v, int position, long id) {
273 | if (mModelsList.get(position).isFunctionItem) {
274 | mListener.onFunctionItemClicked(mModelsList.get(position));
275 | return;
276 | }
277 | showPagerView(position);
278 | }
279 | };
280 |
281 | private OnClickListener mOnSingleImageClickListener = new OnClickListener() {
282 |
283 | @Override
284 | public void onClick(View v) {
285 | showPagerView(mModelsList.size());
286 | }
287 | };
288 |
289 | private void showPagerView(int position) {
290 | ViewPagerDialogFragment fragment =
291 | new ViewPagerDialogFragment(mModelsList, mParams, position);
292 | fragment.setStyle(DialogFragment.STYLE_NO_TITLE,
293 | android.R.style.Theme_Holo_NoActionBar_Fullscreen);
294 | fragment.setOnEventListener(mViewPagerListener);
295 | fragment.show(mFragmentManager, "viewpager");
296 | }
297 |
298 | ViewPagerListener mViewPagerListener = new ViewPagerListener() {
299 |
300 | @Override
301 | public void onDone(int currentPosition) {
302 | ArrayList selected = mAdapter.getSelected();
303 |
304 | String[] paths = new String[selected.size()];
305 | for (int i = 0; i < paths.length; i++) {
306 | paths[i] = selected.get(i).mPath;
307 | }
308 | mListener.onDone(paths);
309 | }
310 |
311 | @Override
312 | public void onDismiss() {
313 | updateDoneString();
314 | switch (mParams.getShownStyle()) {
315 | case Pick_Multiple:
316 | mAdapter.notifyDataSetChanged();
317 | break;
318 | case ViewAndDelete:
319 | removeDeletedItems();
320 | if (mModelsList.size() != mAdapter.getCount()) {
321 | mAdapter.addAll(mModelsList);
322 | mListener.onImageDataChanged();
323 | }
324 | break;
325 | default:
326 | break;
327 | }
328 | }
329 |
330 | };
331 |
332 | private void removeDeletedItems() {
333 | for (int i = 0; i < mModelsList.size(); i++) {
334 | if (mModelsList.get(i).isSeleted) {
335 | mModelsList.remove(i);
336 | i--;
337 | }
338 | }
339 |
340 | }
341 |
342 | private AdpterEventListener mAdapterEventListener = new AdpterEventListener() {
343 |
344 | @Override
345 | public void onItemSelectedStatusChange(int position, boolean isSelected) {
346 | updateDoneString();
347 | }
348 | };
349 |
350 | }
351 |
--------------------------------------------------------------------------------
/source/src/com/jfeinstein/jazzyviewpager/JazzyViewPager.java:
--------------------------------------------------------------------------------
1 | package com.jfeinstein.jazzyviewpager;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashMap;
5 | import java.util.LinkedHashMap;
6 |
7 | import android.annotation.TargetApi;
8 | import android.content.Context;
9 | import android.content.res.TypedArray;
10 | import android.graphics.Camera;
11 | import android.graphics.Color;
12 | import android.graphics.Matrix;
13 | import android.os.Build;
14 | import android.support.v4.view.PagerAdapter;
15 | import android.support.v4.view.ViewPager;
16 | import android.util.AttributeSet;
17 | import android.util.Log;
18 | import android.view.MotionEvent;
19 | import android.view.View;
20 |
21 | import com.habzy.image.models.ItemModel;
22 | import com.habzy.image.models.ViewParams;
23 | import com.habzy.image.models.ViewParams.TransitionEffect;
24 | import com.habzy.image.picker.R;
25 | import com.nineoldandroids.view.ViewHelper;
26 |
27 | public class JazzyViewPager extends ViewPager {
28 |
29 | public static final String TAG = "JazzyViewPager";
30 |
31 | private boolean mEnabled = true;
32 | private boolean mFadeEnabled = false;
33 | private boolean mOutlineEnabled = false;
34 | public static int sOutlineColor = Color.WHITE;
35 | private TransitionEffect mEffect = TransitionEffect.Standard;
36 |
37 | private HashMap mObjs = new LinkedHashMap();
38 |
39 | private JazzyPagerAdapter mAdapter;
40 |
41 | private static final float SCALE_MAX = 0.5f;
42 | private static final float ZOOM_MAX = 0.5f;
43 | private static final float ROT_MAX = 15.0f;
44 |
45 | private static final boolean API_11;
46 | static {
47 | API_11 = Build.VERSION.SDK_INT >= 11;
48 | }
49 |
50 | public JazzyViewPager(Context context) {
51 | this(context, null);
52 | }
53 |
54 | @SuppressWarnings("incomplete-switch")
55 | public JazzyViewPager(Context context, AttributeSet attrs) {
56 | super(context, attrs);
57 | setClipChildren(false);
58 | // now style everything!
59 | TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.JazzyViewPager);
60 | int effect = ta.getInt(R.styleable.JazzyViewPager_style, 0);
61 | String[] transitions = getResources().getStringArray(R.array.jazzy_effects);
62 | setTransitionEffect(TransitionEffect.valueOf(transitions[effect]));
63 | setFadeEnabled(ta.getBoolean(R.styleable.JazzyViewPager_fadeEnabled, false));
64 | setOutlineEnabled(ta.getBoolean(R.styleable.JazzyViewPager_outlineEnabled, false));
65 | setOutlineColor(ta.getColor(R.styleable.JazzyViewPager_outlineColor, Color.WHITE));
66 | switch (mEffect) {
67 | case Stack:
68 | case ZoomOut:
69 | setFadeEnabled(true);
70 | }
71 | ta.recycle();
72 | }
73 |
74 | public void setTransitionEffect(TransitionEffect effect) {
75 | mEffect = effect;
76 | // reset();
77 | }
78 |
79 | public void setPagingEnabled(boolean enabled) {
80 | mEnabled = enabled;
81 | }
82 |
83 | public void setFadeEnabled(boolean enabled) {
84 | mFadeEnabled = enabled;
85 | }
86 |
87 | public boolean getFadeEnabled() {
88 | return mFadeEnabled;
89 | }
90 |
91 | public void setOutlineEnabled(boolean enabled) {
92 | mOutlineEnabled = enabled;
93 | wrapWithOutlines();
94 | }
95 |
96 | public void setOutlineColor(int color) {
97 | sOutlineColor = color;
98 | }
99 |
100 | private void wrapWithOutlines() {
101 | for (int i = 0; i < getChildCount(); i++) {
102 | View v = getChildAt(i);
103 | if (!(v instanceof OutlineContainer)) {
104 | removeView(v);
105 | super.addView(wrapChild(v), i);
106 | }
107 | }
108 | }
109 |
110 | private View wrapChild(View child) {
111 | if (!mOutlineEnabled || child instanceof OutlineContainer)
112 | return child;
113 | OutlineContainer out = new OutlineContainer(getContext());
114 | out.setLayoutParams(generateDefaultLayoutParams());
115 | child.setLayoutParams(new OutlineContainer.LayoutParams(LayoutParams.MATCH_PARENT,
116 | LayoutParams.MATCH_PARENT));
117 | out.addView(child);
118 | return out;
119 | }
120 |
121 | public void addView(View child) {
122 | super.addView(wrapChild(child));
123 | }
124 |
125 | public void addView(View child, int index) {
126 | super.addView(wrapChild(child), index);
127 | }
128 |
129 | public void addView(View child, LayoutParams params) {
130 | super.addView(wrapChild(child), params);
131 | }
132 |
133 | public void addView(View child, int width, int height) {
134 | super.addView(wrapChild(child), width, height);
135 | }
136 |
137 | public void addView(View child, int index, LayoutParams params) {
138 | super.addView(wrapChild(child), index, params);
139 | }
140 |
141 | @Override
142 | public boolean onInterceptTouchEvent(MotionEvent arg0) {
143 | /**
144 | * Add try catch to fix bug: Which said in
145 | * http://stackoverflow.com/questions/16459196/java-lang-illegalargumentexception
146 | * -pointerindex-out-of-range-exception-dispat
147 | * ======================================================================================
148 | * And it's token reference from [HackyViewPager](https://github.com/habzy/PhotoView): Hacky
149 | * fix for Issue #4 and http://code.google.com/p/android/issues/detail?id=18990
150 | *
151 | * ScaleGestureDetector seems to mess up the touch events, which means that ViewGroups which
152 | * make use of onInterceptTouchEvent throw a lot of IllegalArgumentException: pointerIndex
153 | * out of range.
154 | *
155 | * There's not much I can do in my code for now, but we can mask the result by just catching
156 | * the problem and ignoring it.
157 | * =========TheEnd======================================================================
158 | */
159 | try {
160 | return mEnabled ? super.onInterceptTouchEvent(arg0) : false;
161 | } catch (IllegalArgumentException e) {
162 | e.printStackTrace();
163 | return false;
164 | }
165 | }
166 |
167 | private State mState;
168 | private int oldPage;
169 |
170 | private View mLeft;
171 | private View mRight;
172 | private float mRot;
173 | private float mTrans;
174 | private float mScale;
175 |
176 | private enum State {
177 | IDLE, GOING_LEFT, GOING_RIGHT
178 | }
179 |
180 | private void logState(View v, String title) {
181 | Log.v(TAG,
182 | title + ": ROT (" + ViewHelper.getRotation(v) + ", " + ViewHelper.getRotationX(v)
183 | + ", " + ViewHelper.getRotationY(v) + "), TRANS ("
184 | + ViewHelper.getTranslationX(v) + ", " + ViewHelper.getTranslationY(v)
185 | + "), SCALE (" + ViewHelper.getScaleX(v) + ", " + ViewHelper.getScaleY(v)
186 | + "), ALPHA " + ViewHelper.getAlpha(v));
187 | }
188 |
189 | protected void animateScroll(int position, float positionOffset) {
190 | if (mState != State.IDLE) {
191 | mRot = (float) (1 - Math.cos(2 * Math.PI * positionOffset)) / 2 * 30.0f;
192 | ViewHelper.setRotationY(this, mState == State.GOING_RIGHT ? mRot : -mRot);
193 | ViewHelper.setPivotX(this, getMeasuredWidth() * 0.5f);
194 | ViewHelper.setPivotY(this, getMeasuredHeight() * 0.5f);
195 | }
196 | }
197 |
198 | protected void animateTablet(View left, View right, float positionOffset) {
199 | if (mState != State.IDLE) {
200 | if (left != null) {
201 | manageLayer(left, true);
202 | mRot = 30.0f * positionOffset;
203 | mTrans =
204 | getOffsetXForRotation(mRot, left.getMeasuredWidth(),
205 | left.getMeasuredHeight());
206 | ViewHelper.setPivotX(left, left.getMeasuredWidth() / 2);
207 | ViewHelper.setPivotY(left, left.getMeasuredHeight() / 2);
208 | ViewHelper.setTranslationX(left, mTrans);
209 | ViewHelper.setRotationY(left, mRot);
210 | logState(left, "Left");
211 | }
212 | if (right != null) {
213 | manageLayer(right, true);
214 | mRot = -30.0f * (1 - positionOffset);
215 | mTrans =
216 | getOffsetXForRotation(mRot, right.getMeasuredWidth(),
217 | right.getMeasuredHeight());
218 | ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f);
219 | ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f);
220 | ViewHelper.setTranslationX(right, mTrans);
221 | ViewHelper.setRotationY(right, mRot);
222 | logState(right, "Right");
223 | }
224 | }
225 | }
226 |
227 | private void animateCube(View left, View right, float positionOffset, boolean in) {
228 | if (mState != State.IDLE) {
229 | if (left != null) {
230 | manageLayer(left, true);
231 | mRot = (in ? 90.0f : -90.0f) * positionOffset;
232 | ViewHelper.setPivotX(left, left.getMeasuredWidth());
233 | ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f);
234 | ViewHelper.setRotationY(left, mRot);
235 | }
236 | if (right != null) {
237 | manageLayer(right, true);
238 | mRot = -(in ? 90.0f : -90.0f) * (1 - positionOffset);
239 | ViewHelper.setPivotX(right, 0);
240 | ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f);
241 | ViewHelper.setRotationY(right, mRot);
242 | }
243 | }
244 | }
245 |
246 | private void animateAccordion(View left, View right, float positionOffset) {
247 | if (mState != State.IDLE) {
248 | if (left != null) {
249 | manageLayer(left, true);
250 | ViewHelper.setPivotX(left, left.getMeasuredWidth());
251 | ViewHelper.setPivotY(left, 0);
252 | ViewHelper.setScaleX(left, 1 - positionOffset);
253 | }
254 | if (right != null) {
255 | manageLayer(right, true);
256 | ViewHelper.setPivotX(right, 0);
257 | ViewHelper.setPivotY(right, 0);
258 | ViewHelper.setScaleX(right, positionOffset);
259 | }
260 | }
261 | }
262 |
263 | private void animateZoom(View left, View right, float positionOffset, boolean in) {
264 | if (mState != State.IDLE) {
265 | if (left != null) {
266 | manageLayer(left, true);
267 | mScale =
268 | in ? ZOOM_MAX + (1 - ZOOM_MAX) * (1 - positionOffset) : 1 + ZOOM_MAX
269 | - ZOOM_MAX * (1 - positionOffset);
270 | ViewHelper.setPivotX(left, left.getMeasuredWidth() * 0.5f);
271 | ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f);
272 | ViewHelper.setScaleX(left, mScale);
273 | ViewHelper.setScaleY(left, mScale);
274 | }
275 | if (right != null) {
276 | manageLayer(right, true);
277 | mScale =
278 | in ? ZOOM_MAX + (1 - ZOOM_MAX) * positionOffset : 1 + ZOOM_MAX - ZOOM_MAX
279 | * positionOffset;
280 | ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f);
281 | ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f);
282 | ViewHelper.setScaleX(right, mScale);
283 | ViewHelper.setScaleY(right, mScale);
284 | }
285 | }
286 | }
287 |
288 | private void animateRotate(View left, View right, float positionOffset, boolean up) {
289 | if (mState != State.IDLE) {
290 | if (left != null) {
291 | manageLayer(left, true);
292 | mRot = (up ? 1 : -1) * (ROT_MAX * positionOffset);
293 | mTrans =
294 | (up ? -1 : 1)
295 | * (float) (getMeasuredHeight() - getMeasuredHeight()
296 | * Math.cos(mRot * Math.PI / 180.0f));
297 | ViewHelper.setPivotX(left, left.getMeasuredWidth() * 0.5f);
298 | ViewHelper.setPivotY(left, up ? 0 : left.getMeasuredHeight());
299 | ViewHelper.setTranslationY(left, mTrans);
300 | ViewHelper.setRotation(left, mRot);
301 | }
302 | if (right != null) {
303 | manageLayer(right, true);
304 | mRot = (up ? 1 : -1) * (-ROT_MAX + ROT_MAX * positionOffset);
305 | mTrans =
306 | (up ? -1 : 1)
307 | * (float) (getMeasuredHeight() - getMeasuredHeight()
308 | * Math.cos(mRot * Math.PI / 180.0f));
309 | ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f);
310 | ViewHelper.setPivotY(right, up ? 0 : right.getMeasuredHeight());
311 | ViewHelper.setTranslationY(right, mTrans);
312 | ViewHelper.setRotation(right, mRot);
313 | }
314 | }
315 | }
316 |
317 | private void animateFlipHorizontal(View left, View right, float positionOffset,
318 | int positionOffsetPixels) {
319 | if (mState != State.IDLE) {
320 | if (left != null) {
321 | manageLayer(left, true);
322 | mRot = 180.0f * positionOffset;
323 | if (mRot > 90.0f) {
324 | left.setVisibility(View.INVISIBLE);
325 | } else {
326 | if (left.getVisibility() == View.INVISIBLE)
327 | left.setVisibility(View.VISIBLE);
328 | mTrans = positionOffsetPixels;
329 | ViewHelper.setPivotX(left, left.getMeasuredWidth() * 0.5f);
330 | ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f);
331 | ViewHelper.setTranslationX(left, mTrans);
332 | ViewHelper.setRotationY(left, mRot);
333 | }
334 | }
335 | if (right != null) {
336 | manageLayer(right, true);
337 | mRot = -180.0f * (1 - positionOffset);
338 | if (mRot < -90.0f) {
339 | right.setVisibility(View.INVISIBLE);
340 | } else {
341 | if (right.getVisibility() == View.INVISIBLE)
342 | right.setVisibility(View.VISIBLE);
343 | mTrans = -getWidth() - getPageMargin() + positionOffsetPixels;
344 | ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f);
345 | ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f);
346 | ViewHelper.setTranslationX(right, mTrans);
347 | ViewHelper.setRotationY(right, mRot);
348 | }
349 | }
350 | }
351 | }
352 |
353 | private void animateFlipVertical(View left, View right, float positionOffset,
354 | int positionOffsetPixels) {
355 | if (mState != State.IDLE) {
356 | if (left != null) {
357 | manageLayer(left, true);
358 | mRot = 180.0f * positionOffset;
359 | if (mRot > 90.0f) {
360 | left.setVisibility(View.INVISIBLE);
361 | } else {
362 | if (left.getVisibility() == View.INVISIBLE)
363 | left.setVisibility(View.VISIBLE);
364 | mTrans = positionOffsetPixels;
365 | ViewHelper.setPivotX(left, left.getMeasuredWidth() * 0.5f);
366 | ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f);
367 | ViewHelper.setTranslationX(left, mTrans);
368 | ViewHelper.setRotationX(left, mRot);
369 | }
370 | }
371 | if (right != null) {
372 | manageLayer(right, true);
373 | mRot = -180.0f * (1 - positionOffset);
374 | if (mRot < -90.0f) {
375 | right.setVisibility(View.INVISIBLE);
376 | } else {
377 | if (right.getVisibility() == View.INVISIBLE)
378 | right.setVisibility(View.VISIBLE);
379 | mTrans = -getWidth() - getPageMargin() + positionOffsetPixels;
380 | ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f);
381 | ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f);
382 | ViewHelper.setTranslationX(right, mTrans);
383 | ViewHelper.setRotationX(right, mRot);
384 | }
385 | }
386 | }
387 | }
388 |
389 | protected void animateStack(View left, View right, float positionOffset,
390 | int positionOffsetPixels) {
391 | if (mState != State.IDLE) {
392 | if (right != null) {
393 | manageLayer(right, true);
394 | mScale = (1 - SCALE_MAX) * positionOffset + SCALE_MAX;
395 | mTrans = -getWidth() - getPageMargin() + positionOffsetPixels;
396 | ViewHelper.setScaleX(right, mScale);
397 | ViewHelper.setScaleY(right, mScale);
398 | ViewHelper.setTranslationX(right, mTrans);
399 | }
400 | if (left != null) {
401 | left.bringToFront();
402 | }
403 | }
404 | }
405 |
406 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
407 | private void manageLayer(View v, boolean enableHardware) {
408 | if (!API_11)
409 | return;
410 | int layerType = enableHardware ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_NONE;
411 | if (layerType != v.getLayerType())
412 | v.setLayerType(layerType, null);
413 | }
414 |
415 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
416 | private void disableHardwareLayer() {
417 | if (!API_11)
418 | return;
419 | View v;
420 | for (int i = 0; i < getChildCount(); i++) {
421 | v = getChildAt(i);
422 | if (v.getLayerType() != View.LAYER_TYPE_NONE)
423 | v.setLayerType(View.LAYER_TYPE_NONE, null);
424 | }
425 | }
426 |
427 | private Matrix mMatrix = new Matrix();
428 | private Camera mCamera = new Camera();
429 | private float[] mTempFloat2 = new float[2];
430 |
431 | protected float getOffsetXForRotation(float degrees, int width, int height) {
432 | mMatrix.reset();
433 | mCamera.save();
434 | mCamera.rotateY(Math.abs(degrees));
435 | mCamera.getMatrix(mMatrix);
436 | mCamera.restore();
437 |
438 | mMatrix.preTranslate(-width * 0.5f, -height * 0.5f);
439 | mMatrix.postTranslate(width * 0.5f, height * 0.5f);
440 | mTempFloat2[0] = width;
441 | mTempFloat2[1] = height;
442 | mMatrix.mapPoints(mTempFloat2);
443 | return (width - mTempFloat2[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
444 | }
445 |
446 | protected void animateFade(View left, View right, float positionOffset) {
447 | if (left != null) {
448 | ViewHelper.setAlpha(left, 1 - positionOffset);
449 | }
450 | if (right != null) {
451 | ViewHelper.setAlpha(right, positionOffset);
452 | }
453 | }
454 |
455 | protected void animateOutline(View left, View right) {
456 | if (!(left instanceof OutlineContainer))
457 | return;
458 | if (mState != State.IDLE) {
459 | if (left != null) {
460 | manageLayer(left, true);
461 | ((OutlineContainer) left).setOutlineAlpha(1.0f);
462 | }
463 | if (right != null) {
464 | manageLayer(right, true);
465 | ((OutlineContainer) right).setOutlineAlpha(1.0f);
466 | }
467 | } else {
468 | if (left != null)
469 | ((OutlineContainer) left).start();
470 | if (right != null)
471 | ((OutlineContainer) right).start();
472 | }
473 | }
474 |
475 | @Override
476 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
477 | if (mState == State.IDLE && positionOffset > 0) {
478 | oldPage = getCurrentItem();
479 | mState = position == oldPage ? State.GOING_RIGHT : State.GOING_LEFT;
480 | }
481 | boolean goingRight = position == oldPage;
482 | if (mState == State.GOING_RIGHT && !goingRight)
483 | mState = State.GOING_LEFT;
484 | else if (mState == State.GOING_LEFT && goingRight)
485 | mState = State.GOING_RIGHT;
486 |
487 | float effectOffset = isSmall(positionOffset) ? 0 : positionOffset;
488 |
489 | // mLeft = getChildAt(position);
490 | // mRight = getChildAt(position+1);
491 | mLeft = findViewFromObject(position);
492 | mRight = findViewFromObject(position + 1);
493 |
494 | if (mFadeEnabled)
495 | animateFade(mLeft, mRight, effectOffset);
496 | if (mOutlineEnabled)
497 | animateOutline(mLeft, mRight);
498 |
499 | switch (mEffect) {
500 | case Standard:
501 | break;
502 | case Tablet:
503 | animateTablet(mLeft, mRight, effectOffset);
504 | break;
505 | case CubeIn:
506 | animateCube(mLeft, mRight, effectOffset, true);
507 | break;
508 | case CubeOut:
509 | animateCube(mLeft, mRight, effectOffset, false);
510 | break;
511 | case FlipVertical:
512 | animateFlipVertical(mLeft, mRight, positionOffset, positionOffsetPixels);
513 | break;
514 | case FlipHorizontal:
515 | animateFlipHorizontal(mLeft, mRight, effectOffset, positionOffsetPixels);
516 | case Stack:
517 | animateStack(mLeft, mRight, effectOffset, positionOffsetPixels);
518 | break;
519 | case ZoomIn:
520 | animateZoom(mLeft, mRight, effectOffset, true);
521 | break;
522 | case ZoomOut:
523 | animateZoom(mLeft, mRight, effectOffset, false);
524 | break;
525 | case RotateUp:
526 | animateRotate(mLeft, mRight, effectOffset, true);
527 | break;
528 | case RotateDown:
529 | animateRotate(mLeft, mRight, effectOffset, false);
530 | break;
531 | case Accordion:
532 | animateAccordion(mLeft, mRight, effectOffset);
533 | break;
534 | }
535 |
536 | super.onPageScrolled(position, positionOffset, positionOffsetPixels);
537 |
538 | if (effectOffset == 0) {
539 | disableHardwareLayer();
540 | mState = State.IDLE;
541 | }
542 |
543 | }
544 |
545 | private boolean isSmall(float positionOffset) {
546 | return Math.abs(positionOffset) < 0.0001;
547 | }
548 |
549 | public void setObjectForPosition(Object obj, int position) {
550 | mObjs.put(Integer.valueOf(position), obj);
551 | }
552 |
553 | public View findViewFromObject(int position) {
554 | Object o = mObjs.get(Integer.valueOf(position));
555 | if (o == null) {
556 | return null;
557 | }
558 | PagerAdapter a = getAdapter();
559 | View v;
560 | for (int i = 0; i < getChildCount(); i++) {
561 | v = getChildAt(i);
562 | if (a.isViewFromObject(v, o))
563 | return v;
564 | }
565 | return null;
566 | }
567 |
568 | public void setImagePath(ArrayList galleryPhotos, ViewParams params) {
569 | mAdapter = new JazzyPagerAdapter(this, params);
570 | mAdapter.setImagePath(galleryPhotos);
571 | setAdapter(mAdapter);
572 | }
573 |
574 | public void notifyChange() {
575 | mAdapter.notifyDataSetChanged();
576 | }
577 |
578 | public void setPhotoViewListener(PhotoViewListener photoViewListener) {
579 | mAdapter.setPhotoViewListener(photoViewListener);
580 | }
581 | }
582 |
--------------------------------------------------------------------------------