很久没有更新博客了,以后还是决定每个月来更新一遍。本次到来的是一个常用的场景,比如我们在发朋友圈的时候,我们可以选择多张照片,也可以删除之前选择的,但是最多一般会有个上限,达到上限之后一般添加的就消失了。这里给出一个简单的实现思路。

效果图

  • 我们还是先看看效果图
    • 首先是没有图片的时候
  • 然后我们选择两张图片
  • 选可以点图片右上交的×删除一张
  • 最后是选择6张,继续添加标志消失(我这里上限是6张,后面读者可以更新代码自己设置上限)

代码实现

  • 这里简单的提供一种实现方式
  • 我这里是利用RecyclerView来实现,接下来具体看下
    • 首先是主布局文件,其实就是一个RecyclerView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<android.support.v7.widget.RecyclerView
android:id="@+id/rl_repair"
android:layout_width="match_parent"
android:layout_height="250dp">
</android.support.v7.widget.RecyclerView>
```
- 然后主要逻辑代码在adapter,我们先看看adapter的布局
``` xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="10dp">
<ImageView
android:id="@+id/iv_add"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/bg_scan"/>
<ImageView
android:id="@+id/iv_photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
<ImageView
android:id="@+id/iv_remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:scaleType="centerCrop"
android:src="@mipmap/ic_delete"
android:visibility="visible"/>
</RelativeLayout>
  • 这部分代码没有什么要说的,主要是用RelativeLayout里面包裹3个ImageView,一个用图片右上角显示的删除,一个是添加新图片,还有一个是用来展示选择的图片
  • 接下来是adapter的逻辑部分代码了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
if (mList.size() >= MAX_SIZE) {
//最多6张
holder.ivAdd.setVisibility(View.GONE);
holder.ivRemove.setVisibility(View.GONE);
} else {
holder.ivPhoto.setVisibility(View.VISIBLE);
holder.ivPhoto.setVisibility(View.VISIBLE);
holder.ivRemove.setVisibility(View.VISIBLE);
}
if (getItemViewType(position) == TYPE_ADD) {
holder.ivRemove.setVisibility(View.GONE);
holder.ivPhoto.setVisibility(View.GONE);
} else {
holder.ivRemove.setVisibility(View.VISIBLE);
holder.ivAdd.setVisibility(View.GONE);
holder.ivPhoto.setVisibility(View.VISIBLE);
holder.ivPhoto.setImageBitmap(BitmapFactory.decodeFile(mList.get(position)));
}
}
  • 不难看出,这里利用setVisibility来进行操作,更具数据来显示那些或者隐藏哪些。当我们的数目大于等于6的时候,我们就需要删除和添加隐藏起来。
  • 别忘了,我们一开始就需要有添加的图片,所以我们的size应该是
1
2
3
4
@Override
public int getItemCount() {
return mList.size() + 1;
}
  • 数目应该要多加一个,然后应该注意到了我们的getItemViewType()方法了,这里我们进入看下
1
2
3
4
5
6
7
8
@Override
public int getItemViewType(int position) {
if (position == getItemCount() - 1) {
return TYPE_ADD;
} else {
return TYPE_PIC;
}
}
  • 没错,这里就是用来区别是那种类型的方法,我们这里有两个类型
1
2
private static final int TYPE_ADD = 1;
private static final int TYPE_PIC = 2;
  • 然后我们根据传入的postion来区分,如果position==我们的总数-1,那就说明我们这里显示添加图片,否则就显示展示的图片。为什么要减一个的原因就是最后总是要显示添加,除非达到了上限。然后回到我们的onBindViewHolder()代码中,就很简单了,当需要展示添加的时候,就把展示图片和删除的GONE,当需要展示图片的时候,就需要把添加隐藏,其余的展示出来
  • 然后我们还需要监听点击事件,用来增加或者是删除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private OnItemClickListener itemClickListener;
public interface OnItemClickListener {
/**
* 继续添加图片接口
*/
void onItemAddClick();
/**
* 删除已经添加的图片接口
*
* @param position 删除的position
*/
void onItemRemoveClick(int position);
}
  • 写一个点击事件的接口,两个方法,一个是添加,一个删除
  • 然后注册监听
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (context == null) {
context = parent.getContext();
}
final ViewHolder viewHolder = new ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_photo, parent, false));
viewHolder.ivAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
itemClickListener.onItemAddClick();
}
});
viewHolder.ivRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
itemClickListener.onItemRemoveClick(viewHolder.getAdapterPosition());
}
});
return viewHolder;
}
  • 在构造函数当中把接口进行注册
1
2
3
4
public TakePhotoAdapter(List<String> mList, OnItemClickListener itemClickListener) {
this.mList = mList;
this.itemClickListener = itemClickListener;
}
  • 最后就是我们的页面的逻辑代码,先把adapter的接口引入implementsTakePhotoAdapter.OnItemClickListener
  • 然后就是两个接口中的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public void onItemAddClick() {
//添加照片
mTakePhoto = getTakePhoto();
mTakePhoto.onPickFromCapture(configCompress());
}
@Override
public void onItemRemoveClick(int position) {
//删除照片
mPhotoList.remove(position);
mTakePhotoAdapter.notifyDataSetChanged();
}
  • 可以看到每次对图片操作了,我们需要进行刷新。这里图片的添加可以不是我们的重点,大家可以去用第三方库,我这里使用的是TakePhoto这个库。
  • 然后我们这边对RecyclerView进行注册就OK了
1
2
3
rlRepair.setLayoutManager(new GridLayoutManager(this, 3));
mTakePhotoAdapter = new TakePhotoAdapter(mPhotoList, this);
rlRepair.setAdapter(mTakePhotoAdapter);
  • 这里用的是GridLayoutManager,并设置每行3个,读者可以更具情况自己设置
  • 差不多就是这么多内容了,很简单的东西。如果有不对或者更好的方式,欢迎指教