先看截图

activity 布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:fitsSystemWindows="true"
android:orientation="vertical">
<include layout="@layout/action_bar" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#F5F5F5"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="60dp"
android:gravity="center_vertical"
android:text="问题和意见"
android:textColor="#666666"
android:textSize="18sp"
android:textStyle="bold" />
<EditText
android:id="@+id/etFeed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/tv_bg_white_002"
android:gravity="left|top"
android:hint="请填写您的宝贝意见,感谢您的支持(必填)"
android:minLines="6"
android:padding="4dp"
android:textColor="#999999"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="60dp"
android:gravity="center_vertical"
android:text="图片和视频"
android:textColor="#666666"
android:textSize="18sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:nestedScrollingEnabled="false"
android:padding="12dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="60dp"
android:gravity="center_vertical"
android:text="联系方式"
android:textColor="#666666"
android:textSize="18sp"
android:textStyle="bold" />
<EditText
android:id="@+id/etPhone"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@drawable/tv_bg_white_002"
android:gravity="left|top"
android:hint="请留下您的联系方式,以便于我们更好的了解问题"
android:maxLength="11"
android:inputType="phone"
android:padding="4dp"
android:textColor="#999999"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvSubmit"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="60dp"
android:layout_marginBottom="40dp"
android:background="@drawable/btn_bg_red_201"
android:gravity="center"
android:singleLine="true"
android:text="提交"
android:textAllCaps="false"
android:textColor="#FFFFFF"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
activity 业务逻辑主要代码
private List<String> mPicList;
private List<String> mPicIdList = new ArrayList<>();
mRecyclerView.setLayoutManager(new GridLayoutManager(mActivity, 4, OrientationHelper.VERTICAL, false));
mRecyclerView.setAdapter(mRecyclerViewAdapter = new FormImgAdapter(mActivity));
mRecyclerViewAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
if (view.getId() == R.id.ivDelete) {
mPicIdList.remove(position);
mRecyclerViewAdapter.remove(position);
}
}
});
View footView = getLayoutInflater().inflate(R.layout.item_gd_img, null);
RoundedImageView ivPic = footView.findViewById(R.id.ivPic);
ivPic.setImageResource(R.mipmap.add_1);
ivPic.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Matisse.from(mActivity)
.choose(MimeType.ofImage())
.countable(true)
.showSingleMediaType(true)
.maxSelectable(30)
.theme(R.style.Matisse_Zhihu)
.restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
.thumbnailScale(0.85f)
.imageEngine(new MyGlideEngine())
.capture(true)
.captureStrategy(new CaptureStrategy(true, "com.elon.zhzh.fileProvider"))
.forResult(1024);
}
});
mRecyclerViewAdapter.addFooterView(footView);
mRecyclerViewAdapter.setFooterViewAsFlow(true);
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
if (requestCode == 1024 && resultCode == RESULT_OK) {
uploadFileSuccSize = 0;
List<String> mPicList = Matisse.obtainPathResult(data);
if (mPicList != null && mPicList.size() > 0) {
for (String item : mPicList) {
mPicIdList.add(item);
mRecyclerViewAdapter.addData(item);
}
}
}
} catch (Exception e) {
e.printStackTrace();
ToastUtils.showShort("数据异常");
}
}
FormImgAdapter 数据适配器
public class FormImgAdapter extends BaseQuickAdapter<String, BaseViewHolder> {
private final Context context;
private boolean showDelete = true;
public FormImgAdapter(Context context) {
super(R.layout.item_gd_img, null);
this.context = context;
setOnItemClickListener((adapter, view, position) ->
ImagePreview.getInstance()
.setContext(context)
.setIndex(position)
.setImageList(getData())
.setLoadStrategy(ImagePreview.LoadStrategy.AlwaysOrigin)
.setEnableDragClose(true)
.setShowCloseButton(true)
.setShowDownButton(false)
.start());
}
@Override
protected void convert(BaseViewHolder helper, String item) {
helper.setVisible(R.id.ivDelete, showDelete);
helper.addOnClickListener(R.id.ivDelete);
if (item != null) {
RequestOptions options = new RequestOptions()
.error(R.drawable.default_error_img)
.placeholder(R.drawable.default_image);
Glide.with(context)
.load(item)
.thumbnail(0.5f)
.apply(options)
.into((RoundedImageView) helper.getView(R.id.ivPic));
}
}
public void showDelete(boolean showDelete) {
this.showDelete = showDelete;
notifyDataSetChanged();
}
}
item 截图

item 布局
<?xml version="1.0" encoding="utf-8"?>
<com.elon.zhzh.elon.widget.GrideViewItemLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp">
<com.itheima.roundedimageview.RoundedImageView
android:id="@+id/ivPic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:riv_corner_radius="10dp"
app:riv_mutate_background="true"
app:riv_oval="false"
app:riv_tile_mode="clamp" />
<ImageView
android:id="@+id/ivDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:padding="10dp"
android:src="@drawable/appitem_del_btn"
android:visibility="gone" />
<ImageView
android:id="@+id/ivVideo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:padding="10dp"
android:src="@drawable/ic_video_file_picker"
android:visibility="gone" />
</com.elon.zhzh.elon.widget.GrideViewItemLayout>
item 根布局 GrideViewItemLayout 类代码
public class GrideViewItemLayout extends RelativeLayout {
public GrideViewItemLayout(Context context) {
super(context);
}
public GrideViewItemLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GrideViewItemLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec));
int childWidhtSize = getMeasuredWidth();
heightMeasureSpec = widthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidhtSize, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
关于知乎图片选择框架
implementation 'com.zhihu.android:matisse:0.5.3-beta3'
关于 BaseQuickAdapter 类BaseRecyclerViewAdapterHelper 框架
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'