Android照片选择界面
Posted dorr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android照片选择界面相关的知识,希望对你有一定的参考价值。
package cc.vv.btongbaselibrary.ui.view.imagepicker;
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.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
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 android.widget.Toast;
import java.util.ArrayList;
import cc.vv.btongbaselibrary.R;
import cc.vv.btongbaselibrary.ui.view.imagepicker.adapter.FolderAdapter;
import cc.vv.btongbaselibrary.ui.view.imagepicker.adapter.ImageAdapter;
import cc.vv.btongbaselibrary.ui.view.imagepicker.entry.FolderObj;
import cc.vv.btongbaselibrary.ui.view.imagepicker.entry.ImageObj;
import cc.vv.btongbaselibrary.ui.view.imagepicker.model.ImageModel;
import cc.vv.btongbaselibrary.vFinal.BTResultCode;
/**
* 图片选择界面
*
* @author Zml
*/
public class ImageSelectorActivity extends AppCompatActivity {
public static final String KEY_MAX_SELECT_COUNT = "max_select_count";
public static final String KEY_IS_SINGLE = "is_single";
private static final String KEY_SELECTED = "selected";
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<FolderObj> mFolders;
private FolderObj mFolder;
private boolean isToSettings = false;
private static final int PERMISSION_REQUEST_CODE = 0X0011;
private boolean isOpenFolder;
private boolean isInitFolder;
private boolean isSingle;
private int mMaxCount;
/**
* 用于接收从外面传进来的已选择的图片列表。当用户原来已经有选择过图片,现在重新打开选择器,
* 允许用户把先前选过的图片传进来,并把这些图片默认为选中状态。
*/
private ArrayList<String> mSelectedImages;
/**
* 启动图片选择器
*
* @param activity
* @param requestCode
* @param isSingle 是否单选
* @param maxSelectCount 图片的最大选择数量,小于等于0时,不限数量,isSingle为false时才有用。
* @param selected 接收从外面传进来的已选择的图片列表。当用户原来已经有选择过图片,现在重新打开
* 选择器,允许用户把先前选过的图片传进来,并把这些图片默认为选中状态。
*/
public static void openActivity(Activity activity, int requestCode,
boolean isSingle, int maxSelectCount, ArrayList<String> selected) {
Intent intent = new Intent(activity, ImageSelectorActivity.class);
intent.putExtra(KEY_MAX_SELECT_COUNT, maxSelectCount);
intent.putExtra(KEY_IS_SINGLE, isSingle);
intent.putStringArrayListExtra(KEY_SELECTED, selected);
activity.startActivityForResult(intent, requestCode);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_select);
Intent intent = getIntent();
mMaxCount = intent.getIntExtra(KEY_MAX_SELECT_COUNT, 0);
isSingle = intent.getBooleanExtra(KEY_IS_SINGLE, false);
mSelectedImages = intent.getStringArrayListExtra(KEY_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 = findViewById(R.id.rv_image);
rvFolder = findViewById(R.id.rv_folder);
tvConfirm = findViewById(R.id.tv_confirm);
tvPreview = findViewById(R.id.tv_preview);
btnConfirm = findViewById(R.id.btn_confirm);
btnPreview = findViewById(R.id.btn_preview);
tvFolderName = findViewById(R.id.tv_folder_name);
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<ImageObj> 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();
}
});
}
/**
* 初始化图片列表
*/
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);
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(ImageObj image, boolean isSelect, int selectCount) {
setSelectImageCount(selectCount);
}
});
mAdapter.setOnItemClickListener(new ImageAdapter.OnItemClickListener() {
@Override
public void OnItemClick(ImageObj image, int position) {
toPreviewActivity(mAdapter.getData(), position);
}
});
}
/**
* 初始化图片文件夹列表
*/
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(FolderObj 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(FolderObj folder) {
if (folder != null && mAdapter != null && !folder.equals(mFolder)) {
mFolder = folder;
tvFolderName.setText(folder.getName());
rvImage.scrollToPosition(0);
mAdapter.refresh(folder.getImages());
}
}
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 confirm() {
if (mAdapter == null) {
return;
}
//因为图片的实体类是Image,而我们返回的是String数组,所以要进行转换。
ArrayList<ImageObj> selectImages = mAdapter.getSelectImages();
ArrayList<String> images = new ArrayList<>();
for (ImageObj image : selectImages) {
images.add(image.getPath());
}
//点击确定,把选中的图片通过Intent传给上一个Activity。
Intent intent = new Intent();
intent.putStringArrayListExtra(ImageGalleryUtil.SELECT_RESULT, images);
setResult(BTResultCode.ImageSelectorActivity_RESULT_CODE, intent);
finish();
}
private void toPreviewActivity(ArrayList<ImageObj> images, int position) {
if (images != null && !images.isEmpty()) {
PreviewActivity.openActivity(this, images,
mAdapter.getSelectImages(), isSingle, mMaxCount, position);
}
}
@Override
protected void onStart() {
super.onStart();
if (isToSettings) {
isToSettings = 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 == PreviewActivity.REQUEST_CODE) {
if (data != null && data.getBooleanExtra(PreviewActivity.KEY_IS_CONFIRM, false)) {
//如果用户在预览页点击了确定,就直接把用户选中的图片返回给用户。
confirm();
} else {
//否则,就刷新当前页面。
mAdapter.notifyDataSetChanged();
setSelectImageCount(mAdapter.getSelectImages().size());
}
}
}
/**
* 横竖屏切换处理
*
* @param newConfig
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
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 hasWriteContactsPermission = ContextCompat.checkSelfPermission(getApplication(),
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (hasWriteContactsPermission == PackageManager.PERMISSION_GRANTED) {
//有权限,加载图片。
loadImageForSDCard();
} else {
//没有权限,申请权限。
ActivityCompat.requestPermissions(ImageSelectorActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}
/**
* 处理权限申请的回调。
*
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//允许权限,加载图片。
loadImageForSDCard();
} else {
//拒绝权限,弹出提示框。
showExceptionDialog();
}
}
}
/**
* 发生没有权限等异常时,显示一个提示dialog.
*/
private void showExceptionDialog() {
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();
isToSettings = true;
}
}).show();
}
/**
* 从SDCard加载图片。
*/
private void loadImageForSDCard() {
ImageModel.loadImageForSDCard(this, new ImageModel.DataCallback() {
@Override
public void onSuccess(ArrayList<FolderObj> folders) {
mFolders = folders;
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mFolders != null && !mFolders.isEmpty()) {
initFolderList();
setFolder(mFolders.get(0));
if (mSelectedImages != null && mAdapter != null) {
mAdapter.setSelectedImages(mSelectedImages);
mSelectedImages = null;
}
}
}
});
}
});
}
/**
* 启动应用的设置
*/
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);
}
}
以上是关于Android照片选择界面的主要内容,如果未能解决你的问题,请参考以下文章
Android实现批量照片上传至server,拍照或者从相冊选择