android中 自定义了一个MyView(继承自View类) 在xml布局文件中作为组件添加(无错误提示)但运行后报错

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android中 自定义了一个MyView(继承自View类) 在xml布局文件中作为组件添加(无错误提示)但运行后报错相关的知识,希望对你有一定的参考价值。

参考技术A 1、自定义view需要注意
构造函数
,所有的xml布局,初始化时构造函数使用的都是 (Context context, AttributeSet attrs) 两个参数的。如果没有该构造函数会报错。
2、如果有自定义属性,则需要在当前xml中引入工程包名,否则自定义属性会报错
这个问题报错的愿意是第一个,构造函数使用错误。增加构造函数就能解决问题。
比如:
public class MyView extends View//下面2个构造函数都加上
public MyView(Context context)

public MyView(Context context, AttributeSet attrs)
super(context, attrs);

Android 自定义View

    这篇文章以简单的方式说明怎么去自定义View至于源码的分析,在后面总结再写吧。 

    Android 自定义View的流程:

  1.      View的测量;
  2.      View的绘制;

    如果子类想要自定义测量过程,则子类需要重写onMeasure方法。如下我们写一个MyView类继承View:

public class MyView extends View{
    
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }

    可以看到onMeasure接受两个参数 widthMeasureSpec,heightMeasureSpec ,显然这就是View的width和height。widthMeasureSpec,heightMeasureSpec是一个32位的整形值,其中高2位为测量模式SpecMode,低30位表示某种测量模式下的规格大小SpecSize。后缀MeasureSpec是View类的一个静态内部类,用来说明应该如何测量这个View。

测量模式分为三种:

  1. UNSPECIFIED:不指定测量模式,父视图没有限制我们自定义View的大小,View可以是想要的任何尺寸。
  2. EXACTLY:精确测量模式,当我们自定义的View的layout_width或者layout_heigth指定为具体数值或者match_parent时生效。(指定为match_parent时为父视图的大小)
  3. AT_MOST:最大值模式,当我们自定义的View的layout_width或者layout_heigth指定为warp_content时生效,此时自定义的View可以是不超过父视图允许的最大尺寸的任何尺寸。

 

    我们如何获得测量模式和测量大小呢?

//获取测量模式
int specMode = MeasureSpec.getMode(measureSpec);
//获取测量大小
int specSize = MeasureSpec.getSize(measureSpec);

    View类默认的onMeasure()方法只支持EXACTLY模式,如果你不重写该方法,引入控件时属性设置为wrap_content,是不会生效的,而是自动采用match_parent。   

    onMeasure()方法中,我们可以通过setMeasureDimension(int width,int height)传入我们想要的宽和高,如果我们自定义View时不重写该方法,则默认会直接调用getDefaultSize()来获得View的宽和高。。

   下面我们看一个简单的实例:

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View{
    
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
        //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(measure(widthMeasureSpec),measure(heightMeasureSpec));
    }
    
    /**
     * 完全自己自定义的方法哦,你甚至可以让不管设置什么都返回固定大小!
     * @param measureSpec 传入的measureSpec
     * @return 处理后的大小
     */
    private int measure(int measureSpec){
        int result = 0;
        //分别获取测量模式 和 测量大小
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        
        //如果是精确度模式,呢就按xml中定义的来
        if(specMode == MeasureSpec.EXACTLY){
            result = specSize;
        }
        //如果是最大值模式,就按我们定义的来
        else if(specMode == MeasureSpec.AT_MOST){
            result = 200;
        }
        
        return result;
    }
}

    在XML中引用MyView

<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="com.example.app.MainActivity" >

    <com.example.app.MyView
        android:layout_width="400px"
        android:layout_height="wrap_content"
        android:background="#ff0000"
        />

</RelativeLayout>

 


以上是关于android中 自定义了一个MyView(继承自View类) 在xml布局文件中作为组件添加(无错误提示)但运行后报错的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio开发基础之自定义View组件

进阶篇-用户界面:5.android绘图api自定义View(视图)

android 自定义View

自定义View——入门继承View的实例

Swift、iboutlet 和自定义控件

自定义View的封装