在开发中需要用到九宫格添加并显示图片,和qq空间发动态时一样。于是写了一个控件。
效果图:
实现思路
自定义一个继承LinearLayout的布局,显示方式为水平,然后添加三个显示方式为垂直的布局。根据需要显示图片的数量,控制布局的显示隐藏(比如只有一张图片就把第二行第三行都隐藏)。
核心代码
public class NineImageView extends LinearLayout {
private Context context;
private List<String> list;
private int height;
private int width;
private int margin;
private int imagesize;
public NineImageView(Context context) {
super(context);
}
RelativeLayout addView;
LinearLayout.LayoutParams addParams;
LinearLayout.LayoutParams baseParams;
LinearLayout base0;
LinearLayout base1;
LinearLayout base2;
public NineImageView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
this.list = new ArrayList<>();//存放图片地址的list
this.margin = ScreenUtils.dip2px(context, 4);//图片显示的边距
this.height = ScreenUtils.getScreenWidth(context) / 3;//布局的高
this.width = ScreenUtils.getScreenWidth(context);//布局的宽
this.imagesize = height - margin * 2;//图片的大小
setOrientation(VERTICAL);
createBaseView();
createAddView();
}
}
这里我们初始化了各种参数,为保证美观,设置每一张图片都是正方形。
下一步,添加三个垂直分布的布局
private void createBaseView() {
baseParams = new LayoutParams(width, height);
base0 = new LinearLayout(context);
base0.setOrientation(HORIZONTAL);
base1 = new LinearLayout(context);
base1.setOrientation(HORIZONTAL);
base2 = new LinearLayout(context);
base2.setOrientation(HORIZONTAL);
addView(base0, baseParams);
addView(base1, baseParams);
addView(base2, baseParams);
}
添加一个加号按钮,如图:
private void createAddView() {
addView = new RelativeLayout(context);
addView.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.heart_add_bk));
ImageView imageView = new ImageView(context);
RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params1.addRule(RelativeLayout.CENTER_IN_PARENT);
imageView.setImageDrawable(context.getResources().getDrawable(R.drawable.all_add));
addView.addView(imageView, params1);
addParams = new LayoutParams(imagesize, imagesize);
addParams.setMargins(margin, margin, margin, margin);
addView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null)
listener.OnAddClick();
}
});
}
暴露几个函数,这里只给出添加图片的函数
public NineImageView addImage(String path) {
this.list.add(path);
initView();
return this;
}
public void commit() {
postInvalidate();
}
刷新布局
private void initView() {
//先清空所有的图片
base0.removeAllViews();
base1.removeAllViews();
base2.removeAllViews();
if (list.size() <= 0) {//如果没有图片需要显示,直接添加按钮
base0.addView(addView, addParams);
showBase0();
} else {
switch (list.size() / 3) {
case 0:
//3张以内,按钮在第一排
for (int i = 0; i < list.size(); i++) {
addImage(base0, list.get(i), i);
}
base0.addView(addView, addParams);
showBase0();
break;
case 1:
//6张以内,按钮在第二排
for (int i = 0; i < 3; i++) {
addImage(base0, list.get(i), i);
}
for (int i = 3; i < list.size(); i++) {
addImage(base1, list.get(i), i);
}
base1.addView(addView, addParams);
showBase1();
break;
case 2:
//9张以内,按钮在第三排
for (int i = 0; i < 3; i++) {
addImage(base0, list.get(i), i);
}
for (int i = 3; i < 6; i++) {
addImage(base1, list.get(i), i);
}
for (int i = 6; i < list.size(); i++) {
addImage(base2, list.get(i), i);
}
base2.addView(addView, addParams);
showBase2();
break;
case 3:
//9张,按钮消失
for (int i = 0; i < 3; i++) {
addImage(base0, list.get(i), i);
}
for (int i = 3; i < 6; i++) {
addImage(base1, list.get(i), i);
}
for (int i = 6; i < 9; i++) {
addImage(base2, list.get(i), i);
}
showBase2();
break;
}
}
}
private void showBase0() {
base0.setVisibility(VISIBLE);
base1.setVisibility(GONE);
base2.setVisibility(GONE);
}
private void showBase1() {
base0.setVisibility(VISIBLE);
base1.setVisibility(VISIBLE);
base2.setVisibility(GONE);
}
private void showBase2() {
base0.setVisibility(VISIBLE);
base1.setVisibility(VISIBLE);
base2.setVisibility(VISIBLE);
}
private void addImage(LinearLayout layout, String s, final int pos) {
ImageView imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
LinearLayout.LayoutParams params = new LayoutParams(imagesize, imagesize);
ImageUtils.getInstance(context).loadImage(s, imageView);
params.setMargins(margin, margin, margin, margin);
layout.addView(imageView, params);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null)
listener.OnImageClick(list.get(pos), pos);
}
});
}
然后再根据自己需要,写一些其他的函数,比如remove函数之类的,再暴露出图片点击接口,按钮点击接口,就可以了。由于不是太复杂的需要,所以并没有多扩展什么功能,感兴趣的朋友可以自行扩展。
源代码:
/**
* Created by simple on 2017/4/5.
*/
public class NineImageView extends LinearLayout {
private Context context;
private List<String> list;
private int height;
private int width;
private int margin;
private int imagesize;
public NineImageView(Context context) {
super(context);
}
RelativeLayout addView;
LinearLayout.LayoutParams addParams;
LinearLayout.LayoutParams baseParams;
LinearLayout base0;
LinearLayout base1;
LinearLayout base2;
public NineImageView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
this.list = new ArrayList<>();//存放图片地址的list
this.margin = ScreenUtils.dip2px(context, 4);//图片显示的边距
this.height = ScreenUtils.getScreenWidth(context) / 3;//布局的高
this.width = ScreenUtils.getScreenWidth(context);//布局的宽
this.imagesize = height - margin * 2;//图片的大小
setOrientation(VERTICAL);
createBaseView();
createAddView();
}
private void createBaseView() {
baseParams = new LayoutParams(width, height);
base0 = new LinearLayout(context);
base0.setOrientation(HORIZONTAL);
base1 = new LinearLayout(context);
base1.setOrientation(HORIZONTAL);
base2 = new LinearLayout(context);
base2.setOrientation(HORIZONTAL);
addView(base0, baseParams);
addView(base1, baseParams);
addView(base2, baseParams);
}
private void createAddView() {
addView = new RelativeLayout(context);
addView.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.heart_add_bk));
ImageView imageView = new ImageView(context);
RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params1.addRule(RelativeLayout.CENTER_IN_PARENT);
imageView.setImageDrawable(context.getResources().getDrawable(R.drawable.all_add));
addView.addView(imageView, params1);
addParams = new LayoutParams(imagesize, imagesize);
addParams.setMargins(margin, margin, margin, margin);
addView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null)
listener.OnAddClick();
}
});
}
private void initView() {
//先清空所有的图片
base0.removeAllViews();
base1.removeAllViews();
base2.removeAllViews();
if (list.size() <= 0) {//如果没有图片需要显示,直接添加按钮
base0.addView(addView, addParams);
showBase0();
} else {
switch (list.size() / 3) {
case 0:
//3张以内,按钮在第一排
for (int i = 0; i < list.size(); i++) {
addImage(base0, list.get(i), i);
}
base0.addView(addView, addParams);
showBase0();
break;
case 1:
//6张以内,按钮在第二排
for (int i = 0; i < 3; i++) {
addImage(base0, list.get(i), i);
}
for (int i = 3; i < list.size(); i++) {
addImage(base1, list.get(i), i);
}
base1.addView(addView, addParams);
showBase1();
break;
case 2:
//9张以内,按钮在第三排
for (int i = 0; i < 3; i++) {
addImage(base0, list.get(i), i);
}
for (int i = 3; i < 6; i++) {
addImage(base1, list.get(i), i);
}
for (int i = 6; i < list.size(); i++) {
addImage(base2, list.get(i), i);
}
base2.addView(addView, addParams);
showBase2();
break;
case 3:
//9张,按钮消失
for (int i = 0; i < 3; i++) {
addImage(base0, list.get(i), i);
}
for (int i = 3; i < 6; i++) {
addImage(base1, list.get(i), i);
}
for (int i = 6; i < 9; i++) {
addImage(base2, list.get(i), i);
}
showBase2();
break;
}
}
}
private void showBase0() {
base0.setVisibility(VISIBLE);
base1.setVisibility(GONE);
base2.setVisibility(GONE);
}
private void showBase1() {
base0.setVisibility(VISIBLE);
base1.setVisibility(VISIBLE);
base2.setVisibility(GONE);
}
private void showBase2() {
base0.setVisibility(VISIBLE);
base1.setVisibility(VISIBLE);
base2.setVisibility(VISIBLE);
}
private void addImage(LinearLayout layout, String s, final int pos) {
ImageView imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
LinearLayout.LayoutParams params = new LayoutParams(imagesize, imagesize);
ImageUtils.getInstance(context).loadImage(s, imageView);
params.setMargins(margin, margin, margin, margin);
layout.addView(imageView, params);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null)
listener.OnImageClick(list.get(pos), pos);
}
});
}
public NineImageView addImage(String path) {
this.list.add(path);
initView();
return this;
}
public NineImageView addImage(List<PhotoInfo> list) {
for (PhotoInfo info : list)
this.list.add(info.getPhotoPath());
initView();
return this;
}
public NineImageView setImage(List<PhotoInfo> list) {
this.list = new ArrayList<>();
for (PhotoInfo info : list)
this.list.add(info.getPhotoPath());
initView();
return this;
}
public ArrayList<String> getImageList() {
return (ArrayList<String>) this.list;
}
public NineImageView remove(int position) {
this.list.remove(position);
initView();
return this;
}
public void commit() {
postInvalidate();
}
public NineImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
OnClickListener listener;
public interface OnClickListener {
void OnAddClick();
void OnImageClick(String uri, int position);
}
public void setOnClickListener(OnClickListener listener) {
this.listener = listener;
}
}