diff --git a/README.md b/README.md
index 05050ce..d129753 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,10 @@ Image selector for Android device. Support single choice and multi-choice.
-------------------
+###Run Demo
+
+>./gradlew installDebug
+
###Quick Start
* Step 0
Add module `multi-image-selector` as your dependence.
@@ -15,6 +19,11 @@ Add module `multi-image-selector` as your dependence.
* Step 1
Declare permission `android.permission.READ_EXTERNAL_STORAGE` in your `AndroidManifest.xml` .
Declare `MultiImageSelectorActivity` in your `AndroidManifest.xml` .
+```xml
+
+```
* Step 2
Call image selector activity in your code, eg.
@@ -101,6 +110,12 @@ class CustomerActivity extends Activity implements MultiImageSelectorFragment.Ca
1. Fixed. When set `EXTRA_SHOW_CAMERA` to `true`, the first grid item onclick event were messed.
2. Add. Support initial selected image list.
+* 2015-4-16
+ 1. Fixed. Crack when rotate device. (Issue by [@Leminity](https://github.com/Leminity))
+ 2. Fixed. PopupListView position error. (Issue by [@Slock](https://github.com/Slock))
+ 3. Change. Demo application shortcut.
+ 4. Change. Readme file.
+
-------------------
###Thanks
diff --git a/README_zh.md b/README_zh.md
index d82d4fe..b4900fa 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -8,6 +8,10 @@
-------------------
+###运行DEMO
+
+>./gradlew installDebug
+
###快速开始
* 第0步
把模块 `multi-image-selector` 作为你的项目依赖添加到工程中.
@@ -15,6 +19,11 @@
* 第1步
在你的 `AndroidManifest.xml` 文件中添加权限 `android.permission.READ_EXTERNAL_STORAGE`.
别忘了同时在 `AndroidManifest.xml` 中声明 `MultiImageSelectorActivity` 这个Activity.
+```xml
+
+```
* 第2步
代码中调用,例如:
@@ -101,6 +110,12 @@ class CustomerActivity extends Activity implements MultiImageSelectorFragment.Ca
1. 修复. 当设置 `EXTRA_SHOW_CAMERA` 为 `true` 时, 点击第一个Item会混乱的问题.
2. 新增. 支持初始化图片选择设定。
+* 2015-4-16
+ 1. 修复. 旋转设备时,程序会崩溃. (Issue by [@Leminity](https://github.com/Leminity))
+ 2. 修复. 文件夹PopupListView位置错误. (Issue by [@Slock](https://github.com/Slock))
+ 3. 更改. 演示程序截图.
+ 4. 更改. Readme 文件.
+
-------------------
###感谢
diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml
new file mode 100644
index 0000000..2399710
--- /dev/null
+++ b/app/src/main/res/values-zh/strings.xml
@@ -0,0 +1,6 @@
+
+ MultiImageSelector
+
+ Hello world!
+ Settings
+
diff --git a/multi-image-selector/multi-image-selector.iml b/multi-image-selector/multi-image-selector.iml
index d9aa2fa..658af94 100644
--- a/multi-image-selector/multi-image-selector.iml
+++ b/multi-image-selector/multi-image-selector.iml
@@ -1,5 +1,5 @@
-
+
@@ -12,8 +12,9 @@
-
+
+
@@ -86,10 +87,9 @@
-
-
+
+
-
-
+
\ No newline at end of file
diff --git a/multi-image-selector/src/main/java/me/nereo/multi_image_selector/MultiImageSelectorFragment.java b/multi-image-selector/src/main/java/me/nereo/multi_image_selector/MultiImageSelectorFragment.java
index b99f6ca..01876c6 100644
--- a/multi-image-selector/src/main/java/me/nereo/multi_image_selector/MultiImageSelectorFragment.java
+++ b/multi-image-selector/src/main/java/me/nereo/multi_image_selector/MultiImageSelectorFragment.java
@@ -3,6 +3,7 @@ package me.nereo.multi_image_selector;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
+import android.content.res.Configuration;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
@@ -14,6 +15,7 @@ import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v7.widget.ListPopupWindow;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -44,6 +46,8 @@ import me.nereo.multi_image_selector.utils.TimeUtils;
*/
public class MultiImageSelectorFragment extends Fragment {
+ private static final String TAG = "MultiImageSelector";
+
/** 最大图片选择次数,int类型 */
public static final String EXTRA_SELECT_COUNT = "max_select_count";
/** 图片选择模式,int类型 */
@@ -62,6 +66,7 @@ public class MultiImageSelectorFragment extends Fragment {
// 请求加载系统照相机
private static final int REQUEST_CAMERA = 100;
+
// 结果数据
private ArrayList resultList = new ArrayList<>();
// 文件夹数据
@@ -143,7 +148,7 @@ public class MultiImageSelectorFragment extends Fragment {
mCategoryText = (TextView) view.findViewById(R.id.category_btn);
// 初始化,加载所有图片
- mCategoryText.setText("所有图片");
+ mCategoryText.setText(R.string.folder_all);
mCategoryText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
@@ -161,7 +166,7 @@ public class MultiImageSelectorFragment extends Fragment {
mPreviewBtn = (Button) view.findViewById(R.id.preview);
// 初始化,按钮状态初始化
if(resultList == null || resultList.size()<=0){
- mPreviewBtn.setText("预览");
+ mPreviewBtn.setText(R.string.preview);
mPreviewBtn.setEnabled(false);
}
mPreviewBtn.setOnClickListener(new View.OnClickListener() {
@@ -206,10 +211,20 @@ public class MultiImageSelectorFragment extends Fragment {
mGridView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onGlobalLayout() {
- final int numCount = mGridView.getNumColumns();
+
+ final int width = mGridView.getWidth();
+ final int height = mGridView.getHeight();
+
+ final int desireSize = getResources().getDimensionPixelOffset(R.dimen.image_size);
+ final int numCount = width / desireSize;
final int columnSpace = getResources().getDimensionPixelOffset(R.dimen.space_size);
- int columnWidth = (mGridView.getWidth() - columnSpace*(numCount-1)) / numCount;
+ int columnWidth = (width - columnSpace*(numCount-1)) / numCount;
mImageAdapter.setItemSize(columnWidth);
+
+ if(mFolderPopupWindow == null){
+ createPopupFolderList(width, height);
+ }
+
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
mGridView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}else{
@@ -238,30 +253,26 @@ public class MultiImageSelectorFragment extends Fragment {
});
mFolderAdapter = new FolderAdapter(getActivity());
- createPopupFolderList();
}
/**
* 创建弹出的ListView
*/
- private void createPopupFolderList() {
+ private void createPopupFolderList(int width, int height) {
mFolderPopupWindow = new ListPopupWindow(getActivity());
-// mFolderPopupWindow.getListView().setDividerHeight(1);
-// mFolderPopupWindow.getListView().setDivider(new ColorDrawable(Color.parseColor("#CCCCCC")));
mFolderPopupWindow.setAdapter(mFolderAdapter);
- int sWidthPix = getResources().getDisplayMetrics().widthPixels;
- mFolderPopupWindow.setContentWidth(sWidthPix);
- mFolderPopupWindow.setHeight(sWidthPix);
+ mFolderPopupWindow.setContentWidth(width);
+ mFolderPopupWindow.setHeight(height * 5/8);
mFolderPopupWindow.setAnchorView(mPopupAnchorView);
mFolderPopupWindow.setModal(true);
mFolderPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
- if(i == 0){
+ if (i == 0) {
getActivity().getSupportLoaderManager().restartLoader(LOADER_ALL, null, mLoaderCallback);
- mCategoryText.setText("所有照片");
+ mCategoryText.setText(R.string.folder_all);
mImageAdapter.setShowCamera(true);
- }else {
+ } else {
Folder folder = (Folder) adapterView.getAdapter().getItem(i);
if (null != folder) {
Bundle args = new Bundle();
@@ -303,6 +314,49 @@ public class MultiImageSelectorFragment extends Fragment {
}
}
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ Log.d(TAG, "on change");
+
+ final int orientation = newConfig.orientation;
+
+ if(mFolderPopupWindow != null){
+ if(mFolderPopupWindow.isShowing()){
+ mFolderPopupWindow.dismiss();
+ }
+ }
+
+ mGridView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+ public void onGlobalLayout() {
+
+ final int height = mGridView.getHeight();
+
+ final int desireSize = getResources().getDimensionPixelOffset(R.dimen.image_size);
+ Log.d(TAG, "Desire Size = "+desireSize);
+ final int numCount = mGridView.getWidth() / desireSize;
+ Log.d(TAG, "Grid Size = "+mGridView.getWidth());
+ Log.d(TAG, "num count = "+numCount);
+ final int columnSpace = getResources().getDimensionPixelOffset(R.dimen.space_size);
+ int columnWidth = (mGridView.getWidth() - columnSpace*(numCount-1)) / numCount;
+ mImageAdapter.setItemSize(columnWidth);
+
+ if(mFolderPopupWindow != null){
+ mFolderPopupWindow.setHeight(height * 5/8);
+ }
+
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
+ mGridView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ }else{
+ mGridView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
+ }
+ }
+ });
+
+ super.onConfigurationChanged(newConfig);
+
+ }
+
/**
* 选择相机
*/
@@ -314,7 +368,7 @@ public class MultiImageSelectorFragment extends Fragment {
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));
startActivityForResult(cameraIntent, REQUEST_CAMERA);
}else{
- Toast.makeText(getActivity(), "没有系统相机", Toast.LENGTH_SHORT).show();
+ Toast.makeText(getActivity(), R.string.msg_no_camera, Toast.LENGTH_SHORT).show();
}
}
@@ -330,10 +384,10 @@ public class MultiImageSelectorFragment extends Fragment {
resultList.remove(image.path);
if(resultList.size() != 0) {
mPreviewBtn.setEnabled(true);
- mPreviewBtn.setText("预览(" + resultList.size() + ")");
+ mPreviewBtn.setText(getResources().getString(R.string.preview) + "(" + resultList.size() + ")");
}else{
mPreviewBtn.setEnabled(false);
- mPreviewBtn.setText("预览");
+ mPreviewBtn.setText(R.string.preview);
}
if (mCallback != null) {
mCallback.onImageUnselected(image.path);
@@ -341,13 +395,13 @@ public class MultiImageSelectorFragment extends Fragment {
} else {
// 判断选择数量问题
if(mDesireImageCount == resultList.size()){
- Toast.makeText(getActivity(), "已经达到最高选择数量了…", Toast.LENGTH_SHORT).show();
+ Toast.makeText(getActivity(), R.string.msg_amount_limit, Toast.LENGTH_SHORT).show();
return;
}
resultList.add(image.path);
mPreviewBtn.setEnabled(true);
- mPreviewBtn.setText("预览(" + resultList.size() + ")");
+ mPreviewBtn.setText(getResources().getString(R.string.preview) + "(" + resultList.size() + ")");
if (mCallback != null) {
mCallback.onImageSelected(image.path);
}
@@ -432,8 +486,6 @@ public class MultiImageSelectorFragment extends Fragment {
mFolderAdapter.setData(mResultFolder);
hasFolderGened = true;
- } else {
- System.out.println("no image found");
}
}
}
diff --git a/multi-image-selector/src/main/java/me/nereo/multi_image_selector/adapter/ImageGridAdapter.java b/multi-image-selector/src/main/java/me/nereo/multi_image_selector/adapter/ImageGridAdapter.java
index c47e2b1..2e042f5 100644
--- a/multi-image-selector/src/main/java/me/nereo/multi_image_selector/adapter/ImageGridAdapter.java
+++ b/multi-image-selector/src/main/java/me/nereo/multi_image_selector/adapter/ImageGridAdapter.java
@@ -174,32 +174,11 @@ public class ImageGridAdapter extends BaseAdapter {
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
-/* ViewHolde holde = null;
-
- if(showCamera){
- int type = getItemViewType(i);
- if(view == null){
-
- view = mInflater.inflate(R.layout.list_item_camera, viewGroup, false);
- }else{
-
- }
- }else{
- if(view == null){
- view = mInflater.inflate(R.layout.list_item_image, viewGroup, false);
- holde = new ViewHolde(view);
- }else{
- holde = (ViewHolde) view.getTag();
- }
- }
- // 绑定数据
- if(holde != null) {
- holde.bindData(getItem(i));
- }*/
int type = getItemViewType(i);
if(type == TYPE_CAMERA){
view = mInflater.inflate(R.layout.list_item_camera, viewGroup, false);
+ view.setTag(null);
}else if(type == TYPE_NORMAL){
ViewHolde holde;
if(view == null){
@@ -216,10 +195,13 @@ public class ImageGridAdapter extends BaseAdapter {
holde.bindData(getItem(i));
}
}
+
+ /** Fixed View Size */
GridView.LayoutParams lp = (GridView.LayoutParams) view.getLayoutParams();
if(lp.height != mItemSize){
view.setLayoutParams(mItemLayoutParams);
}
+
return view;
}
@@ -249,14 +231,17 @@ public class ImageGridAdapter extends BaseAdapter {
indicator.setVisibility(View.GONE);
}
File imageFile = new File(data.path);
- // 显示图片
- Picasso.with(mContext)
- .load(imageFile)
- .placeholder(R.drawable.default_error)
- //.error(R.drawable.default_error)
- .resize(mItemSize, mItemSize)
- .centerCrop()
- .into(image);
+
+ if(mItemSize > 0) {
+ // 显示图片
+ Picasso.with(mContext)
+ .load(imageFile)
+ .placeholder(R.drawable.default_error)
+ //.error(R.drawable.default_error)
+ .resize(mItemSize, mItemSize)
+ .centerCrop()
+ .into(image);
+ }
}
}
diff --git a/multi-image-selector/src/main/java/me/nereo/multi_image_selector/utils/TimeUtils.java b/multi-image-selector/src/main/java/me/nereo/multi_image_selector/utils/TimeUtils.java
index d1fd5ef..95740eb 100644
--- a/multi-image-selector/src/main/java/me/nereo/multi_image_selector/utils/TimeUtils.java
+++ b/multi-image-selector/src/main/java/me/nereo/multi_image_selector/utils/TimeUtils.java
@@ -20,7 +20,7 @@ public class TimeUtils {
}
public static String formatPhotoDate(long time){
- return timeFormat(time, "yyyy年MM月dd日");
+ return timeFormat(time, "yyyy-MM-dd");
}
public static String formatPhotoDate(String path){
diff --git a/multi-image-selector/src/main/java/me/nereo/multi_image_selector/view/GestureImageView.java b/multi-image-selector/src/main/java/me/nereo/multi_image_selector/view/GestureImageView.java
new file mode 100644
index 0000000..55a5297
--- /dev/null
+++ b/multi-image-selector/src/main/java/me/nereo/multi_image_selector/view/GestureImageView.java
@@ -0,0 +1,128 @@
+package me.nereo.multi_image_selector.view;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import android.support.v4.view.GestureDetectorCompat;
+import android.support.v4.view.MotionEventCompat;
+import android.support.v4.view.ScaleGestureDetectorCompat;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.DragEvent;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.ViewConfiguration;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+/**
+ * 支持手势的ImageView
+ * Created by Nereo on 2015/4/10.
+ */
+public class GestureImageView extends ImageView{
+
+ private static final String TAG = "GestureImageView";
+
+ public GestureImageView(Context context) {
+ super(context);
+ init(context);
+ }
+
+ public GestureImageView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public GestureImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context);
+ }
+
+ private ScaleGestureDetector mScaleGesture;
+ private Matrix mImageMatrix;
+ private GestureDetectorCompat mGestureDetector;
+
+ // 最大缩放比例
+ private static final float MAX_SCALE_FACTOR = 3.0f;
+ // 最小缩放比例
+ private static final float MIN_SCALE_FACTOR = 0.3f;
+ // 系统常量,系统认为手指是否移动的最小距离
+ private int mTouchSlop;
+
+ private float mCurrentFactor = 1.0f;
+
+ private float mFirstPointerX, mFirstPointerY;
+ private float mSecondPointerX, mSecondPointerY;
+
+ private int mCenterX, mCenterY;
+
+ /**
+ * 初始化
+ * @param context
+ */
+ private void init(final Context context){
+
+ mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+
+ setScaleType(ScaleType.MATRIX);
+
+ mImageMatrix = new Matrix();
+
+ mScaleGesture = new ScaleGestureDetector(context, new ScaleGestureDetector.SimpleOnScaleGestureListener(){
+ @Override
+ public boolean onScale(ScaleGestureDetector detector) {
+ float factor = detector.getScaleFactor();
+ mImageMatrix.postScale(factor, factor, mCenterX, mCenterY);
+ setImageMatrix(mImageMatrix);
+ return true;
+ }
+ });
+
+ mGestureDetector = new GestureDetectorCompat(context, new GestureDetector.SimpleOnGestureListener(){
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ mImageMatrix.postScale(1.f, 1.f, mCenterX, mCenterY);
+ setImageMatrix(mImageMatrix);
+ return true;
+ }
+
+ @Override
+ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+ //mImageMatrix.setTranslate(0, 0);
+ //setImageMatrix(mImageMatrix);
+ return true;
+ }
+
+ @Override
+ public boolean onDown(MotionEvent e) {
+ return true;
+ }
+ });
+
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ if( w != oldw || h != oldh){
+ int cx = (w - getDrawable().getIntrinsicWidth()) / 2 ;
+ int cy = (h - getDrawable().getIntrinsicHeight()) / 2;
+ mImageMatrix.setTranslate(cx, cy);
+ setImageMatrix(mImageMatrix);
+
+ mCenterX = w / 2;
+ mCenterY = h / 2;
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+
+ boolean retValue = mScaleGesture.onTouchEvent(event);
+
+ retValue = mGestureDetector.onTouchEvent(event) || retValue;
+
+ return retValue || super.onTouchEvent(event);
+ }
+
+}
diff --git a/multi-image-selector/src/main/java/me/nereo/multi_image_selector/view/SuperViewPager.java b/multi-image-selector/src/main/java/me/nereo/multi_image_selector/view/SuperViewPager.java
new file mode 100644
index 0000000..e26dbd3
--- /dev/null
+++ b/multi-image-selector/src/main/java/me/nereo/multi_image_selector/view/SuperViewPager.java
@@ -0,0 +1,21 @@
+package me.nereo.multi_image_selector.view;
+
+import android.content.Context;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+
+/**
+ * 自定义ViewPager
+ * Created by Nereo on 2015/4/10.
+ */
+public class SuperViewPager extends ViewPager {
+
+ public SuperViewPager(Context context) {
+ super(context);
+ }
+
+ public SuperViewPager(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+}
diff --git a/multi-image-selector/src/main/res/layout/fragment_multi_image.xml b/multi-image-selector/src/main/res/layout/fragment_multi_image.xml
index 147e639..20cf2a8 100644
--- a/multi-image-selector/src/main/res/layout/fragment_multi_image.xml
+++ b/multi-image-selector/src/main/res/layout/fragment_multi_image.xml
@@ -1,6 +1,7 @@
@@ -10,9 +11,10 @@
android:layout_height="match_parent"
android:horizontalSpacing="@dimen/space_size"
android:verticalSpacing="@dimen/space_size"
- android:paddingBottom="48dp"
+ android:paddingBottom="?android:attr/actionBarSize"
android:clipToPadding="false"
- android:numColumns="3"/>
+ android:numColumns="auto_fit"
+ android:columnWidth="@dimen/image_size"/>
+ android:layout_height="?android:attr/actionBarSize">
+
+ 96dp
+ 2dp
+ 72dp
+
\ No newline at end of file
diff --git a/multi-image-selector/src/main/res/values-sw480dp/dimens.xml b/multi-image-selector/src/main/res/values-sw480dp/dimens.xml
new file mode 100644
index 0000000..fe0c496
--- /dev/null
+++ b/multi-image-selector/src/main/res/values-sw480dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 100dp
+ 2dp
+ 72dp
+
\ No newline at end of file
diff --git a/multi-image-selector/src/main/res/values-sw720dp/dimens.xml b/multi-image-selector/src/main/res/values-sw720dp/dimens.xml
new file mode 100644
index 0000000..8a71ee0
--- /dev/null
+++ b/multi-image-selector/src/main/res/values-sw720dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 120dp
+ 3dp
+ 82dp
+
\ No newline at end of file
diff --git a/multi-image-selector/src/main/res/values-zh/strings.xml b/multi-image-selector/src/main/res/values-zh/strings.xml
new file mode 100644
index 0000000..d439ac9
--- /dev/null
+++ b/multi-image-selector/src/main/res/values-zh/strings.xml
@@ -0,0 +1,7 @@
+
+ 多图选择器
+ 所有照片
+ 预览
+ 没有系统相机
+ 已经达到最高选择数量
+
diff --git a/multi-image-selector/src/main/res/values/dimens.xml b/multi-image-selector/src/main/res/values/dimens.xml
index df1e644..b298eb7 100644
--- a/multi-image-selector/src/main/res/values/dimens.xml
+++ b/multi-image-selector/src/main/res/values/dimens.xml
@@ -1,5 +1,6 @@
+ 120dp
2dp
72dp
\ No newline at end of file
diff --git a/multi-image-selector/src/main/res/values/strings.xml b/multi-image-selector/src/main/res/values/strings.xml
index 92af08e..d6732fd 100644
--- a/multi-image-selector/src/main/res/values/strings.xml
+++ b/multi-image-selector/src/main/res/values/strings.xml
@@ -1,3 +1,7 @@
multi-image-selector
+ All Images
+ Preview
+ No system camera found
+ Select images amount is limit