安卓自定义View介绍使用
来源:互联网 发布:远程教育软件哪家好 编辑:程序博客网 时间:2024/05/22 10:53
1.自定义View介绍:
自定义View我们大部分时候只需重写两个函数:onMeasure()、onDraw()。onMeasure负责对当前View的尺寸进行测量,onDraw负责把当前这个View绘制出来。当然了,你还得写至少写2个构造函数:
public MyView(Context context) { super(context); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); }
关于onMeasure,我们为什么需要测量?
我们平时写view的大小无非三种情况:而是wrap_content或者是match_parent或者指定大小,那么自定义view为什么还需要来测量宽高呢,我们知道将尺寸设置为“包住内容”和“填充父布局给我们的所有空间”,但是这两个设置并没有指定真正的大小,可是我们绘制到屏幕上的View必须是要有具体的宽高的,正是因为这个原因,我们必须自己去处理和设置尺寸。当然了,View类给了默认的处理,但是如果View类的默认处理不满足我们的要求,我们就得重写onMeasure函数啦~。这里举个例子,比如我们希望我们的View是个正方形,如果在xml中指定宽高为wrap_content,如果使用View类提供的measure处理方式,显然无法满足我们的需求。
我们重写的onMeasure()函数是:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
我们可以通过:
int widthMode = MeasureSpec.getMode(widthMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);
取得我们需要的测量模式和大小。
其中测量模式有三种:
测量模式 ——————– 表示意思
UNSPECIFIED ————-父容器没有对当前View有任何限制,当前View可以任意取尺寸
EXACTLY————— 当前的尺寸就是当前View应该取的尺寸
AT_MOST————— 当前尺寸是当前View能取的最大尺寸
而上面的测量模式跟我们的布局时的wrap_content、match_parent以及写成固定的尺寸有什么对应关系呢?
match_parent—>EXACTLY。怎么理解呢?match_parent就是要利用父View给我们提供的所有剩余空间,而父View剩余空间是确定的,也就是这个测量模式的整数里面存放的尺寸。
wrap_content—>AT_MOST。怎么理解:就是我们想要将大小设置为包裹我们的view内容,那么尺寸大小就是父View给我们作为参考的尺寸,只要不超过这个尺寸就可以啦,具体尺寸就根据我们的需求去设定。
固定尺寸(如100dp)—>EXACTLY。用户自己指定了尺寸大小,我们就不用再去干涉了,当然是以指定的大小为主啦。
1. 感受一下onMeasure的使用,假设我们要实现这样一个效果:将当前的View以正方形的形式显示,即要宽高相等,并且默认的宽高值为100像素。就可以这些编写:
private int getMySize(int defaultSize, int measureSpec) { int mySize = defaultSize; int mode = MeasureSpec.getMode(measureSpec); int size = MeasureSpec.getSize(measureSpec); switch (mode) { case MeasureSpec.UNSPECIFIED: {//如果没有指定大小,就设置为默认大小 mySize = defaultSize; break; } case MeasureSpec.AT_MOST: {//如果测量模式是最大取值为size //我们将大小取最大值,你也可以取其他值 mySize = size; break; } case MeasureSpec.EXACTLY: {//如果是固定的大小,那就不要去改变它 mySize = size; break; } } return mySize;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = getMySize(100, widthMeasureSpec); int height = getMySize(100, heightMeasureSpec); if (width < height) { height = width; } else { width = height; } setMeasuredDimension(width, height);}
我们设置一下布局
<com.hc.studyview.MyView android:layout_width="match_parent" android:layout_height="100dp" android:background="#ff0000" />
看看使用了我们自己定义的onMeasure函数后的效果:
自定义View
而如果我们不重写onMeasure,效果则是如下:
2. 重写onDraw开始画图
我们要View显示一个圆形,由于我们在上面已经实现了宽高尺寸相等,下面就简单了:
@Override protected void onDraw(Canvas canvas) { //调用父View的onDraw函数,因为View这个类帮我们实现了一些 // 基本的而绘制功能,比如绘制背景颜色、背景图片等 super.onDraw(canvas); int r = getMeasuredWidth() / 2;//也可以是getMeasuredHeight()/2,本例中我们已经将宽高设置相等了 //圆心的横坐标为当前的View的左边起始位置+半径 int centerX = getLeft() + r; //圆心的纵坐标为当前的View的顶部起始位置+半径 int centerY = getTop() + r; Paint paint = new Paint(); paint.setColor(Color.GREEN); //开始绘制 canvas.drawCircle(centerX, centerY, r, paint); }
3. 使用自定义布局属性
可以在布局文件中由用户写属性,
自定义View的属性,首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。
<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="titleText" format="string" /> <attr name="titleTextColor" format="color" /> <attr name="titleTextSize" format="dimension" /> <declare-styleable name="CustomTitleView"> <attr name="titleText" /> <attr name="titleTextColor" /> <attr name="titleTextSize" /> </declare-styleable> </resources>
或者这样写:
<resources> <declare-styleable name="CustomTitleView"> <attr name="titleText" format="string" /> <attr name="titleTextColor" format="color" /> <attr name="titleTextSize" format="dimension" /> </declare-styleable> </resources>
第一种写法可以提供共用属性的,当自定义view多时,很有用的。
我们定义了字体,字体颜色,字体大小3个属性,format是值该属性的取值类型:一共有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;不清楚的可以google一把。
然后在布局中声明我们的自定义View
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.customview01.view.CustomTitleView android:layout_width="200dp" android:layout_height="100dp" custom:titleText="3712" custom:titleTextColor="#ff0000" custom:titleTextSize="40sp" /> </RelativeLayout>
一定要引入
xmlns:custom=”http://schemas.android.com/apk/res/com.example.customview01”
我们的命名空间,后面的包路径指的是项目的package
然后在View的构造方法中,获得我们的自定义的样式
/** * 文本 */ private String mTitleText; /** * 文本的颜色 */ private int mTitleTextColor; /** * 文本的大小 */ private int mTitleTextSize; /** * 绘制时控制文本绘制的范围 */ private Rect mBound; private Paint mPaint; public CustomTitleView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CustomTitleView(Context context) { this(context, null); } /** * 获得我自定义的样式属性 * * @param context * @param attrs * @param defStyle */ public CustomTitleView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); /** * 获得我们所定义的自定义样式属性 */ TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.CustomTitleView_titleText: mTitleText = a.getString(attr); break; case R.styleable.CustomTitleView_titleTextColor: // 默认颜色设置为黑色 mTitleTextColor = a.getColor(attr, Color.BLACK); break; case R.styleable.CustomTitleView_titleTextSize: // 默认设置为16sp,TypeValue也可以把sp转化为px mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics())); break; } } a.recycle(); /** * 获得绘制文本的宽和高 */ mPaint = new Paint(); mPaint.setTextSize(mTitleTextSize); // mPaint.setColor(mTitleTextColor); mBound = new Rect(); mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound); }
我们重写了3个构造方法,默认的布局文件调用的是两个参数的构造方法,所以记得让所有的构造调用我们的三个参数的构造,我们在三个参数的构造中获得自定义属性。
更多高级用法参考:http://blog.csdn.net/huachao1001/article/details/51577291
–>路要一步一步走,记住自己走过的路,不再犯同样的错误,才是真正的成长!欢迎指点、交流。<–
- 安卓自定义View介绍使用
- 安卓自定义View
- 安卓自定义view
- 安卓自定义View
- 安卓自定义View
- 安卓自定义view
- 安卓自定义View组件
- 安卓常用自定义View
- 安卓开发自定义View
- 安卓自定义View详解
- 安卓自定义View教程
- 安卓自定义View网址
- 安卓自定义View进阶
- 安卓自定义View进阶
- 安卓自定义分页view
- 安卓开发:使用selector自定义View样式
- 安卓自定义View之贝塞尔曲线简单使用
- 安卓开发28:自定义View类
- State与Transition之Transition
- 面试中被问到的概率题
- 错误pycurl.error: (60, 'SSL certificate problem: unable to get local issuer certificate')解决方案
- Spark之TopN
- NYOJ1237_最大岛屿
- 安卓自定义View介绍使用
- Spring+junit4 实现注解测试原理解析
- Windows 服务状态在启动或停止时卡住的解决办法
- 移动端吸顶、动画、浏览器层模型以及相关总结
- Myeclips导出war错误
- fmdb实现sqlite数据库的增删改查功能(下)
- 京东——分堆
- Spark之BroadCast
- MySQL中varchar 的最大长度