Android-自定义View(一)

22 篇文章 0 订阅

介绍:

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

        }

    }
}

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值