自定義view 圖片展示 九宮格 完美適配
阿新 • • 發佈:2019-01-01
有一段時間沒有寫了,一直在趕專案,沒有辦法。
專案中有一個需求 相信很多專案都會有 多圖上傳 然後展示多圖 相信百度很多這樣的開源控制元件。下面簡單介紹我使用的這個控制元件
先直接上程式碼(包含其中所有程式碼)
package com.mly.view; import java.util.List; import android.content.Context; import android.graphics.Color; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import com.mly.entity.Image; import com.mly.util.ScreenTools; /** * */ public class NineGridlayout extends ViewGroup { /** * 圖片之間的間隔 */ private int gap = 5; private int columns;// private int rows;// private List<Image> listData; //圖片數量 private int totalWidth; private ItemClick itemClick; public ItemClick getItemClick() { return itemClick; } public void setItemClick(ItemClick itemClick) { this.itemClick = itemClick; } 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) { } int x = 0; private void layoutChildrenView() { int childrenCount = listData.size(); int singleWidth; if (listData.size() == 1) { singleWidth = totalWidth; } else { singleWidth = (totalWidth - gap * (3 - 1)) / 3; } int singleHeight = singleWidth; // 根據子view數量確定高度 ViewGroup.LayoutParams params = getLayoutParams(); params.height = singleHeight * rows + gap * (rows - 1); setLayoutParams(params); for (int i = 0; i < childrenCount; i++) { x = i; // CustomImageView childrenView = (CustomImageView) getChildAt(i); QPImageView childrenView = (QPImageView) getChildAt(i); // childrenView.setImageUrl(((Image) listData.get(i)).getUrl()); childrenView.setImageUrl(listData.get(i).getUrl()); // 檢視大圖 childrenView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { for (int j = 0; j < getChildCount(); j++) { if(v==getChildAt(j)){ if(itemClick!=null) itemClick.itemClick(j); break; } } } }); 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); } } private int[] findPosition(int childNum) { int[] position = new int[2]; for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { if ((i * columns + j) == childNum) { position[0] = i;// 行 position[1] = j;// 列 break; } } } return position; } public int getGap() { return gap; } public void setGap(int gap) { this.gap = gap; } public void setImagesData(List<Image> lists) { if (lists == null || lists.isEmpty()) { return; } // 初始化佈局 generateChildrenLayout(lists.size()); // 這裡做一個重用view的處理 if (listData == null) { int i = 0; while (i < lists.size()) { ImageView 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++) { ImageView iv = generateImageView(); addView(iv, generateDefaultLayoutParams()); } } } listData = lists; layoutChildrenView(); } /** * 根據圖片個數確定行列數量 對應關係如下 num(數量) row(行) column(列) * 1 1 1
1 1 1 0 * 2 1 2 2 1 2 0 * 3 1 3 3 1 3 0 * 4 2 2 4 1 4 0 * 5 2 3 5 2 4 * 6 2 3 6 2 4 * 7 3 3 7 2 4 * 8 3 3 8 2 4 * 9 3 3 9 3 4 * 10 3 4 * 11 3 4 * 12 4 4 * * @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; } } private ImageView generateImageView() { //java程式碼實現控制元件和屬性 不用xml實現 QPImageView iv = new QPImageView(getContext()); iv.setScaleType(ImageView.ScaleType.CENTER_CROP); iv.setBackgroundColor(Color.parseColor("#f5f5f5")); return iv; } public static interface ItemClick{ public void itemClick(int index); //自定義條目點選介面 } }
package com.mly.view; import android.content.Context; import android.graphics.Bitmap; import android.util.AttributeSet; import android.widget.ImageView; import com.frame.util.XHLog; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.assist.ImageScaleType; import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer; import com.qxp.R; public class QPImageView extends ImageView { private final static String TAG="com.qpp.view.QPImageView"; private String url; private ImageLoader loader = ImageLoader.getInstance(); public QPImageView(Context context) { super(context); // TODO Auto-generated constructor stub } public QPImageView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public QPImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public void setImageUrl(String url) { if (url.equals(this.url)) return; XHLog.e(TAG, url); this.url = url; loader.displayImage(url, this); } public static DisplayImageOptions MyDisplayImageOptions() { DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(R.drawable.loading_pic) //設定圖片在下載期間顯示的圖片 .showImageForEmptyUri(R.drawable.loading_pic)//設定圖片Uri為空或是錯誤的時候顯示的圖片 .showImageOnFail(R.drawable.loading_pic) //設定圖片載入/解碼過程中錯誤時候顯示的圖片 .cacheInMemory(true)//設定下載的圖片是否快取在記憶體中 .cacheOnDisk(true) .considerExifParams(true) //是否考慮JPEG影象EXIF引數(旋轉,翻轉) .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)//設定圖片以如何的編碼方式顯示 .bitmapConfig(Bitmap.Config.RGB_565)//設定圖片的解碼型別// .displayer(new RoundedBitmapDisplayer(10))//是否設定為圓角,弧度為多少 // .displayer(new FadeInBitmapDisplayer(100))//是否圖片載入好後漸入的動畫時間 .build();//構建完成 return options; } }
ScreenTools(dp px 互轉工具)
package com.mly.util;
import android.content.Context;
public class ScreenTools {
private static ScreenTools mScreenTools;
private Context context;
private ScreenTools(Context context) {
this.context = context.getApplicationContext();
}
public static ScreenTools instance(Context context) {
if (mScreenTools == null)
mScreenTools = new ScreenTools(context);
return mScreenTools;
}
public int dip2px(float f) {
return (int) (0.5D + (double) (f * getDensity(context)));
}
public int dip2px(int i) {
return (int) (0.5D + (double) (getDensity(context) * (float) i));
}
public int get480Height(int i) {
return (i * getScreenWidth()) / 480;
}
public float getDensity(Context context) {
return context.getResources().getDisplayMetrics().density;
}
public int getScal() {
return (100 * getScreenWidth()) / 480;
}
public int getScreenDensityDpi() {
return context.getResources().getDisplayMetrics().densityDpi;
}
public int getScreenHeight() {
return context.getResources().getDisplayMetrics().heightPixels;
}
public int getScreenWidth() {
return context.getResources().getDisplayMetrics().widthPixels;
}
public float getXdpi() {
return context.getResources().getDisplayMetrics().xdpi;
}
public float getYdpi() {
return context.getResources().getDisplayMetrics().ydpi;
}
public int px2dip(float f) {
float f1 = getDensity(context);
return (int) (((double) f - 0.5D) / (double) f1);
}
public int px2dip(int i) {
float f = getDensity(context);
return (int) (((double) i - 0.5D) / (double) f);
}
}
Image 實體類
package com.mly.entity;
/**
* Created by Pan_ on 2015/2/3.
*/
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;
}
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;
}
}
使用方法: xml 中 直接使用 包類名 高 可固定 寬不要固定
由於網路圖片都是String 型別,我們解析資料得到的也是List<String> pic
所以我們需要轉成 List<Image> data 才能被控制元件接受 其實很簡單 new 一個 List<Image> data for迴圈呼叫 Image.seturl(); 既可以完成。