先看下效果图:


关键类:NineGridLayout
public abstract class NineGridLayout extends ViewGroup {
private static final float DEFUALT_SPACING = 3f;
private float image_ratio = 1.7f;//默认图片长宽比例
private int oneImageWidth;//一张图的宽度
private int oneImageHeight;//一张图的高度
protected Context mContext;
private float mSpacing = DEFUALT_SPACING;
private int mColumns;
private int mRows;
private int mTotalWidth;
private int mSingleWidth;
private boolean isNeedClick = true ; // 是否需要item的点击处理
private boolean mIsShowAll = false;
private boolean mIsFirst = true;
private List<PhotoInfo> mUrlList = new ArrayList<>();
public NineGridLayout(Context context) {
this(context, null);
}
public NineGridLayout(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NineGridLayout);
mSpacing = typedArray.getDimension(R.styleable.NineGridLayout_sapcing, DEFUALT_SPACING);
oneImageWidth = (int) typedArray.getDimension(R.styleable.NineGridLayout_oneImageWidth, 0);
oneImageHeight = (int) typedArray.getDimension(R.styleable.NineGridLayout_oneImageHeight, 0);
image_ratio = typedArray.getFloat(R.styleable.NineGridLayout_image_ratio, image_ratio);
typedArray.recycle();
init(context);
}
public void setItemIsNeedClick(boolean isNeedClick){
this.isNeedClick = isNeedClick;
}
private void init(Context context) {
mContext = context;
if (getListSize(mUrlList) == 0) {
setVisibility(GONE);
}else {
setVisibility(VISIBLE);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
mTotalWidth = right - left;
mSingleWidth = (int) ((mTotalWidth - mSpacing * (3 - 1)) / 3);
if (mIsFirst) {//只绘制一次
notifyDataSetChanged();
mIsFirst = false;
}
}
/**
* 设置间隔
*
* @param spacing
*/
public void setSpacing(float spacing) {
mSpacing = spacing;
}
/**
* 设置是否显示所有图片(超过最大数时)
*
* @param isShowAll
*/
public void setIsShowAll(boolean isShowAll) {
mIsShowAll = isShowAll;
}
public void setUrlList(List<PhotoInfo> urlList) {
if (getListSize(urlList) == 0) {
setVisibility(GONE);
return;
}
setVisibility(VISIBLE);
mUrlList.clear();
mUrlList.addAll(urlList);
if (!mIsFirst) {//由于使用在RecyclerView中牵扯到复用布局,所以需要判断当前布局是不是第一次使用,是的话就直接绘制,不是的话就移除掉恰他的布局再绘制
notifyDataSetChanged();
}
}
public void notifyDataSetChanged() {
post(new TimerTask() {
@Override
public void run() {
refresh();
}
});
}
private void refresh() {
removeAllViews();
int size = getListSize(mUrlList);
if (size > 0) {
setVisibility(VISIBLE);
} else {
setVisibility(GONE);
return;
}
if (size == 1) {
PhotoInfo photoInfo = mUrlList.get(0);
RatioImageView imageView = createImageView(0, photoInfo.getImg());
getRealOneImageSize();
imageView.layout(0, 0, oneImageWidth, oneImageHeight);
LayoutParams params = getLayoutParams();
params.height = oneImageHeight;
setLayoutParams(params);
addView(imageView);
displayImage(0,imageView, photoInfo.getImg());
return;
}
generateChildrenLayout(size);
layoutParams();
for (int i = 0; i < size; i++) {
PhotoInfo photoInfo = mUrlList.get(i);
RatioImageView imageView = createImageView(i, photoInfo.getSmallImg());
layoutImageView(imageView, i, photoInfo.getSmallImg());
}
}
private void getRealOneImageSize() {
if(oneImageWidth==0){
oneImageWidth = mSingleWidth;
}
if(oneImageHeight==0){
oneImageHeight = (int) (oneImageWidth * image_ratio);
}
}
private void layoutParams() {
int singleHeight = mSingleWidth;
//根据子view数量确定高度
LayoutParams params = getLayoutParams();
params.height = (int) (singleHeight * mRows + mSpacing * (mRows - 1));
setLayoutParams(params);
}
private RatioImageView createImageView(final int i, final String url) {
final RatioImageView imageView = new RatioImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
if(isNeedClick){
imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onClickImage(i, url, mUrlList,imageView);
}
});
}
return imageView;
}
/**
* @param imageView
* @param url
*/
private void layoutImageView(RatioImageView imageView, int i, String url) {
final int singleWidth = (int) ((mTotalWidth - mSpacing * (3 - 1)) / 3);
int singleHeight = singleWidth;
int[] position = findPosition(i);
int left = (int) ((singleWidth + mSpacing) * position[1]);
int top = (int) ((singleHeight + mSpacing) * position[0]);
int right = left + singleWidth;
int bottom = top + singleHeight;
imageView.layout(left, top, right, bottom);
addView(imageView);
displayImage(i,imageView, url);
}
private int[] findPosition(int childNum) {
int[] position = new int[2];
for (int i = 0; i < mRows; i++) {
for (int j = 0; j < mColumns; j++) {
if ((i * mColumns + j) == childNum) {
position[0] = i;//行
position[1] = j;//列
break;
}
}
}
return position;
}
/**
* 根据图片个数确定行列数量
*
* @param length
*/
private void generateChildrenLayout(int length) {
if (length <= 3) {
mRows = 1;
mColumns = length;
} else if (length <= 6) {
mRows = 2;
mColumns = 3;
if (length == 4) {
mColumns = 2;
}
} else {
mColumns = 3;
if (mIsShowAll) {
mRows = length / 3;
int b = length % 3;
if (b > 0) {
mRows++;
}
} else {
mRows = 3;
}
}
}
private int getListSize(List<PhotoInfo> list) {
if (list == null || list.size() == 0) {
return 0;
}
return list.size();
}
protected abstract void displayImage(int position,RatioImageView imageView, String url);
protected abstract void onClickImage(int position, String url, List<PhotoInfo> urlList, ImageView imageView);
}
牵扯到的类
RatioImageView
public class RatioImageView extends AppCompatImageView {
/**
* 宽高比例
*/
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 != 0) {
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:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
break;
}
return super.onTouchEvent(event);
}
}
PhotoInfo
public class PhotoInfo implements Serializable {
private String img;
private int id;
private String smallImg;
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSmallImg() {
return smallImg;
}
public void setSmallImg(String smallImg) {
this.smallImg = smallImg;
}
private int photoId;
private String photoPath;
//private String thumbPath;
private int width;
private int height;
//视频信息
private String videoId;
private String coverURL;
private String playAuth;
private int zoneVideoId;
public PhotoInfo() {
}
public int getZoneVideoId() {
return zoneVideoId;
}
public void setZoneVideoId(int zoneVideoId) {
this.zoneVideoId = zoneVideoId;
}
public String getVideoId() {
return videoId;
}
public void setVideoId(String videoId) {
this.videoId = videoId;
}
public String getCoverURL() {
return coverURL;
}
public void setCoverURL(String coverURL) {
this.coverURL = coverURL;
}
public String getPlayAuth() {
return playAuth;
}
public void setPlayAuth(String playAuth) {
this.playAuth = playAuth;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getPhotoPath() {
return photoPath;
}
public void setPhotoPath(String photoPath) {
this.photoPath = photoPath;
}
public int getPhotoId() {
return photoId;
}
public void setPhotoId(int photoId) {
this.photoId = photoId;
}
//
//public String getThumbPath() {
// return thumbPath;
//}
//
//public void setThumbPath(String thumbPath) {
// this.thumbPath = thumbPath;
//}
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof PhotoInfo)) {
return false;
}
PhotoInfo info = (PhotoInfo) o;
if (info == null) {
return false;
}
return TextUtils.equals(info.getPhotoPath(), getPhotoPath());
}
}
注:NineGridLayout和RatioImageView非原创,在别人基础上修改的
使用示例
MyNineGridLayout mngl = helper.getView(R.id.ngl_mood);
mngl.setUrlList(item.getZoneImgList());
//注:
public List<PhotoInfo> getZoneImgList() {
return zoneImgList;
}
注:MyNineGridLayout是我写的子类,你只要同样写个子类,然后在重写图片加载显示和点击跳转即可
有问题请评论或者私信我。
网友评论