Android自定义控件(一)
来源:互联网 发布:大数据架构师是什么 编辑:程序博客网 时间:2024/06/07 09:34
出处:http://www.cnblogs.com/0616--ataozhijia/p/4003380.html
http://blog.csdn.net/lmj623565791/article/details/24252901/
开发自定义控件的步骤
1、了解View工作原理
2、编写继承自view的子类
3、为自定义View增加属性
4、绘制控件
5、响应用户消息
6、自定义回调函数
一、view结构原理
view作为所有图形的基类,ViewGroup对view继承扩展为视图容器类。
View定义了绘图的基本操作
基本操作用三个函数完成 measure(),layout(),draw()、其内部又包含了onMeasure(),onLayout(),onDraw(),三个方法,具体操作如下:
1、measure操作
measure操作主要用于计算视图的大小,即视图的宽度和长度,在View中定义为final类型,要求子类不能修改,measure又会调用一下函数
(1)onMeasure(),视图大小将在这里最终确定,也就是说measure只是对onMeasure的包装,子类复写onMeasure()方法实现自己 计算视图大小的方式,
并通过serMeasureDimension(width,height)保存计算结果
2、layout操作
layout操作用于设置视图在屏幕中显示的位置,在View中定义为final类型,要求子类不能修改。layout函数中有两个基本操作
(1)setFrame(l,t,r,b)参数即父视图的具体坐标位置,该函数用于将这些参数保存起来。
(2)onLayout 在view中这个函数什么都不会做,提供该函数主要是为了viewGroup类型布局子视图用的。
3、draw操作
draw操作利用前两步得到的参数,将视图显示在屏幕上,在这里将完成整个视图绘制工作,子类也不应该修改该方法,因为其内部定义了绘图的基本操作。
(1)绘制背景
(2)如果视图显示渐变框,这里会做一些准备工作
(3)绘制视图本身,即调用onDraw()方法、在View中OnDraw是个空函数,也就是说具体悳视图都要复写该函数来实现自己的显示,(比如textView在这里实现绘制文字的过程)。对于ViewGroup则不需要实现该函数,因为容器是没有内容的,其包含了多个ziView,而子view已经实现了自己的绘制方法,因此只需要告诉子View绘制自己就可以了,也就是下面的dispatchDraw()方法。
(4)绘制子视图,即dispatchDraw()方法,在View中这是个空函数,具体视图不需要实现该方法,他是专门为容器类准备的,也就是容器类必须实现的方法。
(5)如果需要(应用程序调用了serVervicalFadingEdge或者setHorizontalFadingEdge),开始绘制渐变框
(6)绘制滚动条
从上面可以看书自定义View最少复写onMeasure()和onDraw()两个方法
二、View类的构造方法
创建自定义控件的三种主要实现方式,
1)继承已有的控件实现自定义控件,主要是当腰实现和已有的控件很多方面比较类似,通过对已有控件的扩展来满足要求
2)通过继承一个布局文件实现自定义控件,一般来书做组合控件时可以通过这个方式来实现
3)通过继承view;来实现自定义控件,使用GDI绘制出组件界面,一般无法通过上述两种方式来实现时用该方法。
三、自定义View增加属性的两种方法
1)在View类中定义,通过构造函数引入的AttributeSet去查找XML布局的属性名称,然后找到它对应引用的资源Id找值
public class MyView extends View{ private String mText; private int mSrcId; public MyView(Context context) { super(context); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); /** * textId即 R.string.aaa * mSrcId即R.drawable.daodaogou * Src="@drawable/daodaogou" * 所以此处没多少意义,熟悉下AttributeSet用法 */ int textId = attrs.getAttributeResourceValue(null, "Text", 0); mSrcId = attrs.getAttributeResourceValue(null, "Src", 0); mText = context.getResources().getText(textId).toString(); } @Override protected void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setTextSize(60); paint.setColor(Color.RED); InputStream inputStream = getResources().openRawResource(mSrcId); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); int width = bitmap.getWidth(); int height = bitmap.getHeight(); canvas.drawBitmap(bitmap,0,0,paint); canvas.drawText(mText,60,60,paint); }}
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.example.myimageview2.MyView android:id="@+id/myView1" android:layout_width="wrap_content" android:layout_height="wrap_content" Text="@string/hello_world" Src="@drawable/xh"/></LinearLayout>
2)通过Text、Src在自定义View类的构造方法获取
public class MyImageView extends LinearLayout { public MyImageView(Context context) { super(context); } public MyImageView(Context context, AttributeSet attrs) { super(context, attrs); int resourceId = -1; TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyImageView); ImageView iv = new ImageView(context); TextView tv = new TextView(context); int N = typedArray.getIndexCount(); for (int i = 0; i < N; i++) { int attr = typedArray.getIndex(i); switch (attr) { case R.styleable.MyImageView_Oriental: resourceId = typedArray.getInt( R.styleable.MyImageView_Oriental, 0); this.setOrientation(resourceId == 1 ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL); break; case R.styleable.MyImageView_Text: resourceId = typedArray.getResourceId( R.styleable.MyImageView_Text, 0); tv.setText(resourceId > 0 ? typedArray.getResources().getText( resourceId) : typedArray .getString(R.styleable.MyImageView_Text)); break; case R.styleable.MyImageView_Src: resourceId = typedArray.getResourceId( R.styleable.MyImageView_Src, 0); iv.setImageResource(resourceId > 0 ?resourceId:R.drawable.ic_launcher); break; } } addView(iv); addView(tv); typedArray.recycle(); }}
attrs.xml进行属性声明,文件放在values目录下
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="MyImageView"> <attr name="Text" format="reference|string"></attr> <attr name="Oriental" > <enum name="Horizontal" value="1"></enum> <enum name="Vertical" value="0"></enum> </attr> <attr name="Src" format="reference|integer"></attr> </declare-styleable></resources>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:uview="http://schemas.android.com/apk/res/com.example.myimageview2" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <com.example.myimageview2.MyImageView android:id="@+id/myImageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" uview:Text="这是一个图片说明" uview:Src="@drawable/tw" uview:Oriental="Vertical"> </com.example.myimageview2.MyImageView></LinearLayout>
六、自定义View的方法
源码:点击打开链接:http://download.csdn.net/detail/gangjindianzi/9560849
- Android自定义控件(一)
- Android自定义控件(一)
- Android 自定义控件(一)
- Android自定义控件(一)
- Android 自定义控件(一)
- android自定义控件(一)
- android自定义控件(一)
- Android自定义控件(一)
- 自定义控件(一)【Android】
- android自定义控件(一)
- Android自定义控件(一)
- Android 自定义控件(一)
- Android自定义控件之自定义组合控件(一)
- Android自定义控件(一) 自定义组合控件
- Android自定义控件(一) 自定义组合控件
- Android自定义控件(一) 自定义组合控件
- Android 自定义控件开发入门(一)
- Android 自定义控件开发入门(一)
- Linux相关
- Linux内核线程
- swiper的基础使用(九)
- git常用命令指导2
- Eclipse中Server视图加载项目之后项目名后边有带括号的名字
- Android自定义控件(一)
- Go语言学习笔记1
- 递归调用(一)
- 谷雪梅 Google中国
- CentOS 7 sytemctl 自定义服务开机启动
- HDU 4968 (贪心)
- 忘记ubuntu 14.04密码怎么办?
- QTableWidget 详细使用
- the type java.util.Map$Entry cannnot be resolved 解决办法