当前位置: 首页 > article >正文

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();

5. 点击增加弹框布局

<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>

6. 弹框页面初始化

 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);

7.  弹框页面监听初始化

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();
            }
        };

8. 增加拍照回调,不加这个图片回调不成功哦。

@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();
            }
        }
    }

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


http://www.kler.cn/a/162440.html

相关文章:

  • Ubuntu 的 ROS 操作系统安装与测试
  • 【R78/G15 开发板测评】串口打印 DHT11 温湿度传感器、DS18B20 温度传感器数据,LabVIEW 上位机绘制演化曲线
  • MQTT协议解析 : 物联网领域的最佳选择
  • 相机光学(四十二)——sony的HDR技术
  • 时序数据库TimescaleDB安装部署以及常见使用
  • Python多进程间通讯(包含共享内存方式)
  • 【无线网络技术】——无线局域网(学习笔记)
  • Github与Gitlab
  • C# 语法笔记
  • C++ 关于结构体struct的一些总结
  • 几何尺寸智能测量仪为您带来经济效益提升
  • 喝酒谁先倒
  • 【五分钟】熟悉python列表和元组的异同点【看这篇够用!建议收藏】
  • 极简模式,助力宏观数据监控
  • 图片和文字如何生成一个二维码?图文生成二维码的做法
  • 万界星空科技MES---制造企业的加工生产模式
  • Meta Platforms推出Imagine:基于Emu的免费AI文本到图像生成器服务
  • 【Linux】stat命令使用
  • 【EMNLP 2023】基于知识迁移的跨语言机器阅读理解算法
  • 【Linux系统化学习】命令行参数 | 环境变量的再次理解
  • springboot快速入门
  • python3: jieba(“结巴”中文分词库) .2023-11-28
  • 028:简单的foreach
  • Android Studio的笔记--String和byte[]
  • 朴素贝叶斯 贝叶斯方法
  • Servlet should have a mapping