sdf
This commit is contained in:
174
app/src/main/java/imageselector/ClipImageActivity.java
Normal file
174
app/src/main/java/imageselector/ClipImageActivity.java
Normal file
@@ -0,0 +1,174 @@
|
||||
package imageselector;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.sl.house_property.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import imageselector.utils.ImageSelector;
|
||||
import imageselector.utils.ImageUtil;
|
||||
import imageselector.utils.StringUtils;
|
||||
import imageselector.view.ClipImageView;
|
||||
|
||||
|
||||
public class ClipImageActivity extends Activity {
|
||||
|
||||
private FrameLayout btnConfirm;
|
||||
private FrameLayout btnBack;
|
||||
private ClipImageView imageView;
|
||||
private int mRequestCode;
|
||||
private boolean isCameraImage;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||
setContentView(R.layout.activity_clip_image);
|
||||
|
||||
Intent intent = getIntent();
|
||||
mRequestCode = intent.getIntExtra("requestCode", 0);
|
||||
|
||||
setStatusBarColor();
|
||||
ImageSelectorActivity.openActivity(this, mRequestCode, true,
|
||||
intent.getBooleanExtra(ImageSelector.IS_VIEW_IMAGE, true),
|
||||
intent.getBooleanExtra(ImageSelector.USE_CAMERA, true), 0,
|
||||
intent.getStringArrayListExtra(ImageSelector.SELECTED));
|
||||
initView();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改状态栏颜色
|
||||
*/
|
||||
private void setStatusBarColor() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.parseColor("#373c3d"));
|
||||
}
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
imageView = (ClipImageView) findViewById(R.id.process_img);
|
||||
btnConfirm = (FrameLayout) findViewById(R.id.btn_confirm);
|
||||
btnBack = (FrameLayout) findViewById(R.id.btn_back);
|
||||
|
||||
btnConfirm.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (imageView.getDrawable() != null) {
|
||||
btnConfirm.setEnabled(false);
|
||||
confirm(imageView.clipImage());
|
||||
}
|
||||
}
|
||||
});
|
||||
btnBack.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if (data != null && requestCode == mRequestCode) {
|
||||
ArrayList<String> images = data.getStringArrayListExtra(ImageSelector.SELECT_RESULT);
|
||||
isCameraImage = data.getBooleanExtra(ImageSelector.IS_CAMERA_IMAGE, false);
|
||||
Bitmap bitmap = ImageUtil.decodeSampledBitmapFromFile(images.get(0), 720, 1080);
|
||||
if (bitmap != null) {
|
||||
imageView.setBitmapData(bitmap);
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void confirm(Bitmap bitmap) {
|
||||
String imagePath = null;
|
||||
if (bitmap != null) {
|
||||
imagePath = ImageUtil.saveImage(bitmap, getCacheDir().getPath() + File.separator + "image_select");
|
||||
bitmap.recycle();
|
||||
bitmap = null;
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmptyString(imagePath)) {
|
||||
ArrayList<String> selectImages = new ArrayList<>();
|
||||
selectImages.add(imagePath);
|
||||
Intent intent = new Intent();
|
||||
intent.putStringArrayListExtra(ImageSelector.SELECT_RESULT, selectImages);
|
||||
intent.putExtra(ImageSelector.IS_CAMERA_IMAGE,isCameraImage);
|
||||
setResult(RESULT_OK, intent);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
public static void openActivity(Activity context, int requestCode, boolean isViewImage,
|
||||
boolean useCamera, ArrayList<String> selected) {
|
||||
Intent intent = new Intent(context, ClipImageActivity.class);
|
||||
intent.putExtras(dataPackages(requestCode, isViewImage, useCamera, selected));
|
||||
context.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
public static void openActivity(Fragment fragment, int requestCode, boolean isViewImage,
|
||||
boolean useCamera, ArrayList<String> selected) {
|
||||
Intent intent = new Intent(fragment.getContext(), ClipImageActivity.class);
|
||||
intent.putExtras(dataPackages(requestCode, isViewImage, useCamera, selected));
|
||||
fragment.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
public static void openActivity(android.app.Fragment fragment, int requestCode, boolean isViewImage,
|
||||
boolean useCamera, ArrayList<String> selected) {
|
||||
Intent intent = new Intent(fragment.getActivity(), ClipImageActivity.class);
|
||||
intent.putExtras(dataPackages(requestCode, isViewImage, useCamera, selected));
|
||||
fragment.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
public static Bundle dataPackages(int requestCode, boolean isViewImage, boolean useCamera,
|
||||
ArrayList<String> selected) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("requestCode", requestCode);
|
||||
bundle.putBoolean(ImageSelector.IS_VIEW_IMAGE, isViewImage);
|
||||
bundle.putBoolean(ImageSelector.USE_CAMERA, useCamera);
|
||||
bundle.putStringArrayList(ImageSelector.SELECTED, selected);
|
||||
return bundle;
|
||||
}
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
//非默认值
|
||||
if (newConfig.fontScale != 1){
|
||||
getResources();
|
||||
}
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resources getResources() {//还原字体大小
|
||||
Resources res = super.getResources();
|
||||
//非默认值
|
||||
if (res.getConfiguration().fontScale != 1) {
|
||||
Configuration newConfig = new Configuration();
|
||||
newConfig.setToDefaults();//设置默认
|
||||
res.updateConfiguration(newConfig, res.getDisplayMetrics());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
package imageselector;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.sl.house_property.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import imageselector.adapter.FullScreenImagePagerAdapter;
|
||||
import imageselector.adapter.FullScreenOnlineImagePagerAdapter;
|
||||
import imageselector.entry.Image;
|
||||
import imageselector.utils.ImageSelector;
|
||||
import imageselector.view.MyViewPager;
|
||||
|
||||
public class FullScreenOnlinePreviewActivity extends AppCompatActivity {
|
||||
|
||||
private MyViewPager vpImage;
|
||||
private TextView tvIndicator;
|
||||
|
||||
|
||||
//tempImages和tempSelectImages用于图片列表数据的页面传输。
|
||||
//之所以不要Intent传输这两个图片列表,因为要保证两位页面操作的是同一个列表数据,同时可以避免数据量大时,
|
||||
// 用Intent传输发生的错误问题。
|
||||
private static ArrayList<String> tempImages;
|
||||
|
||||
private ArrayList<String> mImages;
|
||||
private boolean isShowBar = true;
|
||||
private boolean isConfirm = false;
|
||||
|
||||
|
||||
public static void openActivity(Activity activity, ArrayList<String> images, int position) {
|
||||
tempImages = images;
|
||||
Intent intent = new Intent(activity, FullScreenOnlinePreviewActivity.class);
|
||||
intent.putExtra(ImageSelector.POSITION, position);
|
||||
activity.startActivityForResult(intent, ImageSelector.RESULT_CODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_full_screen_preview);
|
||||
|
||||
setStatusBarVisible(true);
|
||||
mImages = tempImages;
|
||||
tempImages = null;
|
||||
Intent intent = getIntent();
|
||||
setStatusBarColor();
|
||||
initView();
|
||||
initListener();
|
||||
initViewPager();
|
||||
|
||||
tvIndicator.setText(1 + "/" + mImages.size());
|
||||
vpImage.setCurrentItem(intent.getIntExtra(ImageSelector.POSITION, 0));
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
vpImage = (MyViewPager) findViewById(R.id.vp_image);
|
||||
tvIndicator = (TextView) findViewById(R.id.tv_indicator);
|
||||
}
|
||||
|
||||
private void initListener() {
|
||||
findViewById(R.id.btn_back).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化ViewPager
|
||||
*/
|
||||
private void initViewPager() {
|
||||
FullScreenOnlineImagePagerAdapter adapter = new FullScreenOnlineImagePagerAdapter(this, mImages);
|
||||
vpImage.setAdapter(adapter);
|
||||
|
||||
vpImage.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
tvIndicator.setText(position + 1 + "/" + mImages.size());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改状态栏颜色
|
||||
*/
|
||||
private void setStatusBarColor() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.parseColor("#373c3d"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取状态栏高度
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static int getStatusBarHeight(Context context) {
|
||||
int result = 0;
|
||||
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
if (resourceId > 0) {
|
||||
result = context.getResources().getDimensionPixelSize(resourceId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示和隐藏状态栏
|
||||
*
|
||||
* @param show
|
||||
*/
|
||||
private void setStatusBarVisible(boolean show) {
|
||||
if (show) {
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
} else {
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示头部和尾部栏
|
||||
*/
|
||||
private void showBar() {
|
||||
isShowBar = true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏头部和尾部栏
|
||||
*/
|
||||
private void hideBar() {
|
||||
isShowBar = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
//Activity关闭时,通过Intent把用户的操作(确定/返回)传给ImageSelectActivity。
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(ImageSelector.IS_CONFIRM, isConfirm);
|
||||
setResult(ImageSelector.RESULT_CODE, intent);
|
||||
super.finish();
|
||||
}
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
//非默认值
|
||||
if (newConfig.fontScale != 1){
|
||||
getResources();
|
||||
}
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resources getResources() {//还原字体大小
|
||||
Resources res = super.getResources();
|
||||
//非默认值
|
||||
if (res.getConfiguration().fontScale != 1) {
|
||||
Configuration newConfig = new Configuration();
|
||||
newConfig.setToDefaults();//设置默认
|
||||
res.updateConfiguration(newConfig, res.getDisplayMetrics());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
219
app/src/main/java/imageselector/FullScreenPreviewActivity.java
Normal file
219
app/src/main/java/imageselector/FullScreenPreviewActivity.java
Normal file
@@ -0,0 +1,219 @@
|
||||
package imageselector;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.sl.house_property.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import imageselector.adapter.FullScreenImagePagerAdapter;
|
||||
import imageselector.adapter.ImagePagerAdapter;
|
||||
import imageselector.entry.Image;
|
||||
import imageselector.utils.ImageSelector;
|
||||
import imageselector.view.MyViewPager;
|
||||
|
||||
import static android.animation.ObjectAnimator.ofFloat;
|
||||
|
||||
public class FullScreenPreviewActivity extends AppCompatActivity {
|
||||
|
||||
private MyViewPager vpImage;
|
||||
private TextView tvIndicator;
|
||||
|
||||
|
||||
//tempImages和tempSelectImages用于图片列表数据的页面传输。
|
||||
//之所以不要Intent传输这两个图片列表,因为要保证两位页面操作的是同一个列表数据,同时可以避免数据量大时,
|
||||
// 用Intent传输发生的错误问题。
|
||||
private static ArrayList<File> tempImages;
|
||||
|
||||
private ArrayList<File> mImages;
|
||||
private boolean isShowBar = true;
|
||||
private boolean isConfirm = false;
|
||||
|
||||
|
||||
public static void openActivity(Activity activity, ArrayList<File> images, int position) {
|
||||
tempImages = images;
|
||||
Intent intent = new Intent(activity, FullScreenPreviewActivity.class);
|
||||
intent.putExtra(ImageSelector.POSITION, position);
|
||||
activity.startActivityForResult(intent, ImageSelector.RESULT_CODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_full_screen_preview);
|
||||
|
||||
setStatusBarVisible(true);
|
||||
mImages = tempImages;
|
||||
tempImages = null;
|
||||
Intent intent = getIntent();
|
||||
setStatusBarColor();
|
||||
initView();
|
||||
initListener();
|
||||
initViewPager();
|
||||
|
||||
tvIndicator.setText(1 + "/" + mImages.size());
|
||||
vpImage.setCurrentItem(intent.getIntExtra(ImageSelector.POSITION, 0));
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
vpImage = (MyViewPager) findViewById(R.id.vp_image);
|
||||
tvIndicator = (TextView) findViewById(R.id.tv_indicator);
|
||||
}
|
||||
|
||||
private void initListener() {
|
||||
findViewById(R.id.btn_back).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化ViewPager
|
||||
*/
|
||||
private void initViewPager() {
|
||||
FullScreenImagePagerAdapter adapter = new FullScreenImagePagerAdapter(this, mImages);
|
||||
vpImage.setAdapter(adapter);
|
||||
adapter.setOnItemClickListener(new FullScreenImagePagerAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(int position, Image image) {
|
||||
if (isShowBar) {
|
||||
hideBar();
|
||||
} else {
|
||||
showBar();
|
||||
}
|
||||
}
|
||||
});
|
||||
vpImage.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
tvIndicator.setText(position + 1 + "/" + mImages.size());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改状态栏颜色
|
||||
*/
|
||||
private void setStatusBarColor() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.parseColor("#373c3d"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取状态栏高度
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static int getStatusBarHeight(Context context) {
|
||||
int result = 0;
|
||||
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
if (resourceId > 0) {
|
||||
result = context.getResources().getDimensionPixelSize(resourceId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示和隐藏状态栏
|
||||
*
|
||||
* @param show
|
||||
*/
|
||||
private void setStatusBarVisible(boolean show) {
|
||||
if (show) {
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
} else {
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示头部和尾部栏
|
||||
*/
|
||||
private void showBar() {
|
||||
isShowBar = true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏头部和尾部栏
|
||||
*/
|
||||
private void hideBar() {
|
||||
isShowBar = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
//Activity关闭时,通过Intent把用户的操作(确定/返回)传给ImageSelectActivity。
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(ImageSelector.IS_CONFIRM, isConfirm);
|
||||
setResult(ImageSelector.RESULT_CODE, intent);
|
||||
super.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
//非默认值
|
||||
if (newConfig.fontScale != 1){
|
||||
getResources();
|
||||
}
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resources getResources() {//还原字体大小
|
||||
Resources res = super.getResources();
|
||||
//非默认值
|
||||
if (res.getConfiguration().fontScale != 1) {
|
||||
Configuration newConfig = new Configuration();
|
||||
newConfig.setToDefaults();//设置默认
|
||||
res.updateConfiguration(newConfig, res.getDisplayMetrics());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
743
app/src/main/java/imageselector/ImageSelectorActivity.java
Normal file
743
app/src/main/java/imageselector/ImageSelectorActivity.java
Normal file
@@ -0,0 +1,743 @@
|
||||
package imageselector;
|
||||
|
||||
import android.Manifest;
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.support.v4.os.EnvironmentCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.SimpleItemAnimator;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.sl.house_property.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import imageselector.adapter.FolderAdapter;
|
||||
import imageselector.adapter.ImageAdapter;
|
||||
import imageselector.entry.Folder;
|
||||
import imageselector.entry.Image;
|
||||
import imageselector.model.ImageModel;
|
||||
import imageselector.utils.DateUtils;
|
||||
import imageselector.utils.ImageSelector;
|
||||
|
||||
|
||||
public class ImageSelectorActivity extends AppCompatActivity {
|
||||
|
||||
private TextView tvTime;
|
||||
private TextView tvFolderName;
|
||||
private TextView tvConfirm;
|
||||
private TextView tvPreview;
|
||||
private FrameLayout btnConfirm;
|
||||
private FrameLayout btnPreview;
|
||||
private RecyclerView rvImage;
|
||||
private RecyclerView rvFolder;
|
||||
private View masking;
|
||||
|
||||
private ImageAdapter mAdapter;
|
||||
private GridLayoutManager mLayoutManager;
|
||||
|
||||
private ArrayList<Folder> mFolders;
|
||||
private Folder mFolder;
|
||||
private boolean applyLoadImage = false;
|
||||
private static final int PERMISSION_WRITE_EXTERNAL_REQUEST_CODE = 0x00000011;
|
||||
private static final int PERMISSION_CAMERA_REQUEST_CODE = 0x00000012;
|
||||
|
||||
private static final int CAMERA_REQUEST_CODE = 0x00000010;
|
||||
|
||||
private boolean isOpenFolder;
|
||||
private boolean isShowTime;
|
||||
private boolean isInitFolder;
|
||||
private boolean isSingle;
|
||||
private boolean isViewImage = true;
|
||||
private int mMaxCount;
|
||||
|
||||
private boolean useCamera = true;
|
||||
private String mPhotoPath;
|
||||
|
||||
private Handler mHideHandler = new Handler();
|
||||
private Runnable mHide = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
hideTime();
|
||||
}
|
||||
};
|
||||
|
||||
//用于接收从外面传进来的已选择的图片列表。当用户原来已经有选择过图片,现在重新打开选择器,允许用
|
||||
// 户把先前选过的图片传进来,并把这些图片默认为选中状态。
|
||||
private ArrayList<String> mSelectedImages;
|
||||
|
||||
/**
|
||||
* 启动图片选择器
|
||||
*
|
||||
* @param activity
|
||||
* @param requestCode
|
||||
* @param isSingle 是否单选
|
||||
* @param isViewImage 是否点击放大图片查看
|
||||
* @param useCamera 是否使用拍照功能
|
||||
* @param maxSelectCount 图片的最大选择数量,小于等于0时,不限数量,isSingle为false时才有用。
|
||||
* @param selected 接收从外面传进来的已选择的图片列表。当用户原来已经有选择过图片,现在重新打开
|
||||
* 选择器,允许用户把先前选过的图片传进来,并把这些图片默认为选中状态。
|
||||
*/
|
||||
public static void openActivity(Activity activity, int requestCode,
|
||||
boolean isSingle, boolean isViewImage, boolean useCamera,
|
||||
int maxSelectCount, ArrayList<String> selected) {
|
||||
Intent intent = new Intent(activity, ImageSelectorActivity.class);
|
||||
intent.putExtras(dataPackages(isSingle, isViewImage, useCamera, maxSelectCount, selected));
|
||||
activity.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动图片选择器
|
||||
*
|
||||
* @param fragment
|
||||
* @param requestCode
|
||||
* @param isSingle 是否单选
|
||||
* @param isViewImage 是否点击放大图片查看
|
||||
* @param useCamera 是否使用拍照功能
|
||||
* @param maxSelectCount 图片的最大选择数量,小于等于0时,不限数量,isSingle为false时才有用。
|
||||
* @param selected 接收从外面传进来的已选择的图片列表。当用户原来已经有选择过图片,现在重新打开
|
||||
* 选择器,允许用户把先前选过的图片传进来,并把这些图片默认为选中状态。
|
||||
*/
|
||||
public static void openActivity(Fragment fragment, int requestCode,
|
||||
boolean isSingle, boolean isViewImage, boolean useCamera,
|
||||
int maxSelectCount, ArrayList<String> selected) {
|
||||
Intent intent = new Intent(fragment.getContext(), ImageSelectorActivity.class);
|
||||
intent.putExtras(dataPackages(isSingle, isViewImage, useCamera, maxSelectCount, selected));
|
||||
fragment.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动图片选择器
|
||||
*
|
||||
* @param fragment
|
||||
* @param requestCode
|
||||
* @param isSingle 是否单选
|
||||
* @param isViewImage 是否点击放大图片查看
|
||||
* @param useCamera 是否使用拍照功能
|
||||
* @param maxSelectCount 图片的最大选择数量,小于等于0时,不限数量,isSingle为false时才有用。
|
||||
* @param selected 接收从外面传进来的已选择的图片列表。当用户原来已经有选择过图片,现在重新打开
|
||||
* 选择器,允许用户把先前选过的图片传进来,并把这些图片默认为选中状态。
|
||||
*/
|
||||
public static void openActivity(android.app.Fragment fragment, int requestCode,
|
||||
boolean isSingle, boolean isViewImage, boolean useCamera,
|
||||
int maxSelectCount, ArrayList<String> selected) {
|
||||
Intent intent = new Intent(fragment.getActivity(), ImageSelectorActivity.class);
|
||||
intent.putExtras(dataPackages(isSingle, isViewImage, useCamera, maxSelectCount, selected));
|
||||
fragment.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
public static Bundle dataPackages(boolean isSingle, boolean isViewImage, boolean useCamera,
|
||||
int maxSelectCount, ArrayList<String> selected) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(ImageSelector.IS_SINGLE, isSingle);
|
||||
bundle.putBoolean(ImageSelector.IS_VIEW_IMAGE, isViewImage);
|
||||
bundle.putBoolean(ImageSelector.USE_CAMERA, useCamera);
|
||||
bundle.putInt(ImageSelector.MAX_SELECT_COUNT, maxSelectCount);
|
||||
bundle.putStringArrayList(ImageSelector.SELECTED, selected);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_image_select);
|
||||
|
||||
Intent intent = getIntent();
|
||||
mMaxCount = intent.getIntExtra(ImageSelector.MAX_SELECT_COUNT, 0);
|
||||
isSingle = intent.getBooleanExtra(ImageSelector.IS_SINGLE, false);
|
||||
isViewImage = intent.getBooleanExtra(ImageSelector.IS_VIEW_IMAGE, true);
|
||||
useCamera = intent.getBooleanExtra(ImageSelector.USE_CAMERA, true);
|
||||
mSelectedImages = intent.getStringArrayListExtra(ImageSelector.SELECTED);
|
||||
|
||||
setStatusBarColor();
|
||||
initView();
|
||||
initListener();
|
||||
initImageList();
|
||||
checkPermissionAndLoadImages();
|
||||
hideFolderList();
|
||||
setSelectImageCount(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改状态栏颜色
|
||||
*/
|
||||
private void setStatusBarColor() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.parseColor("#373c3d"));
|
||||
}
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
rvImage = (RecyclerView) findViewById(R.id.rv_image);
|
||||
rvFolder = (RecyclerView) findViewById(R.id.rv_folder);
|
||||
tvConfirm = (TextView) findViewById(R.id.tv_confirm);
|
||||
tvPreview = (TextView) findViewById(R.id.tv_preview);
|
||||
btnConfirm = (FrameLayout) findViewById(R.id.btn_confirm);
|
||||
btnPreview = (FrameLayout) findViewById(R.id.btn_preview);
|
||||
tvFolderName = (TextView) findViewById(R.id.tv_folder_name);
|
||||
tvTime = (TextView) findViewById(R.id.tv_time);
|
||||
masking = findViewById(R.id.masking);
|
||||
}
|
||||
|
||||
private void initListener() {
|
||||
findViewById(R.id.btn_back).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
btnPreview.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ArrayList<Image> images = new ArrayList<>();
|
||||
images.addAll(mAdapter.getSelectImages());
|
||||
toPreviewActivity(images, 0);
|
||||
}
|
||||
});
|
||||
|
||||
btnConfirm.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
confirm();
|
||||
}
|
||||
});
|
||||
|
||||
findViewById(R.id.btn_folder).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (isInitFolder) {
|
||||
if (isOpenFolder) {
|
||||
closeFolder();
|
||||
} else {
|
||||
openFolder();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
masking.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
closeFolder();
|
||||
}
|
||||
});
|
||||
|
||||
rvImage.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
|
||||
super.onScrollStateChanged(recyclerView, newState);
|
||||
changeTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
super.onScrolled(recyclerView, dx, dy);
|
||||
changeTime();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化图片列表
|
||||
*/
|
||||
private void initImageList() {
|
||||
// 判断屏幕方向
|
||||
Configuration configuration = getResources().getConfiguration();
|
||||
if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
mLayoutManager = new GridLayoutManager(this, 3);
|
||||
} else {
|
||||
mLayoutManager = new GridLayoutManager(this, 5);
|
||||
}
|
||||
|
||||
rvImage.setLayoutManager(mLayoutManager);
|
||||
mAdapter = new ImageAdapter(this, mMaxCount, isSingle, isViewImage);
|
||||
rvImage.setAdapter(mAdapter);
|
||||
((SimpleItemAnimator) rvImage.getItemAnimator()).setSupportsChangeAnimations(false);
|
||||
if (mFolders != null && !mFolders.isEmpty()) {
|
||||
setFolder(mFolders.get(0));
|
||||
}
|
||||
mAdapter.setOnImageSelectListener(new ImageAdapter.OnImageSelectListener() {
|
||||
@Override
|
||||
public void OnImageSelect(Image image, boolean isSelect, int selectCount) {
|
||||
setSelectImageCount(selectCount);
|
||||
}
|
||||
});
|
||||
mAdapter.setOnItemClickListener(new ImageAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void OnItemClick(Image image, int position) {
|
||||
toPreviewActivity(mAdapter.getData(), position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnCameraClick() {
|
||||
checkPermissionAndCamera();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化图片文件夹列表
|
||||
*/
|
||||
private void initFolderList() {
|
||||
if (mFolders != null && !mFolders.isEmpty()) {
|
||||
isInitFolder = true;
|
||||
rvFolder.setLayoutManager(new LinearLayoutManager(ImageSelectorActivity.this));
|
||||
FolderAdapter adapter = new FolderAdapter(ImageSelectorActivity.this, mFolders);
|
||||
adapter.setOnFolderSelectListener(new FolderAdapter.OnFolderSelectListener() {
|
||||
@Override
|
||||
public void OnFolderSelect(Folder folder) {
|
||||
setFolder(folder);
|
||||
closeFolder();
|
||||
}
|
||||
});
|
||||
rvFolder.setAdapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刚开始的时候文件夹列表默认是隐藏的
|
||||
*/
|
||||
private void hideFolderList() {
|
||||
rvFolder.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
rvFolder.setTranslationY(rvFolder.getHeight());
|
||||
rvFolder.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置选中的文件夹,同时刷新图片列表
|
||||
*
|
||||
* @param folder
|
||||
*/
|
||||
private void setFolder(Folder folder) {
|
||||
if (folder != null && mAdapter != null && !folder.equals(mFolder)) {
|
||||
mFolder = folder;
|
||||
tvFolderName.setText(folder.getName());
|
||||
rvImage.scrollToPosition(0);
|
||||
mAdapter.refresh(folder.getImages(), folder.isUseCamera());
|
||||
}
|
||||
}
|
||||
|
||||
private void setSelectImageCount(int count) {
|
||||
if (count == 0) {
|
||||
btnConfirm.setEnabled(false);
|
||||
btnPreview.setEnabled(false);
|
||||
tvConfirm.setText("确定");
|
||||
tvPreview.setText("预览");
|
||||
} else {
|
||||
btnConfirm.setEnabled(true);
|
||||
btnPreview.setEnabled(true);
|
||||
tvPreview.setText("预览(" + count + ")");
|
||||
if (isSingle) {
|
||||
tvConfirm.setText("确定");
|
||||
} else if (mMaxCount > 0) {
|
||||
tvConfirm.setText("确定(" + count + "/" + mMaxCount + ")");
|
||||
} else {
|
||||
tvConfirm.setText("确定(" + count + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出文件夹列表
|
||||
*/
|
||||
private void openFolder() {
|
||||
if (!isOpenFolder) {
|
||||
masking.setVisibility(View.VISIBLE);
|
||||
ObjectAnimator animator = ObjectAnimator.ofFloat(rvFolder, "translationY",
|
||||
rvFolder.getHeight(), 0).setDuration(300);
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
super.onAnimationStart(animation);
|
||||
rvFolder.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
isOpenFolder = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 收起文件夹列表
|
||||
*/
|
||||
private void closeFolder() {
|
||||
if (isOpenFolder) {
|
||||
masking.setVisibility(View.GONE);
|
||||
ObjectAnimator animator = ObjectAnimator.ofFloat(rvFolder, "translationY",
|
||||
0, rvFolder.getHeight()).setDuration(300);
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
rvFolder.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
isOpenFolder = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏时间条
|
||||
*/
|
||||
private void hideTime() {
|
||||
if (isShowTime) {
|
||||
ObjectAnimator.ofFloat(tvTime, "alpha", 1, 0).setDuration(300).start();
|
||||
isShowTime = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示时间条
|
||||
*/
|
||||
private void showTime() {
|
||||
if (!isShowTime) {
|
||||
ObjectAnimator.ofFloat(tvTime, "alpha", 0, 1).setDuration(300).start();
|
||||
isShowTime = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 改变时间条显示的时间(显示图片列表中的第一个可见图片的时间)
|
||||
*/
|
||||
private void changeTime() {
|
||||
int firstVisibleItem = getFirstVisibleItem();
|
||||
Image image = mAdapter.getFirstVisibleImage(firstVisibleItem);
|
||||
if (image != null) {
|
||||
String time = DateUtils.getImageTime(image.getTime() * 1000);
|
||||
tvTime.setText(time);
|
||||
showTime();
|
||||
mHideHandler.removeCallbacks(mHide);
|
||||
mHideHandler.postDelayed(mHide, 1500);
|
||||
}
|
||||
}
|
||||
|
||||
private int getFirstVisibleItem() {
|
||||
return mLayoutManager.findFirstVisibleItemPosition();
|
||||
}
|
||||
|
||||
private void confirm() {
|
||||
if (mAdapter == null) {
|
||||
return;
|
||||
}
|
||||
//因为图片的实体类是Image,而我们返回的是String数组,所以要进行转换。
|
||||
ArrayList<Image> selectImages = mAdapter.getSelectImages();
|
||||
ArrayList<String> images = new ArrayList<>();
|
||||
for (Image image : selectImages) {
|
||||
images.add(image.getPath());
|
||||
}
|
||||
|
||||
//点击确定,把选中的图片通过Intent传给上一个Activity。
|
||||
setResult(images,false);
|
||||
finish();
|
||||
}
|
||||
|
||||
private void setResult(ArrayList<String> images,boolean isCameraImage) {
|
||||
Intent intent = new Intent();
|
||||
intent.putStringArrayListExtra(ImageSelector.SELECT_RESULT, images);
|
||||
intent.putExtra(ImageSelector.IS_CAMERA_IMAGE,isCameraImage);
|
||||
setResult(RESULT_OK, intent);
|
||||
}
|
||||
|
||||
private void toPreviewActivity(ArrayList<Image> images, int position) {
|
||||
if (images != null && !images.isEmpty()) {
|
||||
PreviewActivity.openActivity(this, images,
|
||||
mAdapter.getSelectImages(), isSingle, mMaxCount, position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
if (applyLoadImage) {
|
||||
applyLoadImage = false;
|
||||
checkPermissionAndLoadImages();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理图片预览页返回的结果
|
||||
*
|
||||
* @param requestCode
|
||||
* @param resultCode
|
||||
* @param data
|
||||
*/
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == ImageSelector.RESULT_CODE) {
|
||||
if (data != null && data.getBooleanExtra(ImageSelector.IS_CONFIRM, false)) {
|
||||
//如果用户在预览页点击了确定,就直接把用户选中的图片返回给用户。
|
||||
confirm();
|
||||
} else {
|
||||
//否则,就刷新当前页面。
|
||||
mAdapter.notifyDataSetChanged();
|
||||
setSelectImageCount(mAdapter.getSelectImages().size());
|
||||
}
|
||||
} else if (requestCode == CAMERA_REQUEST_CODE) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(mPhotoPath))));
|
||||
ArrayList<String> images = new ArrayList<>();
|
||||
images.add(mPhotoPath);
|
||||
setResult(images,true);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 横竖屏切换处理
|
||||
*
|
||||
* @param newConfig
|
||||
*/
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
//非默认值
|
||||
if (newConfig.fontScale != 1){
|
||||
getResources();
|
||||
}
|
||||
super.onConfigurationChanged(newConfig);
|
||||
|
||||
if (mLayoutManager != null && mAdapter != null) {
|
||||
//切换为竖屏
|
||||
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
mLayoutManager.setSpanCount(3);
|
||||
}
|
||||
//切换为横屏
|
||||
else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
mLayoutManager.setSpanCount(5);
|
||||
}
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查权限并加载SD卡里的图片。
|
||||
*/
|
||||
private void checkPermissionAndLoadImages() {
|
||||
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
||||
// Toast.makeText(this, "没有图片", Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
int hasWriteExternalPermission = ContextCompat.checkSelfPermission(getApplication(),
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||
if (hasWriteExternalPermission == PackageManager.PERMISSION_GRANTED) {
|
||||
//有权限,加载图片。
|
||||
loadImageForSDCard();
|
||||
} else {
|
||||
//没有权限,申请权限。
|
||||
ActivityCompat.requestPermissions(ImageSelectorActivity.this,
|
||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_WRITE_EXTERNAL_REQUEST_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查权限并拍照。
|
||||
*/
|
||||
private void checkPermissionAndCamera() {
|
||||
int hasCameraPermission = ContextCompat.checkSelfPermission(getApplication(),
|
||||
Manifest.permission.CAMERA);
|
||||
if (hasCameraPermission == PackageManager.PERMISSION_GRANTED) {
|
||||
//有调起相机拍照。
|
||||
openCamera();
|
||||
} else {
|
||||
//没有权限,申请权限。
|
||||
ActivityCompat.requestPermissions(ImageSelectorActivity.this,
|
||||
new String[]{Manifest.permission.CAMERA}, PERMISSION_CAMERA_REQUEST_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理权限申请的回调。
|
||||
*
|
||||
* @param requestCode
|
||||
* @param permissions
|
||||
* @param grantResults
|
||||
*/
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
if (requestCode == PERMISSION_WRITE_EXTERNAL_REQUEST_CODE) {
|
||||
if (grantResults.length > 0
|
||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
//允许权限,加载图片。
|
||||
loadImageForSDCard();
|
||||
} else {
|
||||
//拒绝权限,弹出提示框。
|
||||
showExceptionDialog(true);
|
||||
}
|
||||
} else if (requestCode == PERMISSION_CAMERA_REQUEST_CODE) {
|
||||
if (grantResults.length > 0
|
||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
//允许权限,有调起相机拍照。
|
||||
openCamera();
|
||||
} else {
|
||||
//拒绝权限,弹出提示框。
|
||||
showExceptionDialog(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发生没有权限等异常时,显示一个提示dialog.
|
||||
*/
|
||||
private void showExceptionDialog(final boolean applyLoad) {
|
||||
new AlertDialog.Builder(this)
|
||||
.setCancelable(false)
|
||||
.setTitle("提示")
|
||||
.setMessage("该相册需要赋予访问存储和拍照的权限,请到“设置”>“应用”>“权限”中配置权限。")
|
||||
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
finish();
|
||||
}
|
||||
}).setPositiveButton("确定", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
startAppSettings();
|
||||
if (applyLoad) {
|
||||
applyLoadImage = true;
|
||||
}
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从SDCard加载图片。
|
||||
*/
|
||||
private void loadImageForSDCard() {
|
||||
ImageModel.loadImageForSDCard(this, new ImageModel.DataCallback() {
|
||||
@Override
|
||||
public void onSuccess(ArrayList<Folder> folders) {
|
||||
mFolders = folders;
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mFolders != null && !mFolders.isEmpty()) {
|
||||
initFolderList();
|
||||
mFolders.get(0).setUseCamera(useCamera);
|
||||
setFolder(mFolders.get(0));
|
||||
if (mSelectedImages != null && mAdapter != null) {
|
||||
mAdapter.setSelectedImages(mSelectedImages);
|
||||
mSelectedImages = null;
|
||||
setSelectImageCount(mAdapter.getSelectImages().size());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 调起相机拍照
|
||||
*/
|
||||
private void openCamera() {
|
||||
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
if (captureIntent.resolveActivity(getPackageManager()) != null) {
|
||||
File photoFile = null;
|
||||
try {
|
||||
photoFile = createImageFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (photoFile != null) {
|
||||
mPhotoPath = photoFile.getAbsolutePath();
|
||||
//通过FileProvider创建一个content类型的Uri
|
||||
Uri photoUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", photoFile);
|
||||
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
|
||||
captureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||
startActivityForResult(captureIntent, CAMERA_REQUEST_CODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private File createImageFile() throws IOException {
|
||||
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
|
||||
String imageFileName = String.format("JPEG_%s.jpg", timeStamp);
|
||||
File storageDir = Environment.getExternalStoragePublicDirectory(
|
||||
Environment.DIRECTORY_PICTURES);
|
||||
if (!storageDir.exists()) {
|
||||
storageDir.mkdir();
|
||||
}
|
||||
File tempFile = new File(storageDir, imageFileName);
|
||||
if (!Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(tempFile))) {
|
||||
return null;
|
||||
}
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动应用的设置
|
||||
*/
|
||||
private void startAppSettings() {
|
||||
Intent intent = new Intent(
|
||||
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
intent.setData(Uri.parse("package:" + getPackageName()));
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN && isOpenFolder) {
|
||||
closeFolder();
|
||||
return true;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resources getResources() {//还原字体大小
|
||||
Resources res = super.getResources();
|
||||
//非默认值
|
||||
if (res.getConfiguration().fontScale != 1) {
|
||||
Configuration newConfig = new Configuration();
|
||||
newConfig.setToDefaults();//设置默认
|
||||
res.updateConfiguration(newConfig, res.getDisplayMetrics());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
346
app/src/main/java/imageselector/PreviewActivity.java
Normal file
346
app/src/main/java/imageselector/PreviewActivity.java
Normal file
@@ -0,0 +1,346 @@
|
||||
package imageselector;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.sl.house_property.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
import imageselector.adapter.ImagePagerAdapter;
|
||||
import imageselector.entry.Image;
|
||||
import imageselector.utils.ImageSelector;
|
||||
import imageselector.view.MyViewPager;
|
||||
|
||||
import static android.animation.ObjectAnimator.ofFloat;
|
||||
|
||||
public class PreviewActivity extends AppCompatActivity {
|
||||
|
||||
private MyViewPager vpImage;
|
||||
private TextView tvIndicator;
|
||||
private TextView tvConfirm;
|
||||
private FrameLayout btnConfirm;
|
||||
private TextView tvSelect;
|
||||
private RelativeLayout rlTopBar;
|
||||
private RelativeLayout rlBottomBar;
|
||||
|
||||
//tempImages和tempSelectImages用于图片列表数据的页面传输。
|
||||
//之所以不要Intent传输这两个图片列表,因为要保证两位页面操作的是同一个列表数据,同时可以避免数据量大时,
|
||||
// 用Intent传输发生的错误问题。
|
||||
private static ArrayList<Image> tempImages;
|
||||
private static ArrayList<Image> tempSelectImages;
|
||||
|
||||
private ArrayList<Image> mImages;
|
||||
private ArrayList<Image> mSelectImages;
|
||||
private boolean isShowBar = true;
|
||||
private boolean isConfirm = false;
|
||||
private boolean isSingle;
|
||||
private int mMaxCount;
|
||||
|
||||
private BitmapDrawable mSelectDrawable;
|
||||
private BitmapDrawable mUnSelectDrawable;
|
||||
|
||||
public static void openActivity(Activity activity, ArrayList<Image> images,
|
||||
ArrayList<Image> selectImages, boolean isSingle,
|
||||
int maxSelectCount, int position) {
|
||||
tempImages = images;
|
||||
tempSelectImages = selectImages;
|
||||
Intent intent = new Intent(activity, PreviewActivity.class);
|
||||
intent.putExtra(ImageSelector.MAX_SELECT_COUNT, maxSelectCount);
|
||||
intent.putExtra(ImageSelector.IS_SINGLE, isSingle);
|
||||
intent.putExtra(ImageSelector.POSITION, position);
|
||||
activity.startActivityForResult(intent, ImageSelector.RESULT_CODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_preview);
|
||||
|
||||
setStatusBarVisible(true);
|
||||
mImages = tempImages;
|
||||
tempImages = null;
|
||||
mSelectImages = tempSelectImages;
|
||||
tempSelectImages = null;
|
||||
|
||||
Intent intent = getIntent();
|
||||
mMaxCount = intent.getIntExtra(ImageSelector.MAX_SELECT_COUNT, 0);
|
||||
isSingle = intent.getBooleanExtra(ImageSelector.IS_SINGLE, false);
|
||||
|
||||
Resources resources = getResources();
|
||||
Bitmap selectBitmap = BitmapFactory.decodeResource(resources, R.drawable.icon_image_select);
|
||||
mSelectDrawable = new BitmapDrawable(resources, selectBitmap);
|
||||
mSelectDrawable.setBounds(0, 0, selectBitmap.getWidth(), selectBitmap.getHeight());
|
||||
|
||||
Bitmap unSelectBitmap = BitmapFactory.decodeResource(resources, R.drawable.icon_image_un_select);
|
||||
mUnSelectDrawable = new BitmapDrawable(resources, unSelectBitmap);
|
||||
mUnSelectDrawable.setBounds(0, 0, unSelectBitmap.getWidth(), unSelectBitmap.getHeight());
|
||||
|
||||
setStatusBarColor();
|
||||
initView();
|
||||
initListener();
|
||||
initViewPager();
|
||||
|
||||
tvIndicator.setText(1 + "/" + mImages.size());
|
||||
changeSelect(mImages.get(0));
|
||||
vpImage.setCurrentItem(intent.getIntExtra(ImageSelector.POSITION, 0));
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
vpImage = (MyViewPager) findViewById(R.id.vp_image);
|
||||
tvIndicator = (TextView) findViewById(R.id.tv_indicator);
|
||||
tvConfirm = (TextView) findViewById(R.id.tv_confirm);
|
||||
btnConfirm = (FrameLayout) findViewById(R.id.btn_confirm);
|
||||
tvSelect = (TextView) findViewById(R.id.tv_select);
|
||||
rlTopBar = (RelativeLayout) findViewById(R.id.rl_top_bar);
|
||||
rlBottomBar = (RelativeLayout) findViewById(R.id.rl_bottom_bar);
|
||||
|
||||
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) rlTopBar.getLayoutParams();
|
||||
lp.topMargin = getStatusBarHeight(this);
|
||||
rlTopBar.setLayoutParams(lp);
|
||||
}
|
||||
|
||||
private void initListener() {
|
||||
findViewById(R.id.btn_back).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
btnConfirm.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
isConfirm = true;
|
||||
finish();
|
||||
}
|
||||
});
|
||||
tvSelect.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
clickSelect();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化ViewPager
|
||||
*/
|
||||
private void initViewPager() {
|
||||
ImagePagerAdapter adapter = new ImagePagerAdapter(this, mImages);
|
||||
vpImage.setAdapter(adapter);
|
||||
adapter.setOnItemClickListener(new ImagePagerAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(int position, Image image) {
|
||||
if (isShowBar) {
|
||||
hideBar();
|
||||
} else {
|
||||
showBar();
|
||||
}
|
||||
}
|
||||
});
|
||||
vpImage.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
tvIndicator.setText(position + 1 + "/" + mImages.size());
|
||||
changeSelect(mImages.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改状态栏颜色
|
||||
*/
|
||||
private void setStatusBarColor() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.parseColor("#373c3d"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取状态栏高度
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static int getStatusBarHeight(Context context) {
|
||||
int result = 0;
|
||||
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
if (resourceId > 0) {
|
||||
result = context.getResources().getDimensionPixelSize(resourceId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示和隐藏状态栏
|
||||
*
|
||||
* @param show
|
||||
*/
|
||||
private void setStatusBarVisible(boolean show) {
|
||||
if (show) {
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
} else {
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示头部和尾部栏
|
||||
*/
|
||||
private void showBar() {
|
||||
isShowBar = true;
|
||||
setStatusBarVisible(true);
|
||||
//添加延时,保证StatusBar完全显示后再进行动画。
|
||||
rlTopBar.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (rlTopBar != null) {
|
||||
ObjectAnimator animator = ofFloat(rlTopBar, "translationY",
|
||||
rlTopBar.getTranslationY(), 0).setDuration(300);
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
super.onAnimationStart(animation);
|
||||
if (rlTopBar != null) {
|
||||
rlTopBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
ofFloat(rlBottomBar, "translationY", rlBottomBar.getTranslationY(), 0)
|
||||
.setDuration(300).start();
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏头部和尾部栏
|
||||
*/
|
||||
private void hideBar() {
|
||||
isShowBar = false;
|
||||
ObjectAnimator animator = ObjectAnimator.ofFloat(rlTopBar, "translationY",
|
||||
0, -rlTopBar.getHeight()).setDuration(300);
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
if (rlTopBar != null) {
|
||||
rlTopBar.setVisibility(View.GONE);
|
||||
//添加延时,保证rlTopBar完全隐藏后再隐藏StatusBar。
|
||||
rlTopBar.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setStatusBarVisible(false);
|
||||
}
|
||||
}, 5);
|
||||
}
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
ofFloat(rlBottomBar, "translationY", 0, rlBottomBar.getHeight())
|
||||
.setDuration(300).start();
|
||||
}
|
||||
|
||||
private void clickSelect() {
|
||||
int position = vpImage.getCurrentItem();
|
||||
if (mImages != null && mImages.size() > position) {
|
||||
Image image = mImages.get(position);
|
||||
if (mSelectImages.contains(image)) {
|
||||
mSelectImages.remove(image);
|
||||
} else if (isSingle) {
|
||||
mSelectImages.clear();
|
||||
mSelectImages.add(image);
|
||||
} else if (mMaxCount <= 0 || mSelectImages.size() < mMaxCount) {
|
||||
mSelectImages.add(image);
|
||||
}
|
||||
changeSelect(image);
|
||||
}
|
||||
}
|
||||
|
||||
private void changeSelect(Image image) {
|
||||
tvSelect.setCompoundDrawables(mSelectImages.contains(image) ?
|
||||
mSelectDrawable : mUnSelectDrawable, null, null, null);
|
||||
setSelectImageCount(mSelectImages.size());
|
||||
}
|
||||
|
||||
private void setSelectImageCount(int count) {
|
||||
if (count == 0) {
|
||||
btnConfirm.setEnabled(false);
|
||||
tvConfirm.setText("确定");
|
||||
} else {
|
||||
btnConfirm.setEnabled(true);
|
||||
if (isSingle) {
|
||||
tvConfirm.setText("确定");
|
||||
} else if (mMaxCount > 0) {
|
||||
tvConfirm.setText("确定(" + count + "/" + mMaxCount + ")");
|
||||
} else {
|
||||
tvConfirm.setText("确定(" + count + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
//Activity关闭时,通过Intent把用户的操作(确定/返回)传给ImageSelectActivity。
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(ImageSelector.IS_CONFIRM, isConfirm);
|
||||
setResult(ImageSelector.RESULT_CODE, intent);
|
||||
super.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
//非默认值
|
||||
if (newConfig.fontScale != 1){
|
||||
getResources();
|
||||
}
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resources getResources() {//还原字体大小
|
||||
Resources res = super.getResources();
|
||||
//非默认值
|
||||
if (res.getConfiguration().fontScale != 1) {
|
||||
Configuration newConfig = new Configuration();
|
||||
newConfig.setToDefaults();//设置默认
|
||||
res.updateConfiguration(newConfig, res.getDisplayMetrics());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
100
app/src/main/java/imageselector/adapter/FolderAdapter.java
Normal file
100
app/src/main/java/imageselector/adapter/FolderAdapter.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package imageselector.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.sl.house_property.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import imageselector.entry.Folder;
|
||||
import imageselector.entry.Image;
|
||||
|
||||
|
||||
public class FolderAdapter extends RecyclerView.Adapter<FolderAdapter.ViewHolder> {
|
||||
|
||||
private Context mContext;
|
||||
private ArrayList<Folder> mFolders;
|
||||
private LayoutInflater mInflater;
|
||||
private int mSelectItem;
|
||||
private OnFolderSelectListener mListener;
|
||||
|
||||
public FolderAdapter(Context context, ArrayList<Folder> folders) {
|
||||
mContext = context;
|
||||
mFolders = folders;
|
||||
this.mInflater = LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = mInflater.inflate(R.layout.adapter_folder, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final ViewHolder holder, int position) {
|
||||
final Folder folder = mFolders.get(position);
|
||||
ArrayList<Image> images = folder.getImages();
|
||||
holder.tvFolderName.setText(folder.getName());
|
||||
holder.ivSelect.setVisibility(mSelectItem == position ? View.VISIBLE : View.GONE);
|
||||
if (images != null && !images.isEmpty()) {
|
||||
holder.tvFolderSize.setText(images.size() + "张");
|
||||
Glide.with(mContext).load(new File(images.get(0).getPath()))
|
||||
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
|
||||
.into(holder.ivImage);
|
||||
} else {
|
||||
holder.tvFolderSize.setText("0张");
|
||||
holder.ivImage.setImageBitmap(null);
|
||||
}
|
||||
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mSelectItem = holder.getAdapterPosition();
|
||||
notifyDataSetChanged();
|
||||
if (mListener != null) {
|
||||
mListener.OnFolderSelect(folder);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mFolders == null ? 0 : mFolders.size();
|
||||
}
|
||||
|
||||
public void setOnFolderSelectListener(OnFolderSelectListener listener) {
|
||||
this.mListener = listener;
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
ImageView ivImage;
|
||||
ImageView ivSelect;
|
||||
TextView tvFolderName;
|
||||
TextView tvFolderSize;
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ivImage = itemView.findViewById(R.id.iv_image);
|
||||
ivSelect = itemView.findViewById(R.id.iv_select);
|
||||
tvFolderName = itemView.findViewById(R.id.tv_folder_name);
|
||||
tvFolderSize = itemView.findViewById(R.id.tv_folder_size);
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnFolderSelectListener {
|
||||
void OnFolderSelect(Folder folder);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package imageselector.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Matrix;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.github.chrisbanes.photoview.PhotoView;
|
||||
import com.github.chrisbanes.photoview.PhotoViewAttacher;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import imageselector.entry.Image;
|
||||
import imageselector.utils.ImageUtil;
|
||||
|
||||
|
||||
public class FullScreenImagePagerAdapter extends PagerAdapter {
|
||||
|
||||
private Context mContext;
|
||||
private List<PhotoView> viewList = new ArrayList<>(4);
|
||||
List<File> mImgList;
|
||||
private OnItemClickListener mListener;
|
||||
|
||||
public FullScreenImagePagerAdapter(Context context, List<File> imgList) {
|
||||
this.mContext = context;
|
||||
createImageViews();
|
||||
mImgList = imgList;
|
||||
}
|
||||
|
||||
private void createImageViews() {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
PhotoView imageView = new PhotoView(mContext);
|
||||
imageView.setAdjustViewBounds(true);
|
||||
viewList.add(imageView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mImgList == null ? 0 : mImgList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewFromObject(View view, Object object) {
|
||||
return view == object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||
if (object instanceof PhotoView) {
|
||||
PhotoView view = (PhotoView) object;
|
||||
view.setImageDrawable(null);
|
||||
viewList.add(view);
|
||||
container.removeView(view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, final int position) {
|
||||
final PhotoView currentView = viewList.remove(0);
|
||||
final File image = mImgList.get(position);
|
||||
container.addView(currentView);
|
||||
|
||||
Glide.with(mContext).asBitmap()
|
||||
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
|
||||
.load(image).into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
int bw = resource.getWidth();
|
||||
int bh = resource.getHeight();
|
||||
if (bw > 8192 || bh > 8192) {
|
||||
Bitmap bitmap = ImageUtil.zoomBitmap(resource, 8192, 8192);
|
||||
setBitmap(currentView, bitmap);
|
||||
} else {
|
||||
setBitmap(currentView, resource);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
currentView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mListener != null) {
|
||||
// mListener.onItemClick(position, image);
|
||||
}
|
||||
}
|
||||
});
|
||||
return currentView;
|
||||
}
|
||||
|
||||
private void setBitmap(PhotoView imageView, Bitmap bitmap) {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
if (bitmap != null) {
|
||||
int bw = bitmap.getWidth();
|
||||
int bh = bitmap.getHeight();
|
||||
int vw = imageView.getWidth();
|
||||
int vh = imageView.getHeight();
|
||||
if (bw != 0 && bh != 0 && vw != 0 && vh != 0) {
|
||||
if (1.0f * bh / bw > 1.0f * vh / vw) {
|
||||
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
float offset = (1.0f * bh * vw / bw - vh) / 2;
|
||||
adjustOffset(imageView, offset);
|
||||
} else {
|
||||
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener l) {
|
||||
mListener = l;
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(int position, Image image);
|
||||
}
|
||||
|
||||
private void adjustOffset(PhotoView view, float offset) {
|
||||
PhotoViewAttacher attacher = view.getAttacher();
|
||||
try {
|
||||
Field field = PhotoViewAttacher.class.getDeclaredField("mBaseMatrix");
|
||||
field.setAccessible(true);
|
||||
Matrix matrix = (Matrix) field.get(attacher);
|
||||
matrix.postTranslate(0, offset);
|
||||
Method method = PhotoViewAttacher.class.getDeclaredMethod("resetMatrix");
|
||||
method.setAccessible(true);
|
||||
method.invoke(attacher);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package imageselector.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Matrix;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.github.chrisbanes.photoview.PhotoView;
|
||||
import com.github.chrisbanes.photoview.PhotoViewAttacher;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import imageselector.entry.Image;
|
||||
import imageselector.utils.ImageUtil;
|
||||
|
||||
|
||||
public class FullScreenOnlineImagePagerAdapter extends PagerAdapter {
|
||||
|
||||
private Context mContext;
|
||||
private List<PhotoView> viewList = new ArrayList<>(4);
|
||||
List<String> mImgList;
|
||||
private OnItemClickListener mListener;
|
||||
|
||||
public FullScreenOnlineImagePagerAdapter(Context context, List<String> imgList) {
|
||||
this.mContext = context;
|
||||
createImageViews();
|
||||
mImgList = imgList;
|
||||
}
|
||||
|
||||
private void createImageViews() {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
PhotoView imageView = new PhotoView(mContext);
|
||||
imageView.setAdjustViewBounds(true);
|
||||
viewList.add(imageView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mImgList == null ? 0 : mImgList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewFromObject(View view, Object object) {
|
||||
return view == object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||
if (object instanceof PhotoView) {
|
||||
PhotoView view = (PhotoView) object;
|
||||
view.setImageDrawable(null);
|
||||
viewList.add(view);
|
||||
container.removeView(view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, final int position) {
|
||||
final PhotoView currentView = viewList.remove(0);
|
||||
final String image = mImgList.get(position);
|
||||
container.addView(currentView);
|
||||
|
||||
Glide.with(mContext).asBitmap()
|
||||
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
|
||||
.load(image).into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
int bw = resource.getWidth();
|
||||
int bh = resource.getHeight();
|
||||
if (bw > 8192 || bh > 8192) {
|
||||
Bitmap bitmap = ImageUtil.zoomBitmap(resource, 8192, 8192);
|
||||
setBitmap(currentView, bitmap);
|
||||
} else {
|
||||
setBitmap(currentView, resource);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
currentView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mListener != null) {
|
||||
// mListener.onItemClick(position, image);
|
||||
}
|
||||
}
|
||||
});
|
||||
return currentView;
|
||||
}
|
||||
|
||||
private void setBitmap(PhotoView imageView, Bitmap bitmap) {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
if (bitmap != null) {
|
||||
int bw = bitmap.getWidth();
|
||||
int bh = bitmap.getHeight();
|
||||
int vw = imageView.getWidth();
|
||||
int vh = imageView.getHeight();
|
||||
if (bw != 0 && bh != 0 && vw != 0 && vh != 0) {
|
||||
if (1.0f * bh / bw > 1.0f * vh / vw) {
|
||||
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
float offset = (1.0f * bh * vw / bw - vh) / 2;
|
||||
adjustOffset(imageView, offset);
|
||||
} else {
|
||||
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener l) {
|
||||
mListener = l;
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(int position, Image image);
|
||||
}
|
||||
|
||||
private void adjustOffset(PhotoView view, float offset) {
|
||||
PhotoViewAttacher attacher = view.getAttacher();
|
||||
try {
|
||||
Field field = PhotoViewAttacher.class.getDeclaredField("mBaseMatrix");
|
||||
field.setAccessible(true);
|
||||
Matrix matrix = (Matrix) field.get(attacher);
|
||||
matrix.postTranslate(0, offset);
|
||||
Method method = PhotoViewAttacher.class.getDeclaredMethod("resetMatrix");
|
||||
method.setAccessible(true);
|
||||
method.invoke(attacher);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
288
app/src/main/java/imageselector/adapter/ImageAdapter.java
Normal file
288
app/src/main/java/imageselector/adapter/ImageAdapter.java
Normal file
@@ -0,0 +1,288 @@
|
||||
package imageselector.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.sl.house_property.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import imageselector.entry.Image;
|
||||
|
||||
|
||||
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ViewHolder> {
|
||||
|
||||
private Context mContext;
|
||||
private ArrayList<Image> mImages;
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
//保存选中的图片
|
||||
private ArrayList<Image> mSelectImages = new ArrayList<>();
|
||||
private OnImageSelectListener mSelectListener;
|
||||
private OnItemClickListener mItemClickListener;
|
||||
private int mMaxCount;
|
||||
private boolean isSingle;
|
||||
private boolean isViewImage;
|
||||
|
||||
private static final int TYPE_CAMERA = 1;
|
||||
private static final int TYPE_IMAGE = 2;
|
||||
|
||||
private boolean useCamera;
|
||||
|
||||
/**
|
||||
* @param maxCount 图片的最大选择数量,小于等于0时,不限数量,isSingle为false时才有用。
|
||||
* @param isSingle 是否单选
|
||||
* @param isViewImage 是否点击放大图片查看
|
||||
*/
|
||||
public ImageAdapter(Context context, int maxCount, boolean isSingle, boolean isViewImage) {
|
||||
mContext = context;
|
||||
this.mInflater = LayoutInflater.from(mContext);
|
||||
mMaxCount = maxCount;
|
||||
this.isSingle = isSingle;
|
||||
this.isViewImage = isViewImage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
if (viewType == TYPE_IMAGE) {
|
||||
View view = mInflater.inflate(R.layout.adapter_images_item, parent, false);
|
||||
return new ViewHolder(view);
|
||||
} else {
|
||||
View view = mInflater.inflate(R.layout.adapter_camera, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final ViewHolder holder, int position) {
|
||||
if (getItemViewType(position) == TYPE_IMAGE) {
|
||||
final Image image = getImage(position);
|
||||
Glide.with(mContext).load(new File(image.getPath()))
|
||||
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
|
||||
.into(holder.ivImage);
|
||||
|
||||
setItemSelect(holder, mSelectImages.contains(image));
|
||||
|
||||
holder.ivGif.setVisibility(image.isGif() ? View.VISIBLE : View.GONE);
|
||||
|
||||
//点击选中/取消选中图片
|
||||
holder.ivSelectIcon.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
checkedImage(holder, image);
|
||||
}
|
||||
});
|
||||
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (isViewImage) {
|
||||
if (mItemClickListener != null) {
|
||||
int p = holder.getAdapterPosition();
|
||||
mItemClickListener.OnItemClick(image, useCamera ? p - 1 : p);
|
||||
}
|
||||
} else {
|
||||
checkedImage(holder, image);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (getItemViewType(position) == TYPE_CAMERA) {
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mItemClickListener != null) {
|
||||
mItemClickListener.OnCameraClick();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (useCamera && position == 0) {
|
||||
return TYPE_CAMERA;
|
||||
} else {
|
||||
return TYPE_IMAGE;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkedImage(ViewHolder holder, Image image) {
|
||||
if (mSelectImages.contains(image)) {
|
||||
//如果图片已经选中,就取消选中
|
||||
unSelectImage(image);
|
||||
setItemSelect(holder, false);
|
||||
} else if (isSingle) {
|
||||
//如果是单选,就先清空已经选中的图片,再选中当前图片
|
||||
clearImageSelect();
|
||||
selectImage(image);
|
||||
setItemSelect(holder, true);
|
||||
} else if (mMaxCount <= 0 || mSelectImages.size() < mMaxCount) {
|
||||
//如果不限制图片的选中数量,或者图片的选中数量
|
||||
// 还没有达到最大限制,就直接选中当前图片。
|
||||
selectImage(image);
|
||||
setItemSelect(holder, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 选中图片
|
||||
*
|
||||
* @param image
|
||||
*/
|
||||
private void selectImage(Image image) {
|
||||
mSelectImages.add(image);
|
||||
if (mSelectListener != null) {
|
||||
mSelectListener.OnImageSelect(image, true, mSelectImages.size());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消选中图片
|
||||
*
|
||||
* @param image
|
||||
*/
|
||||
private void unSelectImage(Image image) {
|
||||
mSelectImages.remove(image);
|
||||
if (mSelectListener != null) {
|
||||
mSelectListener.OnImageSelect(image, false, mSelectImages.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return useCamera ? getImageCount() + 1 : getImageCount();
|
||||
}
|
||||
|
||||
private int getImageCount() {
|
||||
return mImages == null ? 0 : mImages.size();
|
||||
}
|
||||
|
||||
public ArrayList<Image> getData() {
|
||||
return mImages;
|
||||
}
|
||||
|
||||
public void refresh(ArrayList<Image> data, boolean useCamera) {
|
||||
mImages = data;
|
||||
this.useCamera = useCamera;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private Image getImage(int position) {
|
||||
return mImages.get(useCamera ? position - 1 : position);
|
||||
}
|
||||
|
||||
public Image getFirstVisibleImage(int firstVisibleItem) {
|
||||
if (mImages != null && !mImages.isEmpty()) {
|
||||
if (useCamera) {
|
||||
return mImages.get(firstVisibleItem == 0 ? 0 : firstVisibleItem - 1);
|
||||
} else {
|
||||
return mImages.get(firstVisibleItem);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置图片选中和未选中的效果
|
||||
*/
|
||||
private void setItemSelect(ViewHolder holder, boolean isSelect) {
|
||||
if (isSelect) {
|
||||
holder.ivSelectIcon.setImageResource(R.drawable.icon_image_select);
|
||||
holder.ivMasking.setAlpha(0.5f);
|
||||
} else {
|
||||
holder.ivSelectIcon.setImageResource(R.drawable.icon_image_un_select);
|
||||
holder.ivMasking.setAlpha(0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearImageSelect() {
|
||||
if (mImages != null && mSelectImages.size() == 1) {
|
||||
int index = mImages.indexOf(mSelectImages.get(0));
|
||||
mSelectImages.clear();
|
||||
if (index != -1) {
|
||||
notifyItemChanged(useCamera ? index + 1 : index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedImages(ArrayList<String> selected) {
|
||||
if (mImages != null && selected != null) {
|
||||
for (String path : selected) {
|
||||
if (isFull()) {
|
||||
return;
|
||||
}
|
||||
for (Image image : mImages) {
|
||||
if (path.equals(image.getPath())) {
|
||||
if (!mSelectImages.contains(image)) {
|
||||
mSelectImages.add(image);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean isFull() {
|
||||
if (isSingle && mSelectImages.size() == 1) {
|
||||
return true;
|
||||
} else if (mMaxCount > 0 && mSelectImages.size() == mMaxCount) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Image> getSelectImages() {
|
||||
return mSelectImages;
|
||||
}
|
||||
|
||||
public void setOnImageSelectListener(OnImageSelectListener listener) {
|
||||
this.mSelectListener = listener;
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener listener) {
|
||||
this.mItemClickListener = listener;
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
ImageView ivImage;
|
||||
ImageView ivSelectIcon;
|
||||
ImageView ivMasking;
|
||||
ImageView ivGif;
|
||||
ImageView ivCamera;
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ivImage = itemView.findViewById(R.id.iv_image);
|
||||
ivSelectIcon = itemView.findViewById(R.id.iv_select);
|
||||
ivMasking = itemView.findViewById(R.id.iv_masking);
|
||||
ivGif = itemView.findViewById(R.id.iv_gif);
|
||||
|
||||
ivCamera = itemView.findViewById(R.id.iv_camera);
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnImageSelectListener {
|
||||
void OnImageSelect(Image image, boolean isSelect, int selectCount);
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void OnItemClick(Image image, int position);
|
||||
|
||||
void OnCameraClick();
|
||||
}
|
||||
}
|
||||
151
app/src/main/java/imageselector/adapter/ImagePagerAdapter.java
Normal file
151
app/src/main/java/imageselector/adapter/ImagePagerAdapter.java
Normal file
@@ -0,0 +1,151 @@
|
||||
package imageselector.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Matrix;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.github.chrisbanes.photoview.PhotoView;
|
||||
import com.github.chrisbanes.photoview.PhotoViewAttacher;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import imageselector.entry.Image;
|
||||
import imageselector.utils.ImageUtil;
|
||||
|
||||
|
||||
public class ImagePagerAdapter extends PagerAdapter {
|
||||
|
||||
private Context mContext;
|
||||
private List<PhotoView> viewList = new ArrayList<>(4);
|
||||
List<Image> mImgList;
|
||||
private OnItemClickListener mListener;
|
||||
|
||||
public ImagePagerAdapter(Context context, List<Image> imgList) {
|
||||
this.mContext = context;
|
||||
createImageViews();
|
||||
mImgList = imgList;
|
||||
}
|
||||
|
||||
private void createImageViews() {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
PhotoView imageView = new PhotoView(mContext);
|
||||
imageView.setAdjustViewBounds(true);
|
||||
viewList.add(imageView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mImgList == null ? 0 : mImgList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewFromObject(View view, Object object) {
|
||||
return view == object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||
if (object instanceof PhotoView) {
|
||||
PhotoView view = (PhotoView) object;
|
||||
view.setImageDrawable(null);
|
||||
viewList.add(view);
|
||||
container.removeView(view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, final int position) {
|
||||
final PhotoView currentView = viewList.remove(0);
|
||||
final Image image = mImgList.get(position);
|
||||
container.addView(currentView);
|
||||
if (image.isGif()) {
|
||||
currentView.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||
Glide.with(mContext).load(new File(image.getPath()))
|
||||
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
|
||||
.into(currentView);
|
||||
} else {
|
||||
Glide.with(mContext).asBitmap()
|
||||
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
|
||||
.load(new File(image.getPath())).into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
int bw = resource.getWidth();
|
||||
int bh = resource.getHeight();
|
||||
if (bw > 8192 || bh > 8192) {
|
||||
Bitmap bitmap = ImageUtil.zoomBitmap(resource, 8192, 8192);
|
||||
setBitmap(currentView, bitmap);
|
||||
} else {
|
||||
setBitmap(currentView, resource);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
currentView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mListener != null) {
|
||||
mListener.onItemClick(position, image);
|
||||
}
|
||||
}
|
||||
});
|
||||
return currentView;
|
||||
}
|
||||
|
||||
private void setBitmap(PhotoView imageView, Bitmap bitmap) {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
if (bitmap != null) {
|
||||
int bw = bitmap.getWidth();
|
||||
int bh = bitmap.getHeight();
|
||||
int vw = imageView.getWidth();
|
||||
int vh = imageView.getHeight();
|
||||
if (bw != 0 && bh != 0 && vw != 0 && vh != 0) {
|
||||
if (1.0f * bh / bw > 1.0f * vh / vw) {
|
||||
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
float offset = (1.0f * bh * vw / bw - vh) / 2;
|
||||
adjustOffset(imageView, offset);
|
||||
} else {
|
||||
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener l) {
|
||||
mListener = l;
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(int position, Image image);
|
||||
}
|
||||
|
||||
private void adjustOffset(PhotoView view, float offset) {
|
||||
PhotoViewAttacher attacher = view.getAttacher();
|
||||
try {
|
||||
Field field = PhotoViewAttacher.class.getDeclaredField("mBaseMatrix");
|
||||
field.setAccessible(true);
|
||||
Matrix matrix = (Matrix) field.get(attacher);
|
||||
matrix.postTranslate(0, offset);
|
||||
Method method = PhotoViewAttacher.class.getDeclaredMethod("resetMatrix");
|
||||
method.setAccessible(true);
|
||||
method.invoke(attacher);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
67
app/src/main/java/imageselector/entry/Folder.java
Normal file
67
app/src/main/java/imageselector/entry/Folder.java
Normal file
@@ -0,0 +1,67 @@
|
||||
package imageselector.entry;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import imageselector.utils.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* 图片文件夹实体类
|
||||
*/
|
||||
public class Folder {
|
||||
|
||||
private boolean useCamera; // 是否可以调用相机拍照。只有“全部”文件夹才可以拍照
|
||||
private String name;
|
||||
private ArrayList<Image> images;
|
||||
|
||||
public Folder(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Folder(String name, ArrayList<Image> images) {
|
||||
this.name = name;
|
||||
this.images = images;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ArrayList<Image> getImages() {
|
||||
return images;
|
||||
}
|
||||
|
||||
public void setImages(ArrayList<Image> images) {
|
||||
this.images = images;
|
||||
}
|
||||
|
||||
public boolean isUseCamera() {
|
||||
return useCamera;
|
||||
}
|
||||
|
||||
public void setUseCamera(boolean useCamera) {
|
||||
this.useCamera = useCamera;
|
||||
}
|
||||
|
||||
public void addImage(Image image) {
|
||||
if (image != null && StringUtils.isNotEmptyString(image.getPath())) {
|
||||
if (images == null) {
|
||||
images = new ArrayList<>();
|
||||
}
|
||||
images.add(image);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Folder{" +
|
||||
"name='" + name + '\'' +
|
||||
", images=" + images +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
90
app/src/main/java/imageselector/entry/Image.java
Normal file
90
app/src/main/java/imageselector/entry/Image.java
Normal file
@@ -0,0 +1,90 @@
|
||||
package imageselector.entry;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
*图片实体类
|
||||
*/
|
||||
public class Image implements Parcelable {
|
||||
|
||||
private String path;
|
||||
private long time;
|
||||
private String name;
|
||||
private String mimeType;
|
||||
|
||||
public Image(String path, long time, String name,String mimeType) {
|
||||
this.path = path;
|
||||
this.time = time;
|
||||
this.name = name;
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
public void setMimeType(String mimeType) {
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
public boolean isGif(){
|
||||
return "image/gif".equals(mimeType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.path);
|
||||
dest.writeLong(this.time);
|
||||
dest.writeString(this.name);
|
||||
dest.writeString(this.mimeType);
|
||||
}
|
||||
|
||||
protected Image(Parcel in) {
|
||||
this.path = in.readString();
|
||||
this.time = in.readLong();
|
||||
this.name = in.readString();
|
||||
this.mimeType = in.readString();
|
||||
}
|
||||
|
||||
public static final Creator<Image> CREATOR = new Creator<Image>() {
|
||||
@Override
|
||||
public Image createFromParcel(Parcel source) {
|
||||
return new Image(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image[] newArray(int size) {
|
||||
return new Image[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
159
app/src/main/java/imageselector/model/ImageModel.java
Normal file
159
app/src/main/java/imageselector/model/ImageModel.java
Normal file
@@ -0,0 +1,159 @@
|
||||
package imageselector.model;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.provider.MediaStore;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import imageselector.entry.Folder;
|
||||
import imageselector.entry.Image;
|
||||
import imageselector.utils.StringUtils;
|
||||
|
||||
|
||||
public class ImageModel {
|
||||
|
||||
/**
|
||||
* 从SDCard加载图片
|
||||
*
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
public static void loadImageForSDCard(final Context context, final DataCallback callback) {
|
||||
//由于扫描图片是耗时的操作,所以要在子线程处理。
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//扫描图片
|
||||
Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
ContentResolver mContentResolver = context.getContentResolver();
|
||||
|
||||
Cursor mCursor = mContentResolver.query(mImageUri, new String[]{
|
||||
MediaStore.Images.Media.DATA,
|
||||
MediaStore.Images.Media.DISPLAY_NAME,
|
||||
MediaStore.Images.Media.DATE_ADDED,
|
||||
MediaStore.Images.Media._ID,
|
||||
MediaStore.Images.Media.MIME_TYPE},
|
||||
null,
|
||||
null,
|
||||
MediaStore.Images.Media.DATE_ADDED);
|
||||
|
||||
ArrayList<Image> images = new ArrayList<>();
|
||||
|
||||
//读取扫描到的图片
|
||||
if (mCursor != null) {
|
||||
while (mCursor.moveToNext()) {
|
||||
// 获取图片的路径
|
||||
String path = mCursor.getString(
|
||||
mCursor.getColumnIndex(MediaStore.Images.Media.DATA));
|
||||
//获取图片名称
|
||||
String name = mCursor.getString(
|
||||
mCursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));
|
||||
//获取图片时间
|
||||
long time = mCursor.getLong(
|
||||
mCursor.getColumnIndex(MediaStore.Images.Media.DATE_ADDED));
|
||||
|
||||
//获取图片类型
|
||||
String mimeType = mCursor.getString(
|
||||
mCursor.getColumnIndex(MediaStore.Images.Media.MIME_TYPE));
|
||||
|
||||
//过滤未下载完成或者不存在的文件
|
||||
if (!"downloading".equals(getExtensionName(path)) && checkImgExists(path)) {
|
||||
images.add(new Image(path, time, name, mimeType));
|
||||
}
|
||||
}
|
||||
mCursor.close();
|
||||
}
|
||||
Collections.reverse(images);
|
||||
callback.onSuccess(splitFolder(images));
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查图片是否存在。ContentResolver查询处理的数据有可能文件路径并不存在。
|
||||
*
|
||||
* @param filePath
|
||||
* @return
|
||||
*/
|
||||
private static boolean checkImgExists(String filePath) {
|
||||
return new File(filePath).exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* 把图片按文件夹拆分,第一个文件夹保存所有的图片
|
||||
*
|
||||
* @param images
|
||||
* @return
|
||||
*/
|
||||
private static ArrayList<Folder> splitFolder(ArrayList<Image> images) {
|
||||
ArrayList<Folder> folders = new ArrayList<>();
|
||||
folders.add(new Folder("全部图片", images));
|
||||
|
||||
if (images != null && !images.isEmpty()) {
|
||||
int size = images.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
String path = images.get(i).getPath();
|
||||
String name = getFolderName(path);
|
||||
if (StringUtils.isNotEmptyString(name)) {
|
||||
Folder folder = getFolder(name, folders);
|
||||
folder.addImage(images.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return folders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Java文件操作 获取文件扩展名
|
||||
*/
|
||||
public static String getExtensionName(String filename) {
|
||||
if (filename != null && filename.length() > 0) {
|
||||
int dot = filename.lastIndexOf('.');
|
||||
if (dot > -1 && dot < filename.length() - 1) {
|
||||
return filename.substring(dot + 1);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据图片路径,获取图片文件夹名称
|
||||
*
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private static String getFolderName(String path) {
|
||||
if (StringUtils.isNotEmptyString(path)) {
|
||||
String[] strings = path.split(File.separator);
|
||||
if (strings.length >= 2) {
|
||||
return strings[strings.length - 2];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static Folder getFolder(String name, List<Folder> folders) {
|
||||
if (!folders.isEmpty()) {
|
||||
int size = folders.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
Folder folder = folders.get(i);
|
||||
if (name.equals(folder.getName())) {
|
||||
return folder;
|
||||
}
|
||||
}
|
||||
}
|
||||
Folder newFolder = new Folder(name);
|
||||
folders.add(newFolder);
|
||||
return newFolder;
|
||||
}
|
||||
|
||||
public interface DataCallback {
|
||||
void onSuccess(ArrayList<Folder> folders);
|
||||
}
|
||||
}
|
||||
42
app/src/main/java/imageselector/utils/DateUtils.java
Normal file
42
app/src/main/java/imageselector/utils/DateUtils.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package imageselector.utils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateUtils {
|
||||
|
||||
public static String getImageTime(long time) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(new Date());
|
||||
Calendar imageTime = Calendar.getInstance();
|
||||
imageTime.setTimeInMillis(time);
|
||||
if (sameDay(calendar, imageTime)) {
|
||||
return "今天";
|
||||
} else if (sameWeek(calendar, imageTime)) {
|
||||
return "本周";
|
||||
} else if (sameMonth(calendar, imageTime)) {
|
||||
return "本月";
|
||||
} else {
|
||||
Date date = new Date(time);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM");
|
||||
return sdf.format(date);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean sameDay(Calendar calendar1, Calendar calendar2) {
|
||||
return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR)
|
||||
&& calendar1.get(Calendar.DAY_OF_YEAR) == calendar2.get(Calendar.DAY_OF_YEAR);
|
||||
}
|
||||
|
||||
public static boolean sameWeek(Calendar calendar1, Calendar calendar2) {
|
||||
return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR)
|
||||
&& calendar1.get(Calendar.WEEK_OF_YEAR) == calendar2.get(Calendar.WEEK_OF_YEAR);
|
||||
}
|
||||
|
||||
public static boolean sameMonth(Calendar calendar1, Calendar calendar2) {
|
||||
return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR)
|
||||
&& calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH);
|
||||
}
|
||||
|
||||
}
|
||||
174
app/src/main/java/imageselector/utils/ImageSelector.java
Normal file
174
app/src/main/java/imageselector/utils/ImageSelector.java
Normal file
@@ -0,0 +1,174 @@
|
||||
package imageselector.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import imageselector.ClipImageActivity;
|
||||
import imageselector.ImageSelectorActivity;
|
||||
|
||||
|
||||
/**
|
||||
* Depiction:
|
||||
* Author:lry
|
||||
* Date:2018/6/25
|
||||
*/
|
||||
public class ImageSelector {
|
||||
|
||||
/**
|
||||
* 图片选择的结果
|
||||
*/
|
||||
public static final String SELECT_RESULT = "select_result";
|
||||
|
||||
/**
|
||||
* 是否是来自于相机拍照的图片,
|
||||
* 只有本次调用相机拍出来的照片,返回时才为true。
|
||||
* 当为true时,图片返回当结果有且只有一张图片。
|
||||
*/
|
||||
public static final String IS_CAMERA_IMAGE = "is_camera_image";
|
||||
|
||||
//最大的图片选择数
|
||||
public static final String MAX_SELECT_COUNT = "max_select_count";
|
||||
//是否单选
|
||||
public static final String IS_SINGLE = "is_single";
|
||||
//是否点击放大图片查看
|
||||
public static final String IS_VIEW_IMAGE = "is_view_image";
|
||||
//是否使用拍照功能
|
||||
public static final String USE_CAMERA = "is_camera";
|
||||
//原来已选择的图片
|
||||
public static final String SELECTED = "selected";
|
||||
//初始位置
|
||||
public static final String POSITION = "position";
|
||||
|
||||
public static final String IS_CONFIRM = "is_confirm";
|
||||
|
||||
public static final int RESULT_CODE = 0x00000012;
|
||||
|
||||
public static ImageSelectorBuilder builder() {
|
||||
return new ImageSelectorBuilder();
|
||||
}
|
||||
|
||||
public static class ImageSelectorBuilder {
|
||||
|
||||
private boolean isCrop = false;
|
||||
private boolean useCamera = true;
|
||||
private boolean isSingle = false;
|
||||
private boolean isViewImage = true;
|
||||
private int maxSelectCount;
|
||||
private ArrayList<String> selected;
|
||||
|
||||
/**
|
||||
* 是否使用图片剪切功能。默认false。如果使用了图片剪切功能,相册只能单选。
|
||||
*
|
||||
* @param isCrop
|
||||
* @return
|
||||
*/
|
||||
public ImageSelectorBuilder setCrop(boolean isCrop) {
|
||||
this.isCrop = isCrop;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否单选
|
||||
*
|
||||
* @param isSingle
|
||||
* @return
|
||||
*/
|
||||
public ImageSelectorBuilder setSingle(boolean isSingle) {
|
||||
this.isSingle = isSingle;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否点击放大图片查看,,默认为true
|
||||
*
|
||||
* @param isViewImage
|
||||
* @return
|
||||
*/
|
||||
public ImageSelectorBuilder setViewImage(boolean isViewImage) {
|
||||
this.isViewImage = isViewImage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否使用拍照功能。
|
||||
*
|
||||
* @param useCamera 默认为true
|
||||
* @return
|
||||
*/
|
||||
public ImageSelectorBuilder useCamera(boolean useCamera) {
|
||||
this.useCamera = useCamera;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片的最大选择数量,小于等于0时,不限数量,isSingle为false时才有用。
|
||||
*
|
||||
* @param maxSelectCount
|
||||
* @return
|
||||
*/
|
||||
public ImageSelectorBuilder setMaxSelectCount(int maxSelectCount) {
|
||||
this.maxSelectCount = maxSelectCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收从外面传进来的已选择的图片列表。当用户原来已经有选择过图片,现在重新打开
|
||||
* 选择器,允许用户把先前选过的图片传进来,并把这些图片默认为选中状态。
|
||||
*
|
||||
* @param selected
|
||||
* @return
|
||||
*/
|
||||
public ImageSelectorBuilder setSelected(ArrayList<String> selected) {
|
||||
this.selected = selected;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开相册
|
||||
*
|
||||
* @param activity
|
||||
* @param requestCode
|
||||
*/
|
||||
public void start(Activity activity, int requestCode) {
|
||||
if (isCrop) {
|
||||
ClipImageActivity.openActivity(activity, requestCode, isViewImage, useCamera, selected);
|
||||
} else {
|
||||
ImageSelectorActivity.openActivity(activity, requestCode, isSingle, isViewImage,
|
||||
useCamera, maxSelectCount, selected);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开相册
|
||||
*
|
||||
* @param fragment
|
||||
* @param requestCode
|
||||
*/
|
||||
public void start(Fragment fragment, int requestCode) {
|
||||
if (isCrop) {
|
||||
ClipImageActivity.openActivity(fragment, requestCode, isViewImage, useCamera, selected);
|
||||
} else {
|
||||
ImageSelectorActivity.openActivity(fragment, requestCode, isSingle, isViewImage,
|
||||
useCamera, maxSelectCount, selected);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开相册
|
||||
*
|
||||
* @param fragment
|
||||
* @param requestCode
|
||||
*/
|
||||
public void start(android.app.Fragment fragment, int requestCode) {
|
||||
if (isCrop) {
|
||||
ClipImageActivity.openActivity(fragment, requestCode, isViewImage, useCamera, selected);
|
||||
} else {
|
||||
ImageSelectorActivity.openActivity(fragment, requestCode, isSingle, isViewImage,
|
||||
useCamera, maxSelectCount, selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package imageselector.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import imageselector.ClipImageActivity;
|
||||
import imageselector.ImageSelectorActivity;
|
||||
|
||||
|
||||
/**
|
||||
* 提供给外界相册的调用的工具类
|
||||
*/
|
||||
@Deprecated
|
||||
public class ImageSelectorUtils {
|
||||
|
||||
//图片选择的结果
|
||||
public static final String SELECT_RESULT = ImageSelector.SELECT_RESULT;
|
||||
|
||||
/**
|
||||
* 打开相册,选择图片,可多选,不限数量。
|
||||
*
|
||||
* @param activity
|
||||
* @param requestCode
|
||||
*/
|
||||
public static void openPhoto(Activity activity, int requestCode) {
|
||||
openPhoto(activity, requestCode, false, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开相册,选择图片,可多选,不限数量。
|
||||
*
|
||||
* @param activity
|
||||
* @param requestCode
|
||||
* @param selected 接收从外面传进来的已选择的图片列表。当用户原来已经有选择过图片,现在重新打开
|
||||
* 选择器,允许用户把先前选过的图片传进来,并把这些图片默认为选中状态。
|
||||
*/
|
||||
public static void openPhoto(Activity activity, int requestCode, ArrayList<String> selected) {
|
||||
openPhoto(activity, requestCode, false, 0, selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开相册,选择图片,可多选,限制最大的选择数量。
|
||||
*
|
||||
* @param activity
|
||||
* @param requestCode
|
||||
* @param isSingle 是否单选
|
||||
* @param maxSelectCount 图片的最大选择数量,小于等于0时,不限数量,isSingle为false时才有用。
|
||||
*/
|
||||
public static void openPhoto(Activity activity, int requestCode,
|
||||
boolean isSingle, int maxSelectCount) {
|
||||
openPhoto(activity, requestCode, isSingle, maxSelectCount, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开相册,选择图片,可多选,限制最大的选择数量。
|
||||
*
|
||||
* @param activity
|
||||
* @param requestCode
|
||||
* @param isSingle 是否单选
|
||||
* @param maxSelectCount 图片的最大选择数量,小于等于0时,不限数量,isSingle为false时才有用。
|
||||
* @param selected 接收从外面传进来的已选择的图片列表。当用户原来已经有选择过图片,现在重新打开
|
||||
* 选择器,允许用户把先前选过的图片传进来,并把这些图片默认为选中状态。
|
||||
*/
|
||||
public static void openPhoto(Activity activity, int requestCode,
|
||||
boolean isSingle, int maxSelectCount, ArrayList<String> selected) {
|
||||
ImageSelectorActivity.openActivity(activity, requestCode, isSingle, true,
|
||||
true, maxSelectCount, selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开相册,单选图片并剪裁。
|
||||
*
|
||||
* @param activity
|
||||
* @param requestCode
|
||||
*/
|
||||
public static void openPhotoAndClip(Activity activity, int requestCode) {
|
||||
ClipImageActivity.openActivity(activity, requestCode, true, true, null);
|
||||
}
|
||||
}
|
||||
166
app/src/main/java/imageselector/utils/ImageUtil.java
Normal file
166
app/src/main/java/imageselector/utils/ImageUtil.java
Normal file
@@ -0,0 +1,166 @@
|
||||
package imageselector.utils;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.media.ExifInterface;
|
||||
import android.text.format.DateFormat;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
public class ImageUtil {
|
||||
|
||||
public static String saveImage(Bitmap bitmap, String path) {
|
||||
|
||||
String name = new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".png";
|
||||
FileOutputStream b = null;
|
||||
File file = new File(path);
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();// 创建文件夹
|
||||
}
|
||||
|
||||
String fileName = path + File.separator + name;
|
||||
|
||||
try {
|
||||
b = new FileOutputStream(fileName);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 75, b);// 把数据写入文件
|
||||
return fileName;
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (b != null) {
|
||||
b.flush();
|
||||
b.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static Bitmap zoomBitmap(Bitmap bm, int reqWidth, int reqHeight) {
|
||||
// 获得图片的宽高
|
||||
int width = bm.getWidth();
|
||||
int height = bm.getHeight();
|
||||
// 计算缩放比例
|
||||
float scaleWidth = ((float) reqWidth) / width;
|
||||
float scaleHeight = ((float) reqHeight) / height;
|
||||
float scale = Math.min(scaleWidth, scaleHeight);
|
||||
// 取得想要缩放的matrix参数
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postScale(scale, scale);
|
||||
// 得到新的图片
|
||||
Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix,
|
||||
true);
|
||||
return newbm;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据计算的inSampleSize,得到压缩后图片
|
||||
*
|
||||
* @param pathName
|
||||
* @param reqWidth
|
||||
* @param reqHeight
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap decodeSampledBitmapFromFile(String pathName, int reqWidth, int reqHeight) {
|
||||
|
||||
int degree = 0;
|
||||
|
||||
try {
|
||||
ExifInterface exifInterface = new ExifInterface(pathName);
|
||||
int result = exifInterface.getAttributeInt(
|
||||
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
|
||||
switch (result) {
|
||||
case ExifInterface.ORIENTATION_ROTATE_90:
|
||||
degree = 90;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_180:
|
||||
degree = 180;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_270:
|
||||
degree = 270;
|
||||
break;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
|
||||
final BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(pathName, options);
|
||||
// 调用上面定义的方法计算inSampleSize值
|
||||
options.inSampleSize = calculateInSampleSize(options, reqWidth,
|
||||
reqHeight);
|
||||
|
||||
// 使用获取到的inSampleSize值再次解析图片
|
||||
options.inJustDecodeBounds = false;
|
||||
// options.inPreferredConfig = Bitmap.Config.RGB_565;
|
||||
Bitmap bitmap = BitmapFactory.decodeFile(pathName, options);
|
||||
|
||||
if (degree != 0) {
|
||||
Bitmap newBitmap = rotateImageView(bitmap, degree);
|
||||
bitmap.recycle();
|
||||
bitmap = null;
|
||||
return newBitmap;
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
} catch (OutOfMemoryError error) {
|
||||
Log.e("eee", "内存泄露!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 旋转图片
|
||||
*
|
||||
* @param bitmap
|
||||
* @param angle
|
||||
* @return Bitmap
|
||||
*/
|
||||
public static Bitmap rotateImageView(Bitmap bitmap, int angle) {
|
||||
//旋转图片 动作
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postRotate(angle);
|
||||
// 创建新的图片
|
||||
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算inSampleSize,用于压缩图片
|
||||
*
|
||||
* @param options
|
||||
* @param reqWidth
|
||||
* @param reqHeight
|
||||
* @return
|
||||
*/
|
||||
private static int calculateInSampleSize(BitmapFactory.Options options,
|
||||
int reqWidth, int reqHeight) {
|
||||
// 源图片的宽度
|
||||
int width = options.outWidth;
|
||||
int height = options.outHeight;
|
||||
int inSampleSize = 1;
|
||||
|
||||
if (width > reqWidth && height > reqHeight) {
|
||||
// 计算出实际宽度和目标宽度的比率
|
||||
int widthRatio = Math.round((float) width / (float) reqWidth);
|
||||
int heightRatio = Math.round((float) height / (float) reqHeight);
|
||||
inSampleSize = Math.max(widthRatio, heightRatio);
|
||||
}
|
||||
|
||||
return inSampleSize;
|
||||
}
|
||||
|
||||
}
|
||||
12
app/src/main/java/imageselector/utils/StringUtils.java
Normal file
12
app/src/main/java/imageselector/utils/StringUtils.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package imageselector.utils;
|
||||
|
||||
public class StringUtils {
|
||||
|
||||
public static boolean isNotEmptyString(final String str) {
|
||||
return str != null && str.length() > 0;
|
||||
}
|
||||
|
||||
public static boolean isEmptyString(final String str) {
|
||||
return str == null || str.length() <= 0;
|
||||
}
|
||||
}
|
||||
357
app/src/main/java/imageselector/view/ClipImageView.java
Normal file
357
app/src/main/java/imageselector/view/ClipImageView.java
Normal file
@@ -0,0 +1,357 @@
|
||||
package imageselector.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Xfermode;
|
||||
import android.support.v7.widget.AppCompatImageView;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class ClipImageView extends AppCompatImageView {
|
||||
|
||||
private PointF mDownPoint;
|
||||
private PointF mMiddlePoint;
|
||||
private Matrix mMatrix;
|
||||
private Matrix mTempMatrix;
|
||||
|
||||
private int mBitmapWidth;
|
||||
private int mBitmapHeight;
|
||||
|
||||
private final int MODE_NONE = 0;
|
||||
private final int MODE_DRAG = 1;
|
||||
private final int MODE_ZOOM = 2;
|
||||
private final int MODE_POINTER_UP = 3;
|
||||
private int CURR_MODE = MODE_NONE;
|
||||
|
||||
private float mLastDistance;
|
||||
|
||||
private Paint mFrontGroundPaint = new Paint();
|
||||
private int mTargetWidth;
|
||||
private int mTargetHeight;
|
||||
private Xfermode mXfermode;
|
||||
private Rect r;
|
||||
private RectF rf;
|
||||
|
||||
private float mCircleCenterX, mCircleCenterY;
|
||||
private float mCircleX, mCircleY;
|
||||
private boolean isCutImage;
|
||||
|
||||
public ClipImageView(Context context) {
|
||||
super(context);
|
||||
setRadius();
|
||||
}
|
||||
|
||||
public ClipImageView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setRadius();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置要剪裁的图片
|
||||
*
|
||||
* @param bitmap
|
||||
*/
|
||||
public void setBitmapData(Bitmap bitmap) {
|
||||
|
||||
if (bitmap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBitmapHeight = bitmap.getHeight();
|
||||
mBitmapWidth = bitmap.getWidth();
|
||||
setImageBitmap(bitmap);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mDownPoint = new PointF();
|
||||
mMiddlePoint = new PointF();
|
||||
mMatrix = new Matrix();
|
||||
mTempMatrix = new Matrix();
|
||||
mFrontGroundPaint.setColor(Color.parseColor("#ac000000"));
|
||||
mFrontGroundPaint.setAntiAlias(true);
|
||||
mXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
|
||||
|
||||
setScaleType(ScaleType.MATRIX);
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
center();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
mCircleCenterX = getWidth() / 2;
|
||||
mCircleCenterY = getHeight() / 2;
|
||||
mCircleX = mCircleCenterX - mTargetWidth / 2;
|
||||
mCircleY = mCircleCenterY - mTargetHeight / 2;
|
||||
}
|
||||
|
||||
private void setRadius() {
|
||||
|
||||
int width = getScreenWidth(getContext());
|
||||
int height = getScreenHeight(getContext());
|
||||
|
||||
if (width > height) {
|
||||
mTargetWidth = height;
|
||||
mTargetHeight = height;
|
||||
} else {
|
||||
mTargetWidth = width;
|
||||
mTargetHeight = width;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
if (isCutImage) {
|
||||
return;
|
||||
}
|
||||
if (rf == null || rf.isEmpty()) {
|
||||
r = new Rect(0, 0, getWidth(), getHeight());
|
||||
rf = new RectF(r);
|
||||
}
|
||||
// 画入前景圆形蒙板层
|
||||
int sc = canvas.saveLayer(rf, null, Canvas.MATRIX_SAVE_FLAG
|
||||
| Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG
|
||||
| Canvas.FULL_COLOR_LAYER_SAVE_FLAG
|
||||
| Canvas.CLIP_TO_LAYER_SAVE_FLAG | Canvas.ALL_SAVE_FLAG);
|
||||
//画入矩形黑色半透明蒙板层
|
||||
canvas.drawRect(r, mFrontGroundPaint);
|
||||
//设置Xfermode,目的是为了去除矩形黑色半透明蒙板层和圆形的相交部分
|
||||
mFrontGroundPaint.setXfermode(mXfermode);
|
||||
//画入正方形
|
||||
canvas.drawRect(mCircleCenterX - mTargetWidth / 2, mCircleCenterY - mTargetHeight / 2,
|
||||
mCircleCenterX + mTargetWidth / 2, mCircleCenterY + mTargetHeight / 2, mFrontGroundPaint);
|
||||
|
||||
canvas.restoreToCount(sc);
|
||||
//清除Xfermode,防止影响下次画图
|
||||
mFrontGroundPaint.setXfermode(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 截取Bitmap
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Bitmap clipImage() {
|
||||
isCutImage = true;
|
||||
Paint paint = new Paint();
|
||||
setDrawingCacheEnabled(true);
|
||||
Bitmap bitmap = getDrawingCache();
|
||||
Bitmap targetBitmap = Bitmap.createBitmap(mTargetWidth, mTargetHeight,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(targetBitmap);
|
||||
RectF dst = new RectF(-bitmap.getWidth() / 2 + mTargetWidth / 2, -getHeight()
|
||||
/ 2 + mTargetHeight / 2, bitmap.getWidth() / 2
|
||||
+ mTargetWidth / 2, getHeight() / 2 + mTargetHeight / 2);
|
||||
|
||||
canvas.drawBitmap(bitmap, null, dst, paint);
|
||||
setDrawingCacheEnabled(false);
|
||||
bitmap.recycle();
|
||||
bitmap = null;
|
||||
isCutImage = false;
|
||||
//返回正方形图片
|
||||
return targetBitmap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
|
||||
if (mMatrix == null) {
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
float[] values = new float[9];
|
||||
mMatrix.getValues(values);
|
||||
float left = values[Matrix.MTRANS_X];
|
||||
float top = values[Matrix.MTRANS_Y];
|
||||
float right = (left + mBitmapWidth * values[Matrix.MSCALE_X]);
|
||||
float bottom = (top + mBitmapHeight * values[Matrix.MSCALE_Y]);
|
||||
float x = 0f;
|
||||
float y = 0f;
|
||||
|
||||
switch (event.getAction() & MotionEvent.ACTION_MASK) {
|
||||
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
CURR_MODE = MODE_DRAG;
|
||||
mDownPoint.set(event.getX(), event.getY());
|
||||
break;
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
if (getDistance(event) > 10f) {
|
||||
CURR_MODE = MODE_ZOOM;
|
||||
midPoint(mMiddlePoint, event);
|
||||
mLastDistance = getDistance(event);
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
//如果当前模式为拖曳(单指触屏)
|
||||
if (CURR_MODE == MODE_DRAG || CURR_MODE == MODE_POINTER_UP) {
|
||||
if (CURR_MODE == MODE_DRAG) {
|
||||
|
||||
x = event.getX() - mDownPoint.x;
|
||||
y = event.getY() - mDownPoint.y;
|
||||
//left靠边
|
||||
if (x + left > mCircleX) {
|
||||
x = 0;
|
||||
}
|
||||
//right靠边
|
||||
if (x + right < mCircleX + mTargetWidth) {
|
||||
x = 0;
|
||||
}
|
||||
//top靠边
|
||||
if (y + top > mCircleY) {
|
||||
y = 0;
|
||||
}
|
||||
//bottom靠边
|
||||
if (y + bottom < mCircleY + mTargetHeight) {
|
||||
y = 0;
|
||||
}
|
||||
mMatrix.postTranslate(x, y);
|
||||
mDownPoint.set(event.getX(), event.getY());
|
||||
|
||||
} else {
|
||||
CURR_MODE = MODE_DRAG;
|
||||
mDownPoint.set(event.getX(), event.getY());
|
||||
}
|
||||
} else {
|
||||
//否则当前模式为缩放(双指触屏)
|
||||
float distance = getDistance(event);
|
||||
if (distance > 10f) {
|
||||
float scale = distance / mLastDistance;
|
||||
|
||||
//left靠边
|
||||
if (left >= mCircleX) {
|
||||
mMiddlePoint.x = 0;
|
||||
}
|
||||
//right靠边
|
||||
if (right <= mCircleX + mTargetWidth) {
|
||||
mMiddlePoint.x = right;
|
||||
}
|
||||
//top靠边
|
||||
if (top >= mCircleY) {
|
||||
mMiddlePoint.y = 0;
|
||||
}
|
||||
//bottom靠边
|
||||
if (bottom <= mCircleY + mTargetHeight) {
|
||||
mMiddlePoint.y = bottom;
|
||||
}
|
||||
mTempMatrix.set(mMatrix);
|
||||
mTempMatrix.postScale(scale, scale, mMiddlePoint.x, mMiddlePoint.y);
|
||||
|
||||
float[] temp_values = new float[9];
|
||||
mTempMatrix.getValues(temp_values);
|
||||
float temp_left = temp_values[Matrix.MTRANS_X];
|
||||
float temp_top = temp_values[Matrix.MTRANS_Y];
|
||||
float temp_right = (temp_left + mBitmapWidth * temp_values[Matrix.MSCALE_X]);
|
||||
float temp_bottom = (temp_top + mBitmapHeight * temp_values[Matrix.MSCALE_Y]);
|
||||
//靠边预判断
|
||||
if (temp_left > mCircleX || temp_right < mCircleX + mTargetWidth ||
|
||||
temp_top > mCircleY || temp_bottom < mCircleY + mTargetHeight) {
|
||||
return true;
|
||||
}
|
||||
mMatrix.postScale(scale, scale, mMiddlePoint.x, mMiddlePoint.y);
|
||||
mLastDistance = getDistance(event);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
CURR_MODE = MODE_NONE;
|
||||
break;
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
CURR_MODE = MODE_POINTER_UP;
|
||||
break;
|
||||
}
|
||||
setImageMatrix(mMatrix);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 两点的距离
|
||||
*/
|
||||
private float getDistance(MotionEvent event) {
|
||||
float x = event.getX(0) - event.getX(1);
|
||||
float y = event.getY(0) - event.getY(1);
|
||||
return (float) Math.sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
/**
|
||||
* 两点的中点
|
||||
*/
|
||||
private void midPoint(PointF point, MotionEvent event) {
|
||||
float x = event.getX(0) + event.getX(1);
|
||||
float y = event.getY(0) + event.getY(1);
|
||||
point.set(x / 2, y / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 横向、纵向居中
|
||||
*/
|
||||
protected void center() {
|
||||
|
||||
float height = mBitmapHeight;
|
||||
float width = mBitmapWidth;
|
||||
float screenWidth = getWidth();
|
||||
float screenHeight = getHeight();
|
||||
float scale = 1f;
|
||||
if (width >= height) {
|
||||
scale = screenWidth / width;
|
||||
|
||||
if (scale * height < mTargetHeight) {
|
||||
scale = mTargetHeight / height;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (height <= screenHeight) {
|
||||
scale = screenWidth / width;
|
||||
} else {
|
||||
scale = screenHeight / height;
|
||||
}
|
||||
|
||||
if (scale * width < mTargetWidth) {
|
||||
scale = mTargetWidth / width;
|
||||
}
|
||||
}
|
||||
|
||||
float deltaX = (screenWidth - width * scale) / 2f;
|
||||
float deltaY = (screenHeight - height * scale) / 2f;
|
||||
mMatrix.postScale(scale, scale);
|
||||
mMatrix.postTranslate(deltaX, deltaY);
|
||||
setImageMatrix(mMatrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得屏幕宽度
|
||||
*/
|
||||
public static int getScreenWidth(Context context) {
|
||||
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
DisplayMetrics outMetrics = new DisplayMetrics();
|
||||
wm.getDefaultDisplay().getMetrics(outMetrics);
|
||||
return outMetrics.widthPixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得屏幕高度
|
||||
*/
|
||||
public static int getScreenHeight(Context context) {
|
||||
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
DisplayMetrics outMetrics = new DisplayMetrics();
|
||||
wm.getDefaultDisplay().getMetrics(outMetrics);
|
||||
return outMetrics.heightPixels;
|
||||
}
|
||||
}
|
||||
30
app/src/main/java/imageselector/view/MyViewPager.java
Normal file
30
app/src/main/java/imageselector/view/MyViewPager.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package imageselector.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* 继承ViewPager并在onInterceptTouchEvent捕捉异常。
|
||||
* 因为ViewPager嵌套PhotoView使用,有时候会发生IllegalArgumentException异常。
|
||||
*/
|
||||
public class MyViewPager extends ViewPager {
|
||||
|
||||
public MyViewPager(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public MyViewPager(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
try {
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
app/src/main/java/imageselector/view/SquareImageView.java
Normal file
28
app/src/main/java/imageselector/view/SquareImageView.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package imageselector.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.AppCompatImageView;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
/**
|
||||
* 正方形的ImageView
|
||||
*/
|
||||
public class SquareImageView extends AppCompatImageView {
|
||||
|
||||
public SquareImageView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public SquareImageView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public SquareImageView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user