一百行代碼實(shí)現(xiàn)微信朋友圈九宮格圖片顯示
來(lái)源:程序員人生 發(fā)布時(shí)間:2015-05-14 08:44:43 閱讀次數(shù):9871次
前言
很多時(shí)候我們都在刷微博或微信朋友圈的時(shí)候都會(huì)看到很多圖片,而這些圖片的顯示跟我們平時(shí)很多控件的顯示方式都不1樣,而且,當(dāng)我們仔細(xì)去視察后就會(huì)發(fā)現(xiàn),他加載的圖片都是根據(jù)圖片數(shù)量動(dòng)態(tài)加載的,根據(jù)不同的圖片數(shù)量來(lái)用不同的布局顯示
當(dāng)圖片是4張的時(shí)候,就會(huì)構(gòu)成1個(gè)2x2的正方形,除1張的情況,另外的都是依照9宮格的方式顯示和排列圖片的。那末這類布局是怎樣實(shí)現(xiàn)的呢,1開(kāi)始,好多人都可能認(rèn)為用原生的GridView就可以弄掂,但是,卻有幾種特殊的情況是GridView解決不了的,例如4張圖片的情況,或1張,其實(shí)也能夠根據(jù)圖片的數(shù)量然后用幾個(gè)不同布局的GridView來(lái)實(shí)現(xiàn),不過(guò)那樣的話就復(fù)雜很多了。而且處理起來(lái)很麻煩,其實(shí),大部份的實(shí)現(xiàn)都是通過(guò)自定義ViewGroup來(lái)實(shí)現(xiàn)的,通過(guò)代碼編寫來(lái)設(shè)定childrenView的layout來(lái)實(shí)現(xiàn)這類布局,而NineGridView控件就是這么1個(gè)東西,代碼其實(shí)很簡(jiǎn)單,100行就夠了。
代碼編寫
先自定義1個(gè)View集成ViewGroup,編輯器會(huì)提示你實(shí)現(xiàn)OnLayout方法,實(shí)現(xiàn)之,這里我們動(dòng)態(tài)的添加的話其實(shí)不用到OnLayout方法,自定義1個(gè)layoutChildrenView()用來(lái)為子view設(shè)定位置就好了,該方法的實(shí)現(xiàn)以下:
這代碼里面在調(diào)用子view的layout方法的同時(shí)設(shè)定了本身ViewGroup的高度大小,由于NineGridView的高度是要根據(jù)子View的高度來(lái)肯定的.
-
private void layoutChildrenView(){
-
int childrenCount = listData.size();
-
-
int singleWidth = (totalWidth - gap * (3 - 1)) / 3;
-
int singleHeight = singleWidth;
-
-
//根據(jù)子view數(shù)量肯定高度
-
ViewGroup.LayoutParams params = getLayoutParams();
-
params.height = singleHeight * rows + gap * (rows - 1);
-
setLayoutParams(params);
-
-
for (int i = 0; i < childrenCount; i++) {
-
CustomImageView childrenView = (CustomImageView) getChildAt(i);
-
childrenView.setImageUrl(((Image) listData.get(i)).getUrl());
-
int[] position = findPosition(i);
-
int left = (singleWidth + gap) * position[1];
-
int top = (singleHeight + gap) * position[0];
-
int right = left + singleWidth;
-
int bottom = top + singleHeight;
-
-
childrenView.layout(left, top, right, bottom);
-
}
-
-
}
復(fù)制代碼
添加1個(gè)設(shè)置圖片資源的接口,1般情況下我們都是用在listview來(lái)顯示數(shù)據(jù),而數(shù)據(jù)都是封裝好的,這里提供1個(gè)Image封裝類,接口和封裝類代碼以下:
-
public void setImagesData(List<Image> lists) {
-
if (lists == null || lists.isEmpty()) {
-
return;
-
}
-
//初始化布局
-
generateChildrenLayout(lists.size());
-
//這里做1個(gè)重用view的處理
-
if (listData == null) {
-
int i = 0;
-
while (i < lists.size()) {
-
CustomImageView iv = generateImageView();
-
addView(iv,generateDefaultLayoutParams());
-
i++;
-
}
-
} else {
-
int oldViewCount = listData.size();
-
int newViewCount = lists.size();
-
if (oldViewCount > newViewCount) {
-
removeViews(newViewCount - 1, oldViewCount - newViewCount);
-
} else if (oldViewCount < newViewCount) {
-
for (int i = 0; i < newViewCount - oldViewCount; i++) {
-
CustomImageView iv = generateImageView();
-
addView(iv,generateDefaultLayoutParams());
-
}
-
}
-
}
-
listData = lists;
-
layoutChildrenView();
-
}
復(fù)制代碼
Image封裝類:
-
-
public class Image {
-
private String url;
-
private int width;
-
private int height;
-
-
public Image(String url, int width, int height) {
-
this.url = url;
-
this.width = width;
-
this.height = height;
-
L.i(toString());
-
}
-
-
public String getUrl() {
-
return url;
-
}
-
-
public void setUrl(String url) {
-
this.url = url;
-
}
-
-
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;
-
}
-
-
@Override
-
public String toString() {
-
-
return "image---->>url="+url+"width="+width+"height"+height;
-
}
-
}
-
復(fù)制代碼
在添加數(shù)據(jù)的時(shí)候,我們要根據(jù)圖片的個(gè)數(shù)來(lái)肯定具體的布局情況,這個(gè)函數(shù)就是generateChildrenLayout(),實(shí)現(xiàn)以下:
-
/**
-
* 根據(jù)圖片個(gè)數(shù)肯定行列數(shù)量
-
* 對(duì)應(yīng)關(guān)系以下
-
* num row column
-
* 1 1 1
-
* 2 1 2
-
* 3 1 3
-
* 4 2 2
-
* 5 2 3
-
* 6 2 3
-
* 7 3 3
-
* 8 3 3
-
* 9 3 3
-
*
-
* @param length
-
*/
-
private void generateChildrenLayout(int length) {
-
if (length <= 3) {
-
rows = 1;
-
columns = length;
-
} else if (length <= 6) {
-
rows = 2;
-
columns = 3;
-
if (length == 4) {
-
columns = 2;
-
}
-
} else {
-
rows = 3;
-
columns = 3;
-
}
-
}
復(fù)制代碼
這些,就是NineGridLayout的核心代碼了,是否是很簡(jiǎn)單,全部類的源碼以下:
-
package com.weixinninegridlayout;
-
-
import android.content.Context;
-
import android.graphics.Color;
-
import android.graphics.drawable.ColorDrawable;
-
import android.util.AttributeSet;
-
import android.view.View;
-
import android.view.ViewGroup;
-
import android.widget.ImageView;
-
-
import java.util.List;
-
-
-
/**
-
* Created by Pan_ on 2015/2/2.
-
*/
-
public class NineGridlayout extends ViewGroup {
-
-
/**
-
* 圖片之間的間隔
-
*/
-
private int gap = 5;
-
private int columns;//
-
private int rows;//
-
private List listData;
-
private int totalWidth;
-
-
public NineGridlayout(Context context) {
-
super(context);
-
}
-
-
public NineGridlayout(Context context, AttributeSet attrs) {
-
super(context, attrs);
-
ScreenTools screenTools=ScreenTools.instance(getContext());
-
totalWidth=screenTools.getScreenWidth()-screenTools.dip2px(80);
-
}
-
-
@Override
-
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
}
-
-
@Override
-
protected void onLayout(boolean changed, int l, int t, int r, int b) {
-
-
}
-
private void layoutChildrenView(){
-
int childrenCount = listData.size();
-
-
int singleWidth = (totalWidth - gap * (3 - 1)) / 3;
-
int singleHeight = singleWidth;
-
-
//根據(jù)子view數(shù)量肯定高度
-
ViewGroup.LayoutParams params = getLayoutParams();
-
params.height = singleHeight * rows + gap * (rows - 1);
-
setLayoutParams(params);
-
-
for (int i = 0; i < childrenCount; i++) {
-
CustomImageView childrenView = (CustomImageView) getChildAt(i);
-
childrenView.setImageUrl(((Image) listData.get(i)).getUrl());
-
int[] position = findPosition(i);
-
生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
------分隔線----------------------------
------分隔線----------------------------