自定义view(一)
来源:互联网 发布:600756 浪潮软件 编辑:程序博客网 时间:2024/05/20 18:00
- 首先需要我们知道android的控件架构:
每一个activity都包含一个window对象,也就是phonewindow,phonewinodw把DecorView当做根视图,也就是顶层视图,所有view的监听事件,都通过WindowMannagerServer来进行接收的,并且通过activity对象来回调响应的onClickListener。那个title也就是平时的actionbar,ContentView就是我们天天都要接触的部分了。这也就解释了为什么要在setContentView前设置requestWindowFeature(Window.FEATURE_requestWindowFeature())在调用setContent方法前调用。 - view的测量
测量都是在onMeasure()方法中进行,需要用到MeasureSpec类,通过这个类我们可以拿到具体的测量模式和测量到的测量值。其中MeasureSpec是一个32位的int值,其中高2位位测量的模式,低30位是测量的大小。
测量模式
- EXACTLY
精确模式,就是当我们制定控件的layout_width和layout_height属性为具体值时,android:layout_width=”200dp”, 同时也要注意了,如果是android:layout_width=“match_parent”时也是使用的该模式 - AT_MOST
这个可能就是用的最多的。最大值测量模式,在viewgroup的时候可能用的都是这个吧。当控件的layout_width和layout——height属性指定为wrap_content时,控件大小一般随着控件的子控件或者内容的变化而变化,此时控件的尺寸只要不超过父控件允许 的最大值即可 - UNSPECIFIED
这个其实也不太懂,通常情况下载绘制自定义view时候使用
- EXACTLY
view类默认的onMeasure()使用的方法只支持EXACTIY模式,所以在自定义的时候记得重写onMeasure()方法。不然控件只能响应具体的宽高和match_parent属性,没办法wrap_content。
演示代码
** * 描述:自定义view初步练习 ,自定义view最主要的就是 测量跟绘制, * 作者:Marc on 2016/5/27 09:07 * */public class TechView extends View { public TechView(Context context) { super(context); } public TechView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //这里使用自定义的方法进行测量。 setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeigth(heightMeasureSpec)); } /** * 自定义方法,对宽进行重新定义 * * @param heightMeasureSpec 该对象中包含测量的模式和测量值的大小 * @return */ private int measureHeigth(int heightMeasureSpec) { int result = 0; int specMode = MeasureSpec.getMode(heightMeasureSpec);//拿到测量模式 int specSize = MeasureSpec.getSize(heightMeasureSpec);//拿到测量大小 //通过判断测量的模式,给出不同的测量值 if (specMode == MeasureSpec.EXACTLY) { //如果是精确值模式,就直接使用指定的specSize即可 result = specSize; } else { //如果不是精确值,是其他的2种模式 result = 200; if (specMode == MeasureSpec.AT_MOST) { // 尤其是AT_MOST 模式,也就是给定的是wrap_content属性,需要给一个默认值大小与测量出来的specSize中最小的那个 result = Math.min(result, specSize); } } return result; } /** * 测量宽度的方法 * * @param widthMeasureSpec 该对象中包含测量的模式和测量值的大小 * @return */ private int measureWidth(int widthMeasureSpec) { int result = 0; int specMode = MeasureSpec.getMode(widthMeasureSpec);//拿到宽度的测量模式 int specSize = MeasureSpec.getSize(widthMeasureSpec);//拿到宽度的测量值的大小 //通过判断测量模式给出测量值 if (specMode == MeasureSpec.EXACTLY) { //如果是精确测量模式,那就直接给定测量出的值 result = specSize; } else { //如果是其他2种测量模式,就给个默认值 result = 200; if (specMode == MeasureSpec.AT_MOST) { //如果是AT_MOST模式也就是给定的是wrap_content模式,需要把result设置成默认值跟测量值中小的那个 result = Math.min(result, specSize); } } return result; } /** * 自定义view中绘制 * * @param canvas */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED);//会成红色,这样子明显 int width = getWidth(); int height = getHeight(); Log.d("marc", "width ==" + width + ";height==" + height); }- 结果```java 在布局中,如果指定具体宽高值,就是采用具体的。 指定match_parent就是充满父窗体 wrap_content属性时,如果不重写onMeasure()方法,系统不知道使用多大尺寸,就会默认填满父窗体。
0 0
- 自定义View(一)
- 自定义view(一)
- 自定义View(一)
- 自定义View(一)
- 自定义View(一)
- 自定义View(一)
- 自定义view(一)
- 自定义View(一)
- 自定义View(一)
- 自定义View(一)
- 自定义View(一)
- 自定义View(一)
- 自定义View(一)
- 自定义View(一)
- 自定义View(一) 初识自定义view
- Android 自定义View(一)
- android-自定义View(一)
- android 自定义view(一)
- HTML 学习 (一)
- C++纯虚函数
- Mac OS X Git安装教程
- 提供一个对话框供用户选择一个文件夹路径。
- Android中ListView数据使用sAdapter.notifyDataSetChanged();方法不刷新的问题
- 自定义view(一)
- linux 中 kill() 与 signal() 函数
- win7 右键卡死
- [Maven实战]发布maven项目到中央仓库(Central Repository)
- EJB 是怎样通过Resteasy进行验证的
- session和cookie机制
- 自定义简单的Toast,可自行修改文字、图片、样式
- 获取当前运行应用信息的几种方法
- 变量的显示:echo