Android photo selection interface

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;

/**
* Used to receive a list of selected images from outside. When the user has already selected a picture, and now reopen the selector,
* allows the user to pass in the pictures previously selected, and these pictures are selected as the default state.
*/
private ArrayList<String> mSelectedImages;

/**
* Start the image selector
*
* @param activity
* @param requestCode
* @param isSingle Whether single selection
* @param maxSelectCount The maximum number of images to select, if less than or equal to 0, unlimited Quantity, only useful when isSingle is false.
* @param selected Receive a list of selected images passed in from outside. When the user has already selected a picture, now reopen the
* selector, allowing the user to pass in the previously selected pictures, and these pictures will be selected by default.
*/
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);
}
}

/**
* The folder list is hidden by default at the beginning
*/
private void hideFolderList() {
rvFolder.post(new Runnable() {
@ Override
public void run() {
rvFolder.setTranslationY(rvFolder.getHeight());
rvFolder.setVisibility(View.GONE);
}
});
}

/**
* Set the selected folder and refresh the picture list at the same time
*
* @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;
}
//Because the entity class of the picture is Image, and we return a String array, So to convert.
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)) {
//If the user clicks OK on the preview page, directly return the image selected by the user to the user .
confirm();
} else {
//Otherwise, refresh the current page.
mAdapter.notifyDataSetChanged();
setSelectImageCount(mAdapter.getSelectImages().size());
}
}
}

/**
* Horizontal and vertical screen switching processing
*
* @param newConfig
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged (newConfig);
if (mLayoutManager != null && mAdapter != null) {
//Switch to portrait
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
mLayoutManager.setSpanCount(3);
}
//Switch to landscape
else if (newConfig. orientation == Configuration.ORIENTATION_LANDSCAPE) {
mLayoutManager.setSpanCount(5);
}
mAdapter.notifyDataSetChanged();
}
}

/**
* Check permissions and load images from SD card.
*/
private void checkPermissionAndLoadImages() {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Toast.makeText(this, "No picture", Toast.LENGTH_LONG).show();
return;
}
int hasWriteContactsPermission = ContextCompat.checkSelfPermission(getApplication(),
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (hasWriteContactsPermission == PackageManager.PERMISSION_GRANTED) {
//Have permission to load images.
loadImageForSDCard();
} else {
//No permission, apply for permission.
ActivityCompat.requestPermissions(ImageSelectorActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}

/**
* Callback for processing permission request.
*
* @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) {
//Allow permission, load image.
loadImageForSDCard();
} else {
//Permission denied, a prompt box pops up.
showExceptionDialog();
}
}
}

/**
* When an exception such as no permission occurs, display a prompt dialog.
*/
private void showExceptionDialog() {
new AlertDialog.Builder(this)
.setCancelable(false)
.setTitle("Prompt")
.setMessage("The album needs to be given permission to access storage, please go to "Settings" > "Apps" > Configure permissions in "Permissions".")
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
finish();
}
}). setPositiveButton("OK", 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);
}
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325141752&siteId=291194637