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的流程:
- View的测量;
- 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。
测量模式分为三种:
- UNSPECIFIED:不指定测量模式,父视图没有限制我们自定义View的大小,View可以是想要的任何尺寸。
- EXACTLY:精确测量模式,当我们自定义的View的layout_width或者layout_heigth指定为具体数值或者match_parent时生效。(指定为match_parent时为父视图的大小)
- 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布局文件中作为组件添加(无错误提示)但运行后报错的主要内容,如果未能解决你的问题,请参考以下文章