package com.ypx.imagepicker.activity; import android.Manifest; import android.app.Activity; import android.content.DialogInterface; import android.content.pm.PackageManager; 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: 选择器加载基类,主要处理媒体文件的加载和权限管理 * <p> * 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<ImageItem> 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<ImageSet> 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<ImageItem> 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<ImageItem> 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); } else { //从媒体库拿到文件夹列表 ImagePicker.provideMediaSets(getActivity(), getSelectConfig().getMimeTypes(), new MediaSetsDataSource.MediaSetProvider() { @Override public void providerMediaSets(ArrayList<ImageSet> 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<ImageItem> imageItems) { if (finalDialogInterface != null) { finalDialogInterface.dismiss(); } set.imageItems = imageItems; loadMediaItemsComplete(set); } }, new MediaItemsDataSource.MediaItemProvider() { @Override public void providerMediaItems(ArrayList<ImageItem> 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<ImageSet> imageSets, @NonNull List<ImageItem> 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<ImageItem>) imageItems; imageSet.count = imageSet.imageItems.size(); imageSets.add(imageSet); } else { imageSets.get(0).imageItems = (ArrayList<ImageItem>) imageItems; imageSets.get(0).cover = imageItem; imageSets.get(0).coverPath = imageItem.path; imageSets.get(0).count = imageItems.size(); } } private WeakReference<Activity> weakReference; /** * @return 获取弱引用的activity对象 */ protected Activity getWeakActivity() { if (getActivity() != null) { if (weakReference == null) { weakReference = new WeakReference<Activity>(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()); } } } }