介绍:
一般在做界面时使用控件就分两类,一种是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);
}
}
}
}
}