介紹:
一般在做界面時使用控件就分兩類,一種是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);
}
}
}
}
}