github源码:https://github.com/LuckSiege/PictureSelector
需要创建三个类,最后在activity中完成逻辑代码。1、FullyGridLayoutManager :继承GridLayoutManager的类,不用改动 。
2、GlideEngine:图像引擎,用glide实现图片加载,必须使用到!重新写几个自己要用的方法,源码有注释。
3、GridImageAdapter:适配器,按照源码注释,实现自己需要的方法。
需要用到的资源文件有: ic_add_image.png 、 ic_delete_menu.png 、gv_filter_image.xml 以及添加一些colos。 (在源码中找到就好了)
注意事项:!!! 图片文件不要放在drawble文件夹,要放在mipmap文件夹下,不然可能会出现加载布局文件错误! (oom问题)
以下是代码:
package com.example.pseapplication.picturesel; import android.content.Context; import android.view.View; import android.view.ViewGroup; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; /** * author:luck * project:PictureSelector * package:com.luck.picture.ui * email:893855882@qq.com * data:16/12/31 */ public class FullyGridLayoutManager extends GridLayoutManager { public FullyGridLayoutManager(Context context, int spanCount) { super(context, spanCount); } public FullyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) { super(context, spanCount, orientation, reverseLayout); } private int[] mMeasuredDimension = new int[2]; @Override public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { final int widthMode = View.MeasureSpec.getMode(widthSpec); final int heightMode = View.MeasureSpec.getMode(heightSpec); final int widthSize = View.MeasureSpec.getSize(widthSpec); final int heightSize = View.MeasureSpec.getSize(heightSpec); int width = 0; int height = 0; int count = getItemCount(); int span = getSpanCount(); for (int i = 0; i < count; i++) { measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), mMeasuredDimension); if (getOrientation() == HORIZONTAL) { if (i % span == 0) { width = width + mMeasuredDimension[0]; } if (i == 0) { height = mMeasuredDimension[1]; } } else { if (i % span == 0) { height = height + mMeasuredDimension[1]; } if (i == 0) { width = mMeasuredDimension[0]; } } } switch (widthMode) { case View.MeasureSpec.EXACTLY: width = widthSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } switch (heightMode) { case View.MeasureSpec.EXACTLY: height = heightSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } setMeasuredDimension(width, height); } final RecyclerView.State mState = new RecyclerView.State(); private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { int itemCount = mState.getItemCount(); if (position < itemCount) { try { View view = recycler.getViewForPosition(0); if (view != null) { RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), p.width); int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, getPaddingTop() + getPaddingBottom(), p.height); view.measure(childWidthSpec, childHeightSpec); measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin; measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin; recycler.recycleView(view); } } catch (Exception e) { e.printStackTrace(); } } } }
package com.example.pseapplication.picturesel; import android.content.Context; import android.graphics.Bitmap; import android.widget.ImageView; import androidx.annotation.NonNull; import androidx.core.graphics.drawable.RoundedBitmapDrawable; import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.BitmapImageViewTarget; import com.example.pseapplication.R; import com.luck.picture.lib.engine.ImageEngine; import com.luck.picture.lib.listener.OnImageCompleteCallback; import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; public class GlideEngine implements ImageEngine { private GlideEngine() { } private static GlideEngine instance; public static GlideEngine createGlideEngine() { if (null == instance) { synchronized (GlideEngine.class) { if (null == instance) { instance = new GlideEngine(); } } } return instance; } @Override public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { Glide.with(context) .load(url) .into(imageView); } @Override public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { } @Override public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { } @Override public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { Glide.with(context) .asBitmap() .load(url) .override(180, 180) .centerCrop() .sizeMultiplier(0.5f) .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) .into(new BitmapImageViewTarget(imageView) { @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory. create(context.getResources(), resource); circularBitmapDrawable.setCornerRadius(8); imageView.setImageDrawable(circularBitmapDrawable); } }); } @Override public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { } @Override public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { Glide.with(context) .load(url) .override(200, 200) .centerCrop() .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) .into(imageView); } }
package com.example.pseapplication.picturesel; import android.content.Context; import android.net.Uri; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.example.pseapplication.R; import com.luck.picture.lib.config.PictureMimeType; import com.luck.picture.lib.entity.LocalMedia; import com.luck.picture.lib.listener.OnItemClickListener; import com.luck.picture.lib.tools.DateUtils; import java.util.ArrayList; import java.util.List; public class GridImageAdapter extends RecyclerView.Adapter<GridImageAdapter.ViewHolder> { public static final String TAG = "PictureSelector"; public static final int TYPE_CAMERA = 1; public static final int TYPE_PICTURE = 2; private LayoutInflater mInflater; private List<LocalMedia> list = new ArrayList<>(); private int selectMax = 9; /** * 点击添加图片跳转 */ private onAddPicClickListener mOnAddPicClickListener; public interface onAddPicClickListener { void onAddPicClick(); } /** * 删除 */ public void delete(int position) { try { if (position != RecyclerView.NO_POSITION && list.size() > position) { list.remove(position); notifyItemRemoved(position); notifyItemRangeChanged(position, list.size()); } } catch (Exception e) { e.printStackTrace(); } } public GridImageAdapter(Context context, onAddPicClickListener mOnAddPicClickListener) { this.mInflater = LayoutInflater.from(context); this.mOnAddPicClickListener = mOnAddPicClickListener; } public void setSelectMax(int selectMax) { this.selectMax = selectMax; } public void setList(List<LocalMedia> list) { this.list = list; } public List<LocalMedia> getData() { return list == null ? new ArrayList<>() : list; } public void remove(int position) { if (list != null && position < list.size()) { list.remove(position); } } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = mInflater.inflate(R.layout.gv_filter_image, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) { //少于8张,显示继续添加的图标 if (getItemViewType(position) == TYPE_CAMERA) { viewHolder.mImg.setImageResource(R.mipmap.ic_add_image); viewHolder.mImg.setOnClickListener(v -> mOnAddPicClickListener.onAddPicClick()); viewHolder.mIvDel.setVisibility(View.INVISIBLE); }else { viewHolder.mIvDel.setVisibility(View.VISIBLE); viewHolder.mIvDel.setOnClickListener(view -> { int index = viewHolder.getAdapterPosition(); // 这里有时会返回-1造成数据下标越界,具体可参考getAdapterPosition()源码, // 通过源码分析应该是bindViewHolder()暂未绘制完成导致,知道原因的也可联系我~感谢 if (index != RecyclerView.NO_POSITION && list.size() > index) { list.remove(index); notifyItemRemoved(index); notifyItemRangeChanged(index, list.size()); } }); LocalMedia media = list.get(position); if (media == null || TextUtils.isEmpty(media.getPath())) { return; } int chooseModel = media.getChooseModel(); String path; if (media.isCut() && !media.isCompressed()) { // 裁剪过 path = media.getCutPath(); } else if (media.isCompressed() || (media.isCut() && media.isCompressed())) { // 压缩过,或者裁剪同时压缩过,以最终压缩过图片为准 path = media.getCompressPath(); } else { // 原图 path = media.getPath(); } long duration = media.getDuration(); viewHolder.tvDuration.setVisibility(PictureMimeType.isHasVideo(media.getMimeType()) ? View.VISIBLE : View.GONE); if (chooseModel == PictureMimeType.ofAudio()) { viewHolder.tvDuration.setVisibility(View.VISIBLE); viewHolder.tvDuration.setCompoundDrawablesRelativeWithIntrinsicBounds (R.drawable.picture_icon_audio, 0, 0, 0); } else { viewHolder.tvDuration.setCompoundDrawablesRelativeWithIntrinsicBounds (R.drawable.picture_icon_video, 0, 0, 0); } viewHolder.tvDuration.setText(DateUtils.formatDurationTime(duration)); if (chooseModel == PictureMimeType.ofAudio()) { viewHolder.mImg.setImageResource(R.drawable.picture_audio_placeholder); } else { Glide.with(viewHolder.itemView.getContext()) .load(PictureMimeType.isContent(path) && !media.isCut() && !media.isCompressed() ? Uri.parse(path) : path) .centerCrop() .placeholder(R.color.app_color_f6) .diskCacheStrategy(DiskCacheStrategy.ALL) .into(viewHolder.mImg); } if (mItemClickListener != null) { viewHolder.itemView.setOnClickListener(v -> { int adapterPosition = viewHolder.getAdapterPosition(); mItemClickListener.onItemClick(v, adapterPosition); }); } } } private OnItemClickListener mItemClickListener; public void setOnItemClickListener(OnItemClickListener l) { this.mItemClickListener = l; } @Override public int getItemCount() { if (list.size() < selectMax) { return list.size() + 1; } else { return list.size(); } } @Override public int getItemViewType(int position) { if (isShowAddItem(position)) { return TYPE_CAMERA; } else { return TYPE_PICTURE; } } public static class ViewHolder extends RecyclerView.ViewHolder { ImageView mImg; ImageView mIvDel; TextView tvDuration; public ViewHolder(View view) { super(view); mImg = view.findViewById(R.id.fiv); mIvDel = view.findViewById(R.id.iv_del); tvDuration = view.findViewById(R.id.tv_duration); } } private boolean isShowAddItem(int position) { int size = list.size(); return position == size; } }
package com.example.pseapplication; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; import com.example.pseapplication.picturesel.FullyGridLayoutManager; import com.example.pseapplication.picturesel.GlideEngine; import com.example.pseapplication.picturesel.GridImageAdapter; import com.luck.picture.lib.PictureSelector; import com.luck.picture.lib.broadcast.BroadcastAction; import com.luck.picture.lib.broadcast.BroadcastManager; import com.luck.picture.lib.config.PictureConfig; import com.luck.picture.lib.config.PictureMimeType; import com.luck.picture.lib.decoration.GridSpacingItemDecoration; import com.luck.picture.lib.entity.LocalMedia; import com.luck.picture.lib.listener.OnResultCallbackListener; import com.luck.picture.lib.tools.ScreenUtils; import com.luck.picture.lib.tools.ToastUtils; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import static java.security.AccessController.getContext; public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private GridImageAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = findViewById(R.id.recyclerview); FullyGridLayoutManager manager = new FullyGridLayoutManager(this, 4, GridLayoutManager.VERTICAL, false); recyclerView.setLayoutManager(manager); //recyclerView.addItemDecoration(new GridSpacingItemDecoration(4, // ScreenUtils.dip2px(this, 8), false)); mAdapter = new GridImageAdapter(MainActivity.this, onAddPicClickListener); recyclerView.setAdapter(mAdapter); if (savedInstanceState != null && savedInstanceState .getParcelableArrayList("selectorList") != null) { mAdapter.setList(savedInstanceState.getParcelableArrayList("selectorList")); } } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { if (requestCode == PictureConfig.CHOOSE_REQUEST) {// 图片选择结果回调 List<LocalMedia> selectList = PictureSelector.obtainMultipleResult(data); mAdapter.setList(selectList); mAdapter.notifyDataSetChanged(); } } } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); if (mAdapter != null && mAdapter.getData() != null && mAdapter.getData().size() > 0) { outState.putParcelableArrayList("selectorList", (ArrayList<? extends Parcelable>) mAdapter.getData()); } } @Override protected void onDestroy() { super.onDestroy(); if (broadcastReceiver != null) { BroadcastManager.getInstance(MainActivity.this).unregisterReceiver(broadcastReceiver, BroadcastAction.ACTION_DELETE_PREVIEW_POSITION); } } private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (TextUtils.isEmpty(action)) { return; } if (BroadcastAction.ACTION_DELETE_PREVIEW_POSITION.equals(action)) { // 外部预览删除按钮回调 Bundle extras = intent.getExtras(); if (extras != null) { int position = extras.getInt(PictureConfig.EXTRA_PREVIEW_DELETE_POSITION); ToastUtils.s(MainActivity.this, "delete image index:" + position); mAdapter.remove(position); mAdapter.notifyItemRemoved(position); } } } }; private GridImageAdapter.onAddPicClickListener onAddPicClickListener = new GridImageAdapter.onAddPicClickListener() { @Override public void onAddPicClick() { // 进入相册 以下是例子:不需要的api可以不写 PictureSelector.create(MainActivity.this) .openGallery(PictureMimeType.ofImage())// 全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio() .imageEngine(GlideEngine.createGlideEngine())// 外部传入图片加载引擎,必传项 //.theme(themeId)// 主题样式设置 具体参考 values/styles 用法:R.style.picture.white.style v2.3.3后 建议使用setPictureStyle()动态方式 // .setPictureUIStyle(mSelectorUIStyle) //.setPictureStyle(mPictureParameterStyle)// 动态自定义相册主题 //.setPictureCropStyle(mCropParameterStyle)// 动态自定义裁剪主题 // .setPictureWindowAnimationStyle(mWindowAnimationStyle)// 自定义相册启动退出动画 .isWeChatStyle(true)// 是否开启微信图片选择风格 // .isUseCustomCamera(cb_custom_camera.isChecked())// 是否使用自定义相机 //.setLanguage(language)// 设置语言,默认中文 // .isPageStrategy(cbPage.isChecked())// 是否开启分页策略 & 每页多少条;默认开启 // .setRecyclerAnimationMode(animationMode)// 列表动画效果 .isWithVideoImage(true)// 图片和视频是否可以同选,只在ofAll模式下有效 .isMaxSelectEnabledMask(true)// 选择数到了最大阀值列表是否启用蒙层效果 //.isAutomaticTitleRecyclerTop(false)// 连续点击标题栏RecyclerView是否自动回到顶部,默认true //.loadCacheResourcesCallback(GlideCacheEngine.createCacheEngine())// 获取图片资源缓存,主要是解决华为10部分机型在拷贝文件过多时会出现卡的问题,这里可以判断只在会出现一直转圈问题机型上使用 //.setOutputCameraPath(createCustomCameraOutPath())// 自定义相机输出目录 //.setButtonFeatures(CustomCameraView.BUTTON_STATE_BOTH)// 设置自定义相机按钮状态 .maxSelectNum(9)// 最大图片选择数量 .minSelectNum(1)// 最小选择数量 .maxVideoSelectNum(1) // 视频最大选择数量 //.minVideoSelectNum(1)// 视频最小选择数量 //.closeAndroidQChangeVideoWH(!SdkVersionUtils.checkedAndroid_Q())// 关闭在AndroidQ下获取图片或视频宽高相反自动转换 .imageSpanCount(4)// 每行显示个数 .isReturnEmpty(false)// 未选择数据时点击按钮是否可以返回 .closeAndroidQChangeWH(true)//如果图片有旋转角度则对换宽高,默认为true // .closeAndroidQChangeVideoWH(!SdkVersionUtils.checkedAndroid_Q())// 如果视频有旋转角度则对换宽高,默认为false //.isAndroidQTransform(false)// 是否需要处理Android Q 拷贝至应用沙盒的操作,只针对compress(false); && .isEnableCrop(false);有效,默认处理 // .setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)// 设置相册Activity方向,不设置默认使用系统 // .isOriginalImageControl(cb_original.isChecked())// 是否显示原图控制按钮,如果设置为true则用户可以自由选择是否使用原图,压缩、裁剪功能将会失效 //.bindCustomPlayVideoCallback(new MyVideoSelectedPlayCallback(getContext()))// 自定义视频播放回调控制,用户可以使用自己的视频播放界面 //.bindCustomPreviewCallback(new MyCustomPreviewInterfaceListener())// 自定义图片预览回调接口 //.bindCustomCameraInterfaceListener(new MyCustomCameraInterfaceListener())// 提供给用户的一些额外的自定义操作回调 //.cameraFileName(System.currentTimeMillis() +".jpg") // 重命名拍照文件名、如果是相册拍照则内部会自动拼上当前时间戳防止重复,注意这个只在使用相机时可以使用,如果使用相机又开启了压缩或裁剪 需要配合压缩和裁剪文件名api //.renameCompressFile(System.currentTimeMillis() +".jpg")// 重命名压缩文件名、 如果是多张压缩则内部会自动拼上当前时间戳防止重复 //.renameCropFileName(System.currentTimeMillis() + ".jpg")// 重命名裁剪文件名、 如果是多张裁剪则内部会自动拼上当前时间戳防止重复 .selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选 // .isSingleDirectReturn(cb_single_back.isChecked())// 单选模式下是否直接返回,PictureConfig.SINGLE模式下有效 .isPreviewImage(true)// 是否可预览图片 // .isPreviewVideo(cb_preview_video.isChecked())// 是否可预览视频 //.querySpecifiedFormatSuffix(PictureMimeType.ofJPEG())// 查询指定后缀格式资源 // .isEnablePreviewAudio(cb_preview_audio.isChecked()) // 是否可播放音频 .isCamera(true)// 是否显示拍照按钮 //.isMultipleSkipCrop(false)// 多图裁剪时是否支持跳过,默认支持 //.isMultipleRecyclerAnimation(false)// 多图裁剪底部列表显示动画效果 // .isZoomAnim(true)// 图片列表点击 缩放效果 默认true //.imageFormat(PictureMimeType.PNG)// 拍照保存图片格式后缀,默认jpeg,Android Q使用PictureMimeType.PNG_Q // .isEnableCrop(cb_crop.isChecked())// 是否裁剪 //.basicUCropConfig()//对外提供所有UCropOptions参数配制,但如果PictureSelector原本支持设置的还是会使用原有的设置 // .isCompress(cb_compress.isChecked())// 是否压缩 //.compressQuality(80)// 图片压缩后输出质量 0~ 100 .synOrAsy(true)//同步true或异步false 压缩 默认同步 //.queryMaxFileSize(10)// 只查多少M以内的图片、视频、音频 单位M //.compressSavePath(getPath())//压缩图片保存地址 //.sizeMultiplier(0.5f)// glide 加载图片大小 0~1之间 如设置 .glideOverride()无效 注:已废弃 //.glideOverride(160, 160)// glide 加载宽高,越小图片列表越流畅,但会影响列表图片浏览的清晰度 注:已废弃 // .withAspectRatio(aspect_ratio_x, aspect_ratio_y)// 裁剪比例 如16:9 3:2 3:4 1:1 可自定义 .hideBottomControls(true)// 是否显示uCrop工具栏,默认不显示 .isGif(true)// 是否显示gif图片 //.isWebp(false)// 是否显示webp图片,默认显示 //.isBmp(false)//是否显示bmp图片,默认显示 // .freeStyleCropEnabled(cb_styleCrop.isChecked())// 裁剪框是否可拖拽 // .circleDimmedLayer(cb_crop_circular.isChecked())// 是否圆形裁剪 //.setCropDimmedColor(ContextCompat.getColor(getContext(), R.color.app_color_white))// 设置裁剪背景色值 //.setCircleDimmedBorderColor(ContextCompat.getColor(getApplicationContext(), R.color.app_color_white))// 设置圆形裁剪边框色值 //.setCircleStrokeWidth(3)// 设置圆形裁剪边框粗细 // .showCropFrame(cb_showCropFrame.isChecked())// 是否显示裁剪矩形边框 圆形裁剪时建议设为false // .showCropGrid(cb_showCropGrid.isChecked())// 是否显示裁剪矩形网格 圆形裁剪时建议设为false .isOpenClickSound(true)// 是否开启点击声音 .selectionData(mAdapter.getData())// 是否传入已选图片 //.isDragFrame(false)// 是否可拖动裁剪框(固定) //.videoMinSecond(10)// 查询多少秒以内的视频 //.videoMaxSecond(15)// 查询多少秒以内的视频 //.recordVideoSecond(10)//录制视频秒数 默认60s //.isPreviewEggs(true)// 预览图片时 是否增强左右滑动图片体验(图片滑动一半即可看到上一张是否选中) //.cropCompressQuality(90)// 注:已废弃 改用cutOutQuality() .cutOutQuality(90)// 裁剪输出质量 默认100 .minimumCompressSize(100)// 小于多少kb的图片不压缩 //.cropWH()// 裁剪宽高比,设置如果大于图片本身宽高则无效 //.cropImageWideHigh()// 裁剪宽高比,设置如果大于图片本身宽高则无效 //.rotateEnabled(false) // 裁剪是否可旋转图片 //.scaleEnabled(false)// 裁剪是否可放大缩小图片 //.videoQuality()// 视频录制质量 0 or 1 //.forResult(PictureConfig.CHOOSE_REQUEST);//结果回调onActivityResult code .forResult(new MyResultCallback(mAdapter)); } }; /** * 返回结果回调 */ private static class MyResultCallback implements OnResultCallbackListener<LocalMedia> { private WeakReference<GridImageAdapter> mAdapterWeakReference; public MyResultCallback(GridImageAdapter adapter) { super(); this.mAdapterWeakReference = new WeakReference<>(adapter); } @Override public void onResult(List<LocalMedia> result) { if (mAdapterWeakReference.get() != null) { mAdapterWeakReference.get().setList(result); mAdapterWeakReference.get().notifyDataSetChanged(); } } @Override public void onCancel() { Log.i("TAG", "PictureSelector Cancel"); } } }
我爱学习 ,学习爱我!0.0