要完成自定義加載圖片的九宮格的步驟
1:寫一個類繼承ViewGroup,同時實現他的構造方法,當然自己使用實現兩個就完全可以了,不要忘了ViewGroup還有一個必須實現的方法onLaout
public classSudokuextendsViewGroup
publicSudoku(Context context) {this(context,null);}
publicSudoku(Context context, AttributeSet attrs) {this(context, attrs,0);}
publicSudoku(Context context, AttributeSet attrs,intdefStyleAttr)
?{super(context, attrs, defStyleAttr);? ? init(context,attrs);}
//這個方法是用來控制子view擺放的位置的這里我們不做處理
@Overrideprotected voidonLayout(booleanchanged,intl,intt,intr,intb) {}
//init方法是用來初始化屬性的
private voidinit(Context context, AttributeSet attrs) {
this.context= context;? ??
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SudokulayoutStyle);//設置自定義屬性
space= typedArray.getDimensionPixelSize(R.styleable.SudokulayoutStyle_space,10);//圖片的間距
imColumn= typedArray.getInteger(R.styleable.SudokulayoutStyle_column_image,3);//一列有幾張圖
width=typedArray.getDimensionPixelSize(R.styleable.SudokulayoutStyle_total_width,720);//layout的寬度
maxheight=typedArray.getDimensionPixelSize(R.styleable.SudokulayoutStyle_oneimage_maxheight,810);//單張圖片最大的高度
maxwidth=typedArray.getDimensionPixelSize(R.styleable.SudokulayoutStyle_oneimage_maxwidth,810);//單張圖片最大的寬度? ??
typedArray.recycle();}
//在這里我們看到了自定義屬性。怎么設置自定義屬性呢?需要在res文件中的values文件夾里創建atts.xml文件,已有的就不用創建了
//自定義屬性設置完了那我們就需要對外放開一個方法加載圖片
public voidsetImageData(int[] image){? //這里我傳的參數是一個數組,因為我把圖片放到資源文件里了,實際中我們傳的會是一個集合或bean里面有圖片的地址
if(image.length==0){//如果數組的長度為0則證明,沒有圖片,實際中可能是集合沒有圖片寬高為0
itemW=0;itemH=0;? ? }e
lse if(image.length==1){//處理圖片大小不能過界
if(getImgaeWidth(this.image[0])==0|| getImgaeHeight(this.image[0])==0){ //因為我的圖片在res里所以我不知道寬和高,因此我創建了兩個方法獲得寬高,實際中集合的bean里應該已經包含寬和高了
itemW=(width-(imColumn+1)*space)/imColumn;
itemH=(width-(imColumn+1)*space)/imColumn;? ? ? ? }
else{
float scaleWidth=(float) getImgaeWidth(this.image[0])/maxwidth;
float scaleHeight=(float) getImgaeHeight(this.image[0])/maxheight;
if(scaleHeight<1&& scaleWidth<1) {itemW=getImgaeWidth(this.image[0])-space*2;
itemH=getImgaeHeight(this.image[0])-space*2;? ? ? ? ? ? }
else{
itemW= (int) (getImgaeWidth(this.image[0])/(scaleHeight>scaleWidth?scaleHeight:scaleWidth))-space*2;
itemH= (int) (getImgaeHeight(this.image[0])/(scaleHeight>scaleWidth?scaleHeight:scaleWidth))-space*2;? ? ? ? ? ? }? ? ? ? }? ? }
else{
itemW=(width-(imColumn+1)*space)/imColumn;itemH=(width-(imColumn+1)*space)/imColumn;? ? }//設置視圖寬高
if(image.length==0) {? ? ? ? setLayoutParams(newLinearLayout.LayoutParams(0,0));? ? }else if(image.length==1) {? ? ? ? LinearLayout.LayoutParams params=newLinearLayout.LayoutParams(itemW,itemH);? ? ? ? params.leftMargin= CommonUtils.dp2px(context,45);? ? ? ? params.topMargin=CommonUtils.dp2px(context,10);? ? ? ? setLayoutParams(params);? ? }else{//總行數introw=(image.length-1)/imColumn+1;//最大列數intcolumn=0;if(imColumn> image.length) {? ? ? ? ? ? column= image.length;? ? ? ? }else{? ? ? ? ? ? column=imColumn;? ? ? ? }//通過每個item的寬高計算出layout整體寬高? 這里要注意因為這里new的是linearLayout所以使用時布局一定要是linearlayout,否則會報錯LinearLayout.LayoutParams params=newLinearLayout.LayoutParams(space*(column+1)+column*itemW,space*(row+1)+row*itemH);? ? ? ? params.leftMargin= CommonUtils.dp2px(context,45);? ? ? ? params.topMargin=CommonUtils.dp2px(context,10);? ? ? ? setLayoutParams(params);? ? }//添加視圖
if(image.length!=0) {//從來沒有創建過
if(oldNum==0) { //oldnum是判斷是否復用過
for(inti : image) { ? ? ? ? ? ? ??
ImageView imageView =newImageView(context);//這里我用的是imageview,實際中可以用自己的加載圖片的方法以實現各種效果如背景默認加載什么的? ? ? ? ? ? ? ?
?addView(imageView);? ? ? ? ? ? }? ? ? ? }
else{//新創建的比之前的要少,則減去多余的部分
if(oldNum> image.length) {? ? ? ? ? ? ??
? removeViews(image.length-1,oldNum-this.image.length);? ? ? ? ? ? }//新創建的比之前的要少,則添加缺少的部分
else if(oldNum< image.length) {
for(inti =0; i < image.length-oldNum; i++) {? ? ? ? ? ?
?? ? ? ? ImageView imageView =newImageView(context);? ? ? ? ? ? ? ? ??
? addView(imageView);? ? ? ? ? ? ??
? }? ? ? ? ? ? }? ? ? ? }
oldNum= image.length;? ? }
else{? ? ? ? removeAllViews();oldNum=0;? ? }//設置每一個圖片的寬高
for(inti =0; i < getChildCount(); i++) {
final inti_=i;? ? ? ? ImageView imageView= (ImageView) getChildAt(i);? ? ? imageView.setImageResource(image[i]);? ? ? ? imageView.setOnClickListener(newOnClickListener() {@Override
public voidonClick(View v) {if(listener!=null) {listener.click(i_);? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? });
introw=i/imColumn+1;intcolumn=i%imColumn+1;intleft=space*column +itemW*(column-1);
inttop=space*row +itemH*(row-1);intright=left+itemW;intbottom=top+itemH;? ? ? ? imageView.layout(left, top, right, bottom);? ? }
}
//獲取寬和高的方法
private intgetImgaeWidth(intid){? ? Bitmap bitmap = BitmapFactory.decodeResource(this.getContext().getResources(), id);intwidth = bitmap.getWidth();returnwidth;}
private intgetImgaeHeight(intid){? ? Bitmap bitmap = BitmapFactory.decodeResource(this.getContext().getResources(), id);intheight = bitmap.getWidth();returnheight;}
以上就是自定義的所有方法了剩下的就剩在布局中使用了