package com.ypx.imagepicker.activity;
import android.Manifest;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import com.ypx.imagepicker.ImagePicker;
import com.ypx.imagepicker.R;
import com.ypx.imagepicker.bean.PickerItemDisableCode;
import com.ypx.imagepicker.bean.selectconfig.BaseSelectConfig;
import com.ypx.imagepicker.bean.ImageItem;
import com.ypx.imagepicker.bean.ImageSet;
import com.ypx.imagepicker.data.ICameraExecutor;
import com.ypx.imagepicker.data.ProgressSceneEnum;
import com.ypx.imagepicker.utils.PStatusBarUtil;
import com.ypx.imagepicker.views.PickerUiConfig;
import com.ypx.imagepicker.data.MediaItemsDataSource;
import com.ypx.imagepicker.data.MediaSetsDataSource;
import com.ypx.imagepicker.data.OnImagePickCompleteListener;
import com.ypx.imagepicker.presenter.IPickerPresenter;
import com.ypx.imagepicker.utils.PPermissionUtils;
import com.ypx.imagepicker.views.PickerUiProvider;
import com.ypx.imagepicker.views.base.PickerControllerView;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import static com.ypx.imagepicker.ImagePicker.REQ_CAMERA;
import static com.ypx.imagepicker.ImagePicker.REQ_STORAGE;
/**
* Description: 选择器加载基类,主要处理媒体文件的加载和权限管理
*
* Author: peixing.yang
* Date: 2019/2/21
* 使用文档 :https://github.com/yangpeixing/YImagePicker/wiki/Documentation_3.x
*/
public abstract class PBaseLoaderFragment extends Fragment implements ICameraExecutor {
//选中图片列表
protected ArrayList selectList = new ArrayList<>();
/**
* @return 获取选择器配置项,主要用于加载文件类型的指定
*/
@NonNull
protected abstract BaseSelectConfig getSelectConfig();
/**
* @return 获取presenter
*/
@NonNull
protected abstract IPickerPresenter getPresenter();
/**
* @return 获取presenter
*/
@NonNull
protected abstract PickerUiConfig getUiConfig();
/**
* 执行回调
*/
protected abstract void notifyPickerComplete();
/**
* 切换文件夹
*/
protected abstract void toggleFolderList();
/**
* 跳转预览页面
*
* @param isClickItem 是否是item点击
* @param index 当前图片位于预览列表数据源的索引
*/
protected abstract void intentPreview(boolean isClickItem, int index);
/**
* @param imageSetList 媒体文件夹加载完成回调
*/
protected abstract void loadMediaSetsComplete(@Nullable List imageSetList);
/**
* @param set 媒体文件夹内文件加载完成回调
*/
protected abstract void loadMediaItemsComplete(@Nullable ImageSet set);
/**
* @param allVideoSet 刷新所有视频的文件夹
*/
protected abstract void refreshAllVideoSet(@Nullable ImageSet allVideoSet);
/**
* @return 返回需要判断当前文件夹列表是否打开
*/
public boolean onBackPressed() {
return false;
}
/**
* @param imageItem 回调一张图片
*/
protected void notifyOnSingleImagePickComplete(ImageItem imageItem) {
selectList.clear();
selectList.add(imageItem);
notifyPickerComplete();
}
/**
* 是否超过最大限制数
*
* @return true:超过
*/
private boolean isOverMaxCount() {
if (selectList.size() >= getSelectConfig().getMaxCount()) {
getPresenter().overMaxCountTip(getContext(), getSelectConfig().getMaxCount());
return true;
}
return false;
}
/**
* 检测当前拍照item是拍照还是录像
*/
protected void checkTakePhotoOrVideo() {
if (getSelectConfig().isShowVideo() && !getSelectConfig().isShowImage()) {
takeVideo();
} else {
takePhoto();
}
}
/**
* 拍照
*/
@Override
public void takePhoto() {
if (getActivity() == null || isOverMaxCount()) {
return;
}
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQ_CAMERA);
} else {
ImagePicker.takePhoto(getActivity(), null,
true, new OnImagePickCompleteListener() {
@Override
public void onImagePickComplete(ArrayList items) {
if (items != null && items.size() > 0 && items.get(0) != null) {
onTakePhotoResult(items.get(0));
}
}
});
}
}
@Override
public void takeVideo() {
if (getActivity() == null || isOverMaxCount()) {
return;
}
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQ_CAMERA);
} else {
ImagePicker.takeVideo(getActivity(), null, getSelectConfig().getMaxVideoDuration(),
true, new OnImagePickCompleteListener() {
@Override
public void onImagePickComplete(ArrayList items) {
if (items != null && items.size() > 0 && items.get(0) != null) {
onTakePhotoResult(items.get(0));
}
}
});
}
}
/**
* 加载媒体文件夹
*/
protected void loadMediaSets() {
if (getActivity() == null) {
return;
}
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQ_STORAGE);
// MediaSetsDataSource.create(getActivity()).setMimeTypeSet(getSelectConfig().getMimeTypes()).loadMediaSets( new MediaSetsDataSource.MediaSetProvider() {
// @Override
// public void providerMediaSets(ArrayList imageSets) {
// loadMediaSetsComplete(imageSets);
// }
// });
} else {
//从媒体库拿到文件夹列表
ImagePicker.provideMediaSets(getActivity(), getSelectConfig().getMimeTypes(), new MediaSetsDataSource.MediaSetProvider() {
@Override
public void providerMediaSets(ArrayList imageSets) {
loadMediaSetsComplete(imageSets);
}
});
}
}
/**
* 根据指定的媒体 文件夹加载文件
*
* @param set 文件夹
*/
protected void loadMediaItemsFromSet(final @NonNull ImageSet set) {
if (set.imageItems == null || set.imageItems.size() == 0) {
DialogInterface dialogInterface = null;
if (!set.isAllMedia() && set.count > 1000) {
dialogInterface = getPresenter().
showProgressDialog(getWeakActivity(), ProgressSceneEnum.loadMediaItem);
}
final BaseSelectConfig selectConfig = getSelectConfig();
final DialogInterface finalDialogInterface = dialogInterface;
ImagePicker.provideMediaItemsFromSetWithPreload(getActivity(), set, selectConfig.getMimeTypes(),
40, new MediaItemsDataSource.MediaItemPreloadProvider() {
@Override
public void providerMediaItems(ArrayList imageItems) {
if (finalDialogInterface != null) {
finalDialogInterface.dismiss();
}
set.imageItems = imageItems;
loadMediaItemsComplete(set);
}
}, new MediaItemsDataSource.MediaItemProvider() {
@Override
public void providerMediaItems(ArrayList imageItems, ImageSet allVideoSet) {
if (finalDialogInterface != null) {
finalDialogInterface.dismiss();
}
set.imageItems = imageItems;
loadMediaItemsComplete(set);
if (selectConfig.isShowImage() && selectConfig.isShowVideo()) {
refreshAllVideoSet(allVideoSet);
}
}
});
} else {
loadMediaItemsComplete(set);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == REQ_CAMERA) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//申请成功,可以拍照
takePhoto();
} else {
PPermissionUtils.create(getContext()).showSetPermissionDialog(
getString(R.string.picker_str_camera_permission));
}
} else if (requestCode == REQ_STORAGE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//申请成功,可以拍照
loadMediaSets();
} else {
PPermissionUtils.create(getContext()).
showSetPermissionDialog(getString(R.string.picker_str_storage_permission));
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
protected PickerControllerView titleBar;
protected PickerControllerView bottomBar;
/**
* 加载自定义控制器布局
*
* @param container 布局容器
* @param isTitle 是否是顶部栏
* @param uiConfig ui配置
* @return 当前需要记载的控制器
*/
protected PickerControllerView inflateControllerView(ViewGroup container, boolean isTitle, PickerUiConfig uiConfig) {
final BaseSelectConfig selectConfig = getSelectConfig();
PickerUiProvider uiProvider = uiConfig.getPickerUiProvider();
PickerControllerView view = isTitle ? uiProvider.getTitleBar(getWeakActivity()) :
uiProvider.getBottomBar(getWeakActivity());
if (view != null && view.isAddInParent()) {
container.addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
if (selectConfig.isShowVideo() && selectConfig.isShowImage()) {
view.setTitle(getString(R.string.picker_str_title_all));
} else if (selectConfig.isShowVideo()) {
view.setTitle(getString(R.string.picker_str_title_video));
} else {
view.setTitle(getString(R.string.picker_str_title_image));
}
final PickerControllerView finalView = view;
View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v == finalView.getCanClickToCompleteView()) {
notifyPickerComplete();
} else if (v == finalView.getCanClickToToggleFolderListView()) {
toggleFolderList();
} else {
intentPreview(false, 0);
}
}
};
if (view.getCanClickToCompleteView() != null) {
view.getCanClickToCompleteView().setOnClickListener(clickListener);
}
if (view.getCanClickToToggleFolderListView() != null) {
view.getCanClickToToggleFolderListView().setOnClickListener(clickListener);
}
if (view.getCanClickToIntentPreviewView() != null) {
view.getCanClickToIntentPreviewView().setOnClickListener(clickListener);
}
}
return view;
}
/**
* 控制器view执行切换文件夹操作
*
* @param isOpen 是否是打开文件夹
*/
protected void controllerViewOnTransitImageSet(boolean isOpen) {
if (titleBar != null) {
titleBar.onTransitImageSet(isOpen);
}
if (bottomBar != null) {
bottomBar.onTransitImageSet(isOpen);
}
}
/**
* 控制器view执行文件夹选择完成
*
* @param set 当前选择文件夹
*/
protected void controllerViewOnImageSetSelected(ImageSet set) {
if (titleBar != null) {
titleBar.onImageSetSelected(set);
}
if (bottomBar != null) {
bottomBar.onImageSetSelected(set);
}
}
/**
* 刷新完成按钮
*/
protected void refreshCompleteState() {
if (titleBar != null) {
titleBar.refreshCompleteViewState(selectList, getSelectConfig());
}
if (bottomBar != null) {
bottomBar.refreshCompleteViewState(selectList, getSelectConfig());
}
}
/**
* 设置文件夹列表的高度
*
* @param mFolderListRecyclerView 文件夹列表
* @param mImageSetMask 文件夹列表的灰色透明蒙层
* @param isCrop 是否是小红书样式
*/
protected void setFolderListHeight(RecyclerView mFolderListRecyclerView, View mImageSetMask, boolean isCrop) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mFolderListRecyclerView.getLayoutParams();
RelativeLayout.LayoutParams maskParams = (RelativeLayout.LayoutParams) mImageSetMask.getLayoutParams();
PickerUiConfig uiConfig = getUiConfig();
int height = uiConfig.getFolderListOpenMaxMargin();
if (uiConfig.getFolderListOpenDirection() == PickerUiConfig.DIRECTION_BOTTOM) {
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
if (isCrop) {
params.bottomMargin = bottomBar != null ? bottomBar.getViewHeight() : 0;
params.topMargin = (titleBar != null ? titleBar.getViewHeight() : 0) + height;
maskParams.topMargin = (titleBar != null ? titleBar.getViewHeight() : 0);
maskParams.bottomMargin = bottomBar != null ? bottomBar.getViewHeight() : 0;
} else {
params.bottomMargin = 0;
params.topMargin = height;
}
} else {
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
if (isCrop) {
params.bottomMargin = height + (bottomBar != null ? bottomBar.getViewHeight() : 0);
params.topMargin = titleBar != null ? titleBar.getViewHeight() : 0;
maskParams.topMargin = (titleBar != null ? titleBar.getViewHeight() : 0);
maskParams.bottomMargin = bottomBar != null ? bottomBar.getViewHeight() : 0;
} else {
params.bottomMargin = height;
params.topMargin = 0;
}
}
mFolderListRecyclerView.setLayoutParams(params);
mImageSetMask.setLayoutParams(maskParams);
}
/**
* 是否拦截不可点击的item
*
* @param disableItemCode 不可点击的item的code码
* @param isCheckOverMaxCount 是否校验超过最大数量时候的item
* @return 是否拦截掉
*/
protected boolean interceptClickDisableItem(int disableItemCode, boolean isCheckOverMaxCount) {
if (disableItemCode != PickerItemDisableCode.NORMAL) {
if (!isCheckOverMaxCount && disableItemCode == PickerItemDisableCode.DISABLE_OVER_MAX_COUNT) {
return false;
}
String message = PickerItemDisableCode.getMessageFormCode(getActivity(), disableItemCode, getPresenter(), getSelectConfig());
if (message.length() > 0) {
getPresenter().tip(getWeakActivity(), message);
}
return true;
}
return false;
}
/**
* 添加一个图片到文件夹列表里。一般在拍照完成的回调里会执行该方法,用于手动添加
* 一个item到指定的文件夹列表里
*
* @param imageSets 当前的文件夹列表
* @param imageItems 当前文件夹列表里面的item数组
* @param imageItem 当前要插入的文件
*/
protected void addItemInImageSets(@NonNull List imageSets,
@NonNull List imageItems,
@NonNull ImageItem imageItem) {
imageItems.add(0, imageItem);
if (imageSets.size() == 0) {
String firstImageSetName;
if (imageItem.isVideo()) {
firstImageSetName = getActivity().getString(R.string.picker_str_folder_item_video);
} else {
firstImageSetName = getActivity().getString(R.string.picker_str_folder_item_image);
}
ImageSet imageSet = ImageSet.allImageSet(firstImageSetName);
imageSet.cover = imageItem;
imageSet.coverPath = imageItem.path;
imageSet.imageItems = (ArrayList) imageItems;
imageSet.count = imageSet.imageItems.size();
imageSets.add(imageSet);
} else {
imageSets.get(0).imageItems = (ArrayList) imageItems;
imageSets.get(0).cover = imageItem;
imageSets.get(0).coverPath = imageItem.path;
imageSets.get(0).count = imageItems.size();
}
}
private WeakReference weakReference;
/**
* @return 获取弱引用的activity对象
*/
protected Activity getWeakActivity() {
if (getActivity() != null) {
if (weakReference == null) {
weakReference = new WeakReference(getActivity());
}
return weakReference.get();
}
return null;
}
protected void tip(String msg) {
getPresenter().tip(getWeakActivity(), msg);
}
final public int dp(float dp) {
if (getActivity() == null || getContext() == null) {
return 0;
}
float density = getResources().getDisplayMetrics().density;
return (int) (dp * density + 0.5);
}
private long lastTime = 0L;
protected boolean onDoubleClick() {
boolean flag = false;
long time = System.currentTimeMillis() - lastTime;
if (time > 300) {
flag = true;
}
lastTime = System.currentTimeMillis();
return !flag;
}
/**
* 设置是否显示状态栏
*/
protected void setStatusBar() {
if (getActivity() != null) {
//刘海屏幕需要适配状态栏颜色
if (getUiConfig().isShowStatusBar() || PStatusBarUtil.hasNotchInScreen(getActivity())) {
PStatusBarUtil.setStatusBar(getActivity(), getUiConfig().getStatusBarColor(),
false, PStatusBarUtil.isDarkColor(getUiConfig().getStatusBarColor()));
} else {
PStatusBarUtil.fullScreen(getActivity());
}
}
}
}