Android NineGridLayout — 仿微信朋友圈和QQ空间的九宫格图片展示自定义控件
- 作者: 五速梦信息网
- 时间: 2026年04月04日 13:52
NineGridLayout
一个仿微信朋友圈和QQ空间的九宫格图片展示自定义控件。

一、介绍
1、当只有1张图时,可以自己定制图片宽高,也可以使用默认九宫格的宽高;
2、当只有4张图时,以2*2的方式显示;<br/>
3、除以上两种情况下,都是按照3列方式显示,但这时有一些细节:<br/>
a、如果只有9张图,当然是以3*3的方式显示;<br/>
b、如果超过9张图,可以设置是否全部显示。<br/>
如果设置不完全显示,则按照3*3的方式显示,但是在第9张图上会有一个带“+”号的数字,<br/>
代表还有几张没有显示,这里是模仿了QQ空间图片超出9张的显示方式;<br/>
如果设置全部显示,理所当然的将所有图片都显示出来。<br/>
4、图片被按下时,会有一个变暗的效果,这也是模仿微信朋友圈的效果。<br/>
二、使用方法
1、核心类是NineGridLayout,继承自ViewGroup的抽象类,所以我们实际项目使用需要继承它,并要实现3个方法,如下:
public abstract class NineGridLayout extends ViewGroup {
//******************************其他代码省略**************************
/**
* 显示一张图片<br/>
* @param imageView<br/>
* @param url<br/>
* @param parentWidth 父控件宽度<br/>
* @return true 代表按照九宫格默认大小显示,false 代表按照自定义宽高显示<br/>
*/<br/>
protected abstract boolean displayOneImage(RatioImageView imageView, String url, int parentWidth);
protected abstract void displayImage(RatioImageView imageView, String url);
/**
* 点击图片时执行<br/>
*/<br/>
protected abstract void onClickImage(int position, String url, List<String> urlList);<br/>
}</pre>
2、我这里用NineGridTestLayout继承NineGridLayout实现,displayOneImage()与displayImage()中的参数都是显示图片需要的,我这里用的是ImageLoader显示图片,当然你也可以用其他的。
public class NineGridTestLayout extends NineGridLayout {
protected static final int MAX_W_H_RATIO = ;
public NineGridTestLayout(Context context) {
super(context);<br/>
}
public NineGridTestLayout(Context context, AttributeSet attrs) {
super(context, attrs);<br/>
}
@Override
protected boolean displayOneImage(final RatioImageView imageView, String url, final int parentWidth) {
//这里是只显示一张图片的情况,显示图片的宽高可以根据实际图片大小自由定制,parentWidth 为该layout的宽度
ImageLoader.getInstance().displayImage(imageView, url, ImageLoaderUtil.getPhotoImageOption(), new ImageLoadingListener() {<br/>
@Override<br/>
public void onLoadingStarted(String imageUri, View view) {
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap bitmap) {<br/>
int w = bitmap.getWidth();<br/>
int h = bitmap.getHeight();
int newW;
int newH;<br/>
if (h > w * MAX_W_H_RATIO) {//h:w = 5:3<br/>
newW = parentWidth / ;<br/>
newH = newW * / ;<br/>
} else if (h < w) {//h:w = 2:3<br/>
newW = parentWidth * / ;<br/>
newH = newW * / ;<br/>
} else {//newH:h = newW :w<br/>
newW = parentWidth / ;<br/>
newH = h * newW / w;<br/>
}<br/>
setOneImageLayoutParams(imageView, newW, newH);<br/>
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
}
});<br/>
return false;// true 代表按照九宫格默认大小显示(此时不要调用setOneImageLayoutParams);false 代表按照自定义宽高显示。<br/>
}
@Override
protected void displayImage(RatioImageView imageView, String url) {<br/>
ImageLoaderUtil.getImageLoader(mContext).displayImage(url, imageView, ImageLoaderUtil.getPhotoImageOption());<br/>
}
@Override
protected void onClickImage(int i, String url, List<String> urlList) {<br/>
Toast.makeText(mContext, "点击了图片" + url, Toast.LENGTH_SHORT).show();<br/>
}<br/>
}
3、在xml中实现
<com.hmy.ninegridlayout.view.NineGridTestLayout xmlns:app=“http://schemas.android.com/apk/res-auto"
android:id="@+id/layout_nine_grid"<br/>
android:layout_width="match_parent"<br/>
android:layout_height="wrap_content"<br/>
android:layout_marginTop="8dp"<br/>
app:sapcing="4dp" /></pre>
app:sapcing是设置九宫格中图片之间的间隔。
4、使用:
public List<String> urlList = new ArrayList<>();//图片url
NineGridTestLayout layout = (NineGridTestLayout) view.findViewById(R.id.layout_nine_grid);<br/>
layout.setIsShowAll(false); //当传入的图片数超过9张时,是否全部显示<br/>
layout.setSpacing(); //动态设置图片之间的间隔<br/>
layout.setUrlList(urlList); //最后再设置图片url</pre>
三、核心类
NineGridLayout.java
RatioImageView.Java
该类有两个功能:
1、是用于ImageView被按下时有变暗效果
2、ImageView的宽高根据设置的比例动态适配高度,如在xml中设置 app:ratio=”2“ ,ImageView的高度根据其宽度改变,但始终是宽的2倍,该功能在该项目中没有使用。
/**
- 根据宽高比例自动计算高度ImageView
- Created by HMY on 2016/4/21.
*/
public class RatioImageView extends ImageView { /**
- 宽高比例
*/
private float mRatio = 0f; public RatioImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
} public RatioImageView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RatioImageView); mRatio = typedArray.getFloat(R.styleable.RatioImageView_ratio, 0f);
typedArray.recycle();
} public RatioImageView(Context context) {
super(context);
} /** - 设置ImageView的宽高比
* - @param ratio
*/
public void setRatio(float ratio) {
mRatio = ratio;
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
if (mRatio != ) {
float height = width / mRatio;
heightMeasureSpec = MeasureSpec.makeMeasureSpec((int) height, MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} @Override
public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Drawable drawable = getDrawable();
if (drawable != null) {
drawable.mutate().setColorFilter(Color.GRAY,
PorterDuff.Mode.MULTIPLY);
}
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
Drawable drawableUp = getDrawable();
if (drawableUp != null) {
drawableUp.mutate().clearColorFilter();
}
break;
} return super.onTouchEvent(event);
} }代码可在我的GitHub上下载,地址:https://github.com/HMY314/NineGridLayout
效果图

- 宽高比例
相关文章
-
android opencv 图像 查找 匹配
android opencv 图像 查找 匹配
- 互联网
- 2026年04月04日
-
Android Ormlite 学习笔记1
Android Ormlite 学习笔记1
- 互联网
- 2026年04月04日
-
Android SDK下载失败的解决方法
Android SDK下载失败的解决方法
- 互联网
- 2026年04月04日
-
Android Kotlin 导入 Protobuf
Android Kotlin 导入 Protobuf
- 互联网
- 2026年04月04日
-
Android Hawk数据库 github开源项目
Android Hawk数据库 github开源项目
- 互联网
- 2026年04月04日
-
Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器
Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器
- 互联网
- 2026年04月04日








