Android-自定義View(一)

介紹:

一般在做界面時使用控件就分兩類,一種是android自帶的控件,另一種就是自定義View。

自定義背景圖

(1)繼承View,重寫相關方法

package com.example.customview;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
/**
 * 自定義View
 *
 */
public class custonView extends View{
    //在佈局文件中使用,構造方法必須是兩個參數(上下文,屬性)
    public custonView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    //重寫onDraw()方法
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
    }


}

(2)將背景圖加載成Bitmap

package com.example.customview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
/**
 * 自定義View
 *
 */
public class custonView extends View{

    Bitmap bitmapBackground;


    //在佈局文件中使用,構造方法必須是兩個參數(上下文,屬性)
    public custonView(Context context, AttributeSet attrs) {
        super(context, attrs);
        bitmapBackground=BitmapFactory.decodeResource(getResources(), R.drawable.background);
    }

    //重寫onDraw()方法
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
    }

}

(3)在控件上畫背景圖

/**
 * 自定義View
 *
 */
public class custonView extends View{

    Bitmap bitmapBackground;


    //在佈局文件中使用,構造方法必須是兩個參數(上下文,屬性)
    public custonView(Context context, AttributeSet attrs) {
        super(context, attrs);
        bitmapBackground=BitmapFactory.decodeResource(getResources(), R.drawable.background);
    }

    //重寫onDraw()方法
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        Paint paint=new Paint();//畫筆
        canvas.drawBitmap(bitmapBackground, 0, 0,paint);//畫布    
    }

}

(4)佈局中使用自定義背景圖

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <com.example.customview.custonView 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

</RelativeLayout>

(5)運行查看效果

這裏寫圖片描述

由於圖片大小原因,圖片在屏幕的左上方,如果想要將圖片將整個屏幕鋪滿,需要自己做計算。
例如想知道圖片向右需要幾個將橫向填滿,n=控件的寬度/圖片的寬度

(6)水平平鋪

package com.example.customview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
 * 自定義View
 *
 */
public class custonView extends View{

    Bitmap bitmapBackground;

    //控件的寬度和高度
    int viewWith,viewHeight;


    //在佈局文件中使用,構造方法必須是兩個參數(上下文,屬性)
    public custonView(Context context, AttributeSet attrs) {
        super(context, attrs);
        bitmapBackground=BitmapFactory.decodeResource(getResources(), R.drawable.background);
    }

    //重寫onDraw()方法
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        Paint paint=new Paint();//畫筆
        //行數
        for(int row=0;row<viewHeight/b;){

        }
        //列數
        for(int col=0;
        col<viewWith/bitmapBackground.getWidth()+1;col++){
                                                //列*圖片的寬度
            canvas.drawBitmap(bitmapBackground, col*bitmapBackground.getWidth(), 0,paint);//畫布  

        }


    }

    //此方法用來圖片平鋪
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // TODO Auto-generated method stub
        super.onSizeChanged(w, h, oldw, oldh);
        viewHeight=h;
        viewWith=w;


    }


}

(7)垂直平鋪

package com.example.customview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
 * 自定義View
 *
 */
public class custonView extends View{

    Bitmap bitmapBackground;

    //控件的寬度和高度
    int viewWith,viewHeight;


    //在佈局文件中使用,構造方法必須是兩個參數(上下文,屬性)
    public custonView(Context context, AttributeSet attrs) {
        super(context, attrs);
        bitmapBackground=BitmapFactory.decodeResource(getResources(), R.drawable.background);
    }

    //重寫onDraw()方法
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        Paint paint=new Paint();//畫筆
        //行數
        for(int row=0;row<viewHeight/bitmapBackground.getHeight()+1;row++){ 
            //列數
            for(int col=0;col<viewWith/bitmapBackground.getWidth();col++){
                                                //列*圖片的寬度
            canvas.drawBitmap(bitmapBackground, col*bitmapBackground.getWidth(), 
                    //行*圖片的高度
                    row*bitmapBackground.getHeight(),paint);//畫布    

            }
        }
    }

    //此方法用來圖片平鋪
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // TODO Auto-generated method stub
        super.onSizeChanged(w, h, oldw, oldh);
        viewHeight=h;
        viewWith=w;


    }
}

在背景圖上畫Logo,Logo居中

package com.example.customview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
 * 自定義View
 *
 */
public class custonView extends View{

    Bitmap bitmapBackground;//背景圖
    Bitmap logo;//圖標Logo

    //控件的寬度和高度
    int viewWith,viewHeight;


    //在佈局文件中使用,構造方法必須是兩個參數(上下文,屬性)
    public custonView(Context context, AttributeSet attrs) {
        super(context, attrs);
        bitmapBackground=BitmapFactory.decodeResource(getResources(), R.drawable.background);
        logo=BitmapFactory.decodeResource(getResources(), R.drawable.loading_logo);
    }

    //重寫onDraw()方法
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        Paint paint=new Paint();//畫筆
        //行數
        for(int row=0;row<viewHeight/bitmapBackground.getHeight()+1;row++){ 
            //列數
            for(int col=0;col<viewWith/bitmapBackground.getWidth();col++){
                                                //列*圖片的寬度
            canvas.drawBitmap(bitmapBackground, col*bitmapBackground.getWidth(), 
                    //行*圖片的高度
                    row*bitmapBackground.getHeight(),paint);//畫布    

            }
        }

        //畫Log,並計算Logo的座標
        //(控件的寬度-logo的寬度)/2
        int logLeft=(viewWith-logo.getWidth())/2;//log的左間距
        int logTop=(viewHeight-logo.getHeight())/2;//log的上漸漸
        canvas.drawBitmap(logo, logLeft, logTop,paint);

    }

    //此方法用來圖片平鋪
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // TODO Auto-generated method stub
        super.onSizeChanged(w, h, oldw, oldh);
        viewHeight=h;
        viewWith=w;
    }
}

效果圖:
這裏寫圖片描述

Logo下方水平居中放置圖片:


/**
 * 自定義view
 * 
 * @author tarena
 * 
 */
public class CustomView extends View {
    Bitmap bitmapBackground,logo,progressBar;
    int viewWidth, viewHeight;


    //在佈局文件中使用,必須使用兩個參數(上下文,屬性)
    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        bitmapBackground = BitmapFactory.decodeResource(getResources(),
                R.drawable.background);//將背景圖轉成Bitmap
        logo = BitmapFactory.decodeResource(getResources(),
                R.drawable.loading_logo);
        progressBar = BitmapFactory.decodeResource(getResources(),
                R.drawable.loading_progressbar);
    }

    //重寫方法,重新畫背景圖
    @Override
    protected void onDraw(Canvas canvas) {
        Paint paint = new Paint();
        for (int row = 0; row < viewHeight / bitmapBackground.getHeight() + 1; row++) {
            for (int col = 0; col < viewWidth / bitmapBackground.getWidth() + 1; col++) {
                canvas.drawBitmap(bitmapBackground,
                        col * bitmapBackground.getWidth(), row
                                * bitmapBackground.getHeight(), paint);
            }
        }

        int logoLeft=(viewWidth-logo.getWidth())/2;
        int logoTop=(viewHeight-logo.getHeight())/2;
        canvas.drawBitmap(logo, logoLeft, logoTop, paint);

        int progressLeft=(viewWidth-progressBar.getWidth())/2;
        int progressTop=logoTop+logo.getHeight()+10;
        canvas.drawBitmap(progressBar, progressLeft, progressTop, paint);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // TODO Auto-generated method stub
        super.onSizeChanged(w, h, oldw, oldh);
        viewHeight = h;
        viewWidth = w;
    }
}

效果圖

這裏寫圖片描述

結合動畫:

上方出現動畫,從右跑並變換圖片(結合線程),並單擊動畫出現文字(onTouchEvent):

package com.tarena.customview1504_01;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * 自定義view
 * 
 * @author tarena
 * 
 */
public class CustomView extends View {
    Bitmap pig, flower, bitmapBackground, logo, progressBar;
    int viewWidth, viewHeight;
    Thread thread;
    boolean isRunning = true;
    int pigX, pigY = 100;//動畫初始值 從右邊跑
    int count;
    boolean isDrawString = false;

    // 在佈局文件中使用
    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        bitmapBackground = BitmapFactory.decodeResource(getResources(),
                R.drawable.background);
        logo = BitmapFactory.decodeResource(getResources(),
                R.drawable.loading_logo);
        progressBar = BitmapFactory.decodeResource(getResources(),
                R.drawable.loading_progressbar);
        pig = BitmapFactory.decodeResource(getResources(), R.drawable.f007);
        flower = BitmapFactory.decodeResource(getResources(), R.drawable.f008);

        MyThread myThread = new MyThread();
        thread = new Thread(myThread);
        thread.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Paint paint = new Paint();
        for (int row = 0; row < viewHeight / bitmapBackground.getHeight() + 1; row++) {
            for (int col = 0; col < viewWidth / bitmapBackground.getWidth() + 1; col++) {
                canvas.drawBitmap(bitmapBackground,
                        col * bitmapBackground.getWidth(), row
                                * bitmapBackground.getHeight(), paint);
            }
        }

        int logoLeft = (viewWidth - logo.getWidth()) / 2;
        int logoTop = (viewHeight - logo.getHeight()) / 2;
        canvas.drawBitmap(logo, logoLeft, logoTop, paint);

        int progressLeft = (viewWidth - progressBar.getWidth()) / 2;
        int progressTop = logoTop + logo.getHeight() + 10;
        canvas.drawBitmap(progressBar, progressLeft, progressTop, paint);
        // 擴展1:現在顯示2幅圖,擴展成顯示3幅畫
        // /擴展2:走到左邊,向右移,再向左移
        if (count % 2 == 0) {
            canvas.drawBitmap(pig, pigX, pigY, paint);
        } else {
            canvas.drawBitmap(flower, pigX, pigY, paint);
        }
        count++;

        paint.setTextSize(48);
        paint.setColor(0xFFFF0000);
        if (isDrawString) {
            canvas.drawText("這是花", pigX, pigY + 48, paint);
        }
    }
    //繼承View單擊觸發的方法
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        int x = (int) event.getX();//單擊得到x點的座標
        int y = (int) event.getY();//點擊得到y點的座標 
        //點擊動畫
        if (x > pigX && x < pigX + pig.getWidth() && y > pigY
                && y < pigY + pig.getHeight()) {
            isDrawString = true;//在屏幕上畫東西
        } else {
            isDrawString = false;
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // TODO Auto-generated method stub
        super.onSizeChanged(w, h, oldw, oldh);
        viewHeight = h;
        viewWidth = w;
        pigX = w;
    }

    class MyThread implements Runnable {

        @Override
        public void run() {
            while (isRunning) {
                try {
                    pigX = pigX - 30;
                    // 在工作線程中調用onDraw更新界面用的是postInvalidate()
                    // 在主線程中調用onDraw更新界面用的是invalidate()

                    postInvalidate();
                    Thread.currentThread().sleep(3000);
                } catch (Exception e) {
                    // ExceptionUtil.handleException(e);
                }
            }

        }

    }
}

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章