栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

Android开发之自定义View

Java 更新时间:发布时间: 百科书网 趣学号

目录

一、View的简介

1.1 View的构造函数

1.2 View的绘制流程图

二、自定义View

2.1 onMeasure()方法

2.2 OnDraw()方法


一、View的简介

View类是Android中各种组件的基类,如View是ViewGroup基类,表现为显示在屏幕上的各种视图。Android中的UI组件都是由View和ViewGroup组成。

1.1 View的构造函数
    //如果View在Java代码中是new出来的,就会调用第一个构造函数
    public View(Context context) {
        throw new RuntimeException("Stub!");
    }

    //如果View是在.xml里面声明的就会调用第二个构造函数
    public View(Context context, @Nullable AttributeSet attrs) {
        throw new RuntimeException("Stub!");
    }
    
    
    public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        throw new RuntimeException("Stub!");
    }

    public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int         defStyleRes) {
        throw new RuntimeException("Stub!");
    }

AttributeSet与自定义属性:系统自带的View可以在xml中配置属性,对于已经写好的自定义的View同样可以在xml中配置属性,为了使自定义View的属性可以在xml中配置,需要一下四个步骤:

  1. 通过为自定义View添加属性
  2. 在xml中为相应的属性生命属性值
  3. 在运行时获取属性值
  4. 将获取的属性值应用到View

1.2 View的绘制流程图

二、自定义View

自定义View的最基本的方法是:

onMeasure():测量,决定View的大小;

onLayout():布局,决定View在ViewGroup中的位置

onDraw():绘制,决定绘制这个View;

2.1 onMeasure()方法
 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
...
}

首先看一下onMeasure函数的两个参数,widthMeasureSpec和heightMeasureSpec。这两个int型的数据包含了测量模式和尺寸。

//获取测量模式        
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
//获取尺寸
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);

什么是测量模式呢?测量模式有三种,分别是UNSPECIFIED/ EXCATLY/ AT_MOST。

测量模式表示意思
UNSPECIFIED父容器没有对当前View有任何限制,当前View可以任意取尺寸
EXACTLY当前的尺寸就是当前View应该取的尺寸
AT_MOST当前尺寸是当前View能取的最大尺寸

现在重写一个onMeasure函数,实现一个自定义的正方形View。

//继承View
public class SquareView extends View {

    //1.只有Context的构造函数
    public SquareView(Context context) {
        super(context);
    }

    //2.含有Context和AttributeSet的构造函数
    public SquareView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    //3.重写onMesure方法
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = getMySize(100,widthMeasureSpec);
        int height = getMySize(100,heightMeasureSpec);

        if (width 



    

    
    
    

运行效果:

        Tips:在自定义View的时候,需要两个构造函数。否则在编译的时候会报异常:Binary XML file line Error inflating class. 原因是:Android在根据xml文件夹创建View对象的时候会调用View的双参构造方法,即public SquareView(Context context, AttributeSetattrs),所以如果没有写全的话就会报错。

2.2 OnDraw()方法

在onMeasure方法中实现了自定义尺寸大小,在onDraw方法中实现了自定义的绘制View。接下来做一个自定义的圆形View。

  @Override
    protected void onDraw(Canvas canvas) {
        //调用父类的onDraw函数,因为View这个类实现了一些基本的绘制功能,比如绘制背景颜色和背景图片
        super.onDraw(canvas);
        //半径
        int r = getMeasuredWidth()/2;
        //以圆心的横坐标为当前View的左起始位置+半径
        int centerX = getLeft() + r;
        //以圆心的横坐标为当前View的顶部起始位置+半径
        int centerY = getTop() + r;
        Paint paint = new Paint();
        paint.setColor(Color.YELLOW);
        canvas.drawCircle(centerX,centerY,r,paint);
    }
 

运行效果:

 2.3 自定义布局属性

首先需要在res/values/styles.xml文件声明一个自定义属性:


    
    
        
        
    

布局文件:




    

Tips: 使用自定义属性需要在根标签添加命名空间,命名空间的取值是

"http://schemas.android.com/apk/res-auto"

修改构造函数,读取自定义属性的值:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

public class CycloView extends View {

    private int defaultSize;
    public CycloView(Context context) {
        super(context);
    }

    public CycloView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        //获取属性集合
        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.CycloView);
        //获取default_size属性
        defaultSize = typedArray.getDimensionPixelSize(R.styleable.CycloView_default_size,100);
        //将TypedArray回收
        typedArray.recycle();
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = getMySize(defaultSize,widthMeasureSpec);
        int height = getMySize(defaultSize,heightMeasureSpec);

        if (width 

参考文档:

自定义View(一) - 简书 (jianshu.com)

(3条消息) 自定义View,有这一篇就够了_走召大爷的博客-CSDN博客_自定义view

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/957225.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号