Android 自定义View
来源:互联网 发布:上虞淘宝培训学校 编辑:程序博客网 时间:2024/05/16 14:05
先总结下自定义View的步骤:
1、自定义View的属性
2、在View的构造方法中获得我们自定义的属性
[ 3、重写onMesure ]
4、重写onDraw
我把3用[]标出了,所以说3不一定是必须的,当然了大部分情况下还是需要重写的。
1、自定义View的属性,首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。
我们定义了字体,字体颜色,字体大小3个属性,format是值该属性的取值类型:
一共有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;不清楚的可以google一把。
然后在布局中声明我们的自定义View
一定要引入 xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"我们的命名空间,后面的包路径指的是项目的package
也可以用http://schemas.android.com/apk/res/res-auto
2、在View的构造方法中,获得我们的自定义的样式
我们重写了3个构造方法,默认的布局文件调用的是两个参数的构造方法,所以记得让所有的构造调用我们的三个参数的构造,我们在三个参数的构造中获得自定义属性。
3、我们重写onDraw,onMesure调用系统提供的:
注意:drawText()表示text在所对应的xy的右下角。基本画东西在所在的点,往右下角开始画
添加设置属性事件
在xml中指定的自定义属性只有在view被初始化的时候能够获取到,有时候我们可能在运行时做一些操作,这种情况就需要我们为自定义属性设置getter和setter方法,以下代码展示了自定义控件暴露的set 和get方法
public boolean getTitleText() { return mTitleText ;}public void setTitleText(boolean mTitleText ) { mTitleText = mTitleText ; invalidate(); requestLayout();}
重点看setTitleText方法,在为mTitlleText赋值之后,调用了invalidate()和requestLayout()方法,我们自定义控件的属性发生改变之后,控件的样子也可能发生改变,在这种情况下就需要调用invalidate()方法让系统去调用view的onDraw()重新绘制。同样的,控件属性的改变可能导致控件所占的大小和形状发生改变,所以我们需要调用requestLayout()来请求测量获取一个新的布局位置。
处理View的布局.
测量
一个View是在展示时总是有它的宽和高,测量View就是为了能够让自定义的控件能够根据各种不同的情况以合适的宽高去展示。提到测量就必须要提到onMeasure方法了。onMeasure方法是一个view确定它的宽高的地方。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { }
onMeasure方法里有两个重要的参数, widthMeasureSpec, heightMeasureSpec。
在这里你只需要记住它们包含了两个信息:mode和size
注:当我们设置为WRAP_CONTENT,或者MATCH_PARENT系统帮我们测量的结果就是MATCH_PARENT的长度。
重写之前先了解MeasureSpec的specMode,一共三种类型:
EXACTLY:一般是设置了明确的值或者是MATCH_PARENT
AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT
UNSPECIFIED:表示子布局想要多大就多大,很少使用
下面是我们重写onMeasure代码:
计算一些自定义控件需要的值 onSizeChange()
onSizeChange() 方法在view第一次被指定了大小值、或者view的大小发生改变时会被调用。所以一般用来计算一些位置和与view的size有关的值。
3、绘制View(Draw)
一旦自定义控件被创建并且测量代码写好之后,接下来你就可以实现onDraw()来绘制View了,onDraw方法包含了一个Canvas叫做画布的参数,onDraw()简单来说就两点:
Canvas决定要去画什么
Paint决定怎么画
比如,Canvas提供了画线方法,Paint就来决定线的颜色。Canvas提供了画矩形,Paint又可以决定让矩形是空心还是实心。
在onDraw方法中开始绘制之前,你应该让画笔Paint对象的信息初始化完毕。这是因为View的重新绘制是比较频繁的,这就可能多次调用onDraw,所以初始化的代码不应该放在onDraw方法里。
4、与用户进行交互
在android系统中最常见的事件就是触摸事件了,它会调用view的onTouchEvent(android.view.MotionEvent).重写这个方法去处理我们的事件逻辑
@Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); }
对与onTouchEvent方法相信大家都有一定了解,如果不了解的话,你就先记住这是处理Touch的地方。
现在的触控有了更多的手势,比如轻点,快速滑动等等,所以在支持特殊用户交互的时候你需要用到android提供的GestureDetector.你只需要实现GestureDetector中相对应的接口,并且处理相应的回调方法。
除了手势之外,如果有移动之类的情况我们还需要让滑动的动画显示得比较平滑。动画应该是平滑的开始和结束,而不是突然消失突然开始。在这种情况下,我们需要用到属性动画 property animation framework
由于与用户进行交互中涉及到的知识举例子会比较多,所以我在之后的自定义控件文章中再讲解。
总结
到这里基本上自定义控件的大致步骤和可能涉及到的知识点都说完了。看一张图。
ScrollView子View为自定义View时需要注意的几点问题:
方法一:mScrollView.setFillViewport(true); 本方法是使子View可以拉伸来填满整个屏幕
方法二:在自定义View类中MobileView(class MobileView extends View)重写onMeasure方法
调用setMeasuredDimension(GlobalFun.BWScreenWidth, GlobalFun.BWScreenHeight);来设置本View的宽和高,这样就会显示。注意宽度和高度必须大于设备的宽和高,此时才会滚动。重写onMeasure方法的有以下几个步骤:
1、获得控件宽度(width)的MODE值
2、根据MODE值获得width的大小
3、获得控件高度(height)的MODE值
4、根据MODE值获得height的大小
5、设置控件大小
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
很多人在重写onMeasure的时候,容易忽略MODE=MeasureSpec.UNSPECIFIED这个值,而忽略给width和height市值值了,以致控件在放置Scrollview和HorizontalScrollView控件的时候,自定义View就无法显示了,出现这个的原因是,自定义View的控件值一直是0,所以自定义View的大小是0,就理所当然的消失了。
计算出当前绘制出来的字符串有多宽,可以这么来!
方法1:Paint pFont = new Paint();
Rect rect = new Rect();
//返回包围整个字符串的最小的一个Rect区域
pFont.getTextBounds(str, 0, 1, rect);
strwid = rect.width();
strhei = rect.height();
方法2:
//直接返回参数字符串所占用的宽度
strwid = paintHead.measureText(str);
//最新获取文字基准高度public float getnewTextheight(Paint mPaint) { Paint.FontMetrics fontMetrics = mPaint.getFontMetrics(); float fontHeight = fontMetrics.bottom - fontMetrics.top; float baseY = fontHeight / 2 - fontMetrics.bottom; return baseY;}//获取文字的高public float getTxtHeight(Paint mPaint) { Paint.FontMetrics fm = mPaint.getFontMetrics(); return (float) Math.ceil(fm.descent - fm.ascent);}
- Android View---自定义View
- Android View---自定义View
- Android 自定义View 之 自定义View属性
- 【自定义View系列】android自定义View概述
- Android自定义view自定义属性
- Android自定义控件 -- 自定义View
- android自定义view(自定义数字键盘)
- Android自定义View-自定义属性
- Android自定义View-自定义属性
- Android 自定义View
- Android 自定义 View
- android自定义View
- Android 中自定义 view
- android 自定义view组件
- Android 自定义 View
- android 自定义view
- Android:如何自定义View
- android 自定义View
- vim 跳转指定行
- 智能交通工程质量的第三方监测
- Redis的安装(linux)
- 集成学习之参数调整策略
- 拓扑排序--九度1448
- Android 自定义View
- iOS GCD使用详解
- java学习笔记————本质篇3
- Oracle多线程并行使用、关联与指定索引执行
- 问题记录 170228 viewpager同时显示前后,即同时显示三张图
- eclipse创建maven工程报错 Could not resolve archetype org.apache.maven.archetypes-webapp-1.0......
- 用python的turtle画炫酷的图
- Unity编程标准导引-3.3 Transform
- 你,我等候了好久的人