android项目实战之使用框架 集成多图片、视频的上传

效果图

实现方式,本功能使用PictureSelector 第三方库 。作者项目地址:https://github.com/LuckSiege/PictureSelector

复制代码
  1. builder.gradle 增加

    implementation 'io.github.lucksiege:pictureselector:v3.11.1'

    implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.3@aar'
    implementation 'io.reactivex.rxjava2:rxjava:2.0.0'

  2. XML布局

    <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content">
    <View android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignTop="@+id/recycler" android:layout_alignBottom="@+id/recycler" android:background="@color/app_color_white" />

                 <androidx.recyclerview.widget.RecyclerView
                     android:id="@+id/recycler"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:layout_marginLeft="8dp"
                     android:layout_marginRight="8dp"
                     android:overScrollMode="never" />
    
             </RelativeLayout>
    
  3. 适配器,这里对GridImageAdapter进行了改进。

    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 final LayoutInflater mInflater;
    private ArrayList<LocalMedia> list = new ArrayList<>();
    private int selectMax = 9;

     /**
      * 删除
      */
     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, List<LocalMedia> result) {
         this.mInflater = LayoutInflater.from(context);
         this.list.addAll(result);
     }
    
     public void setSelectMax(int selectMax) {
         this.selectMax = selectMax;
     }
    
     public void setList(ArrayList<LocalMedia> list) {
         this.list = list;
     }
    
     public int getSelectMax() {
         return selectMax;
     }
    
     public ArrayList<LocalMedia> getData() {
         return list;
     }
    
     public void remove(int position) {
         if (position < list.size()) {
             list.remove(position);
         }
     }
    
     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);
         }
     }
    
     @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;
         }
     }
    
     /**
      * 创建ViewHolder
      */
     @Override
     public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
         View view = mInflater.inflate(R.layout.item_filter_image, viewGroup, false);
         return new ViewHolder(view);
     }
    
     private boolean isShowAddItem(int position) {
         int size = list.size();
         return position == size;
     }
    
     /**
      * 设置值
      */
     @Override
     public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
         //少于MaxSize张,显示继续添加的图标
         if (getItemViewType(position) == TYPE_CAMERA) {
             viewHolder.mImg.setImageResource(R.drawable.ic_add_image);
             viewHolder.mImg.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View view) {
                     if (mItemClickListener != null) {
                         mItemClickListener.openPicture();
                     }
                 }
             });
             viewHolder.mIvDel.setVisibility(View.INVISIBLE);
         } else {
             viewHolder.mIvDel.setVisibility(View.VISIBLE);
             viewHolder.mIvDel.setOnClickListener(view -> {
                 int index = viewHolder.getAbsoluteAdapterPosition();
                 if (index != RecyclerView.NO_POSITION && list.size() > index) {
                     list.remove(index);
                     notifyItemRemoved(index);
                     notifyItemRangeChanged(index, list.size());
                 }
             });
             LocalMedia media = list.get(position);
             int chooseModel = media.getChooseModel();
             String path = media.getAvailablePath();
             long duration = media.getDuration();
             viewHolder.tvDuration.setVisibility(PictureMimeType.isHasVideo(media.getMimeType())
                     ? View.VISIBLE : View.GONE);
             if (chooseModel == SelectMimeType.ofAudio()) {
                 viewHolder.tvDuration.setVisibility(View.VISIBLE);
                 viewHolder.tvDuration.setCompoundDrawablesRelativeWithIntrinsicBounds
                         (R.drawable.ps_ic_audio, 0, 0, 0);
    
             } else {
                 viewHolder.tvDuration.setCompoundDrawablesRelativeWithIntrinsicBounds
                         (R.drawable.ps_ic_video, 0, 0, 0);
             }
             viewHolder.tvDuration.setText(DateUtils.formatDurationTime(duration));
             if (chooseModel == SelectMimeType.ofAudio()) {
                 viewHolder.mImg.setImageResource(com.luck.picture.lib.R.drawable.ps_audio_placeholder);
             } else {
                 RequestOptions options = RequestOptions.centerCropTransform()
                         .centerCrop()
                         .placeholder(R.color.app_color_f6)
                         .diskCacheStrategy(DiskCacheStrategy.ALL);
    
                 Glide.with(viewHolder.itemView.getContext())
                         .load(PictureMimeType.isContent(path) && !media.isCut() && !media.isCompressed() ? Uri.parse(path)
                                 : path)
                         .apply(options)
                         .into(viewHolder.mImg);
             }
             //itemView 的点击事件
             if (mItemClickListener != null) {
                 viewHolder.itemView.setOnClickListener(v -> {
                     int adapterPosition = viewHolder.getAbsoluteAdapterPosition();
                     mItemClickListener.onItemClick(v, adapterPosition);
                 });
             }
    
             if (mItemLongClickListener != null) {
                 viewHolder.itemView.setOnLongClickListener(v -> {
                     int adapterPosition = viewHolder.getAbsoluteAdapterPosition();
                     mItemLongClickListener.onItemLongClick(viewHolder, adapterPosition, v);
                     return true;
                 });
             }
         }
     }
    
     private OnItemClickListener mItemClickListener;
    
     public void setOnItemClickListener(OnItemClickListener l) {
         this.mItemClickListener = l;
     }
    
     public interface OnItemClickListener {
         /**
          * Item click event
          *
          * @param v
          * @param position
          */
         void onItemClick(View v, int position);
    
         /**
          * Open PictureSelector
          */
         void openPicture();
     }
    
     private OnItemLongClickListener mItemLongClickListener;
    
     public void setItemLongClickListener(OnItemLongClickListener l) {
         this.mItemLongClickListener = l;
     }
    

    }

复制代码
4. 布局空间初始化
 FullyGridLayoutManager manager = new FullyGridLayoutManager(mContext, 3, GridLayoutManager.VERTICAL, false);
        mRecyclerView.setLayoutManager(manager);
        adapter = new GridImageAdapter(getContext(), mData);
        adapter.setSelectMax(maxSelectNum);
        mRecyclerView.setAdapter(adapter);
        imageEngine = GlideEngine.createGlideEngine();
  1. 点击增加弹框布局

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical">

     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_margin="10dp"
         android:orientation="vertical">
    
         <TextView
             android:id="@+id/tv_album"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:background="@drawable/shape_album"
             android:gravity="center"
             android:padding="15dp"
             android:text="相册"
             android:textSize="16sp"/>
    
         <View
             android:layout_width="match_parent"
             android:layout_height="1dp"
             android:background="#f5f5f5"/>
    
         <TextView
             android:id="@+id/tv_camera"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:background="@drawable/shape_camera"
             android:gravity="center"
             android:padding="15dp"
             android:text="拍照"
             android:textSize="16sp"/>
    
         <TextView
             android:id="@+id/tv_cancel"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="10dp"
             android:background="@drawable/shape_cancel"
             android:gravity="center"
             android:padding="15dp"
             android:text="取消"
             android:textSize="16sp"/>
    
     </LinearLayout>
    
    </LinearLayout>
  2. 弹框页面初始化

    View bottomView = View.inflate(mContext, R.layout.layout_bottom_dialog, null);
    TextView mAlbum = bottomView.findViewById(R.id.tv_album);
    TextView mCamera = bottomView.findViewById(R.id.tv_camera);
    TextView mCancel = bottomView.findViewById(R.id.tv_cancel);

         pop = new PopupWindow(bottomView, -1, -2);
         pop.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
         pop.setOutsideTouchable(true);
         pop.setFocusable(true);
         WindowManager.LayoutParams lp = getActivity().getWindow().getAttributes();
         lp.alpha = 0.5f;
         getActivity().getWindow().setAttributes(lp);
         pop.setOnDismissListener(new PopupWindow.OnDismissListener() {
    
             @Override
             public void onDismiss() {
                 WindowManager.LayoutParams lp = getActivity().getWindow().getAttributes();
                 lp.alpha = 1f;
                 getActivity().getWindow().setAttributes(lp);
             }
         });
         pop.setAnimationStyle(R.style.main_menu_photo_anim);
         pop.showAtLocation(getActivity().getWindow().getDecorView(), Gravity.BOTTOM, 0, 0);
    
  3. 弹框页面监听初始化

    View.OnClickListener clickListener = new View.OnClickListener() {
    @Override
    public void onClick(View view) {
    switch (view.getId()) {
    case R.id.tv_album:
    //相册
    Log.d("打开相册","sss");
    PictureSelector.create(GoodItemTitleFragment.this)
    .openGallery(SelectMimeType.ofImage())
    .setImageEngine(GlideEngine.createGlideEngine())
    .setMaxSelectNum(maxSelectNum)
    .setMinSelectNum(1)
    .setImageSpanCount(4)
    .forResult(new OnResultCallbackListener<LocalMedia>() {

                                                @Override
                                                public void onResult(ArrayList<LocalMedia> result) {
                                                    selectList.addAll(result);
                                                    //Log.d("ceshi"+RESULT_OK, String.valueOf(images));
                                                    adapter.setList(selectList);
                                                    adapter.notifyDataSetChanged();
                                                }
    
                                                @Override
                                                public void onCancel() {
    
                                                }
                                            });
                        /** PictureSelector.create(GoodItemTitleFragment.this)
                                 .openGallery(PictureMimeType.ofImage())
                                 .maxSelectNum(maxSelectNum)
                                 .minSelectNum(1)
                                 .imageSpanCount(4)
                                 .selectionMode(PictureConfig.MULTIPLE)
                                 .forResult(PictureConfig.CHOOSE_REQUEST);**/
                         break;
                     case R.id.tv_camera:
                         //拍照
                         Log.d("打开拍照","sss");
                         PictureSelector.create(GoodItemTitleFragment.this)
                                 .openCamera(SelectMimeType.ofVideo())
                                 .forResultActivity(PictureConfig.REQUEST_CAMERA);
                         /**PictureSelector.create(GoodItemTitleFragment.this)
                                 .openCamera(PictureMimeType.ofImage())
                                 .forResult(PictureConfig.CHOOSE_REQUEST);**/
                         break;
                     case R.id.tv_cancel:
                         //取消
                         closePopupWindow();
                         break;
                 }
                 closePopupWindow();
             }
         };
    
  4. 增加拍照回调,不加这个图片回调不成功哦。

    @SuppressLint("RestrictedApi")
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.d("ceshi"+requestCode,"111");
    Log.d("ceshi"+resultCode,"222");
    //Log.d("ceshi"+RESULT_OK,"333");
    List<LocalMedia> images;
    if (resultCode == -1) {
    //Log.d("ceshi"+RESULT_OK,"111");
    if (requestCode == PictureConfig.REQUEST_CAMERA) {// 图片选择结果回调
    images = PictureSelector.obtainSelectorList(data);
    selectList.addAll(images);
    //Log.d("ceshi"+RESULT_OK, String.valueOf(images));
    adapter.setList(selectList);
    adapter.notifyDataSetChanged();
    }
    }
    }

本功能涉及的功能较多,用了几天的时间算集成完。欢迎点赞、转发、首次。

相关推荐
m0_548514774 小时前
2024.12.10——攻防世界Web_php_include
android·前端·php
凤邪摩羯4 小时前
Android-性能优化-03-启动优化-启动耗时
android
凤邪摩羯4 小时前
Android-性能优化-02-内存优化-LeakCanary原理解析
android
喀什酱豆腐4 小时前
Handle
android
m0_748232926 小时前
Android Https和WebView
android·网络协议·https
m0_748251726 小时前
Android webview 打开本地H5项目(Cocos游戏以及Unity游戏)
android·游戏·unity
m0_748254668 小时前
go官方日志库带色彩格式化
android·开发语言·golang
zhangphil8 小时前
Android使用PorterDuffXfermode模式PorterDuff.Mode.SRC_OUT橡皮擦实现“刮刮乐”效果,Kotlin(2)
android·kotlin
爱学测试的李木子8 小时前
从0到1搭建 Android 自动化 python+appium 环境
android·软件测试·python·测试工具·自动化
咸芝麻鱼9 小时前
Android Studio | 连接手机设备后,启动App时出现:Waiting For DebuggerApplication (App名)...
android·adb·智能手机·android studio