自定义视图(继承View)
前言
Android提供了丰富的控件,但是有时候还是不能满足自己的需求,这时候就需要自定义视图了,自定义视图分为几种,一种为继承为View的,一种为继承于ViewGroup的。继承于View的需要我们自己去绘制控件,继承于ViewGroup的可以组织已有的控件,下面就先介绍下继承于View的情况。
效果图
下面就是自定义了一个简单的圆形图来介绍整个的绘制过程,如下所示
aaarticlea/png;base64,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y0ZQb+GjKS2rwrzy5pR+8URNKue1dmef2B8VpF7GxrRR1PvJBCu6tKwL88r+8JAzrf1PT4oLurigb33Eyxi7fiOo13ungxUdfDHFz+cvw3Be6+KiDlZMadE4r6mXsbFsNL+N3XmjvVljXl2EOqWcN9qfc5zX/DI6xsY1/hUyxqSOehmTOuplTOqolzGpo17GpI56GZM66mVM6qiXMambeAJAJuoFpJpofm0yxiRuIgEg00Sapulpev6/jLGHtqttXjQ7YX8fGmNM3Cbyszw/yzMAEvRrzc/y83oZY+I2kZ8N/KOdg/8N4KE5G/jfPJ+4vxsC4E6oF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpblZv+Uv5AW5Mdw3wwFEvINXfrjefmBga9QK3M/Z6r+Z6/agX+ENjrPem3d664THdNcADN5Z679LtLQIe010DPHCjr3ck6d6o4THdNcADN+J6R5vuHwY8prsGeOBGVu84uv3Dhsd01wAP3GjqHXe61wc8prsGeOCoF5BqBPX+nXSvCXhMdw3wwN213r+Z7q8CHtNdAzxwd6r376dLvUCfvHqvBjymuwZ44G5f732lezXgMd01wANHvYBUt6z3ftMdCnhMdw3wwFEvIBX1AlJRLyAV9QJS3abee+92KOAx3TXAA0e9gFTUC0hFvYBU1AtIRb2AVHzHCJCKegGpqBeQinoBqagXkIqfzgekol5AKn4rHSCVvHqHbgP14tHit7EDUvEvoQBS8a+QAVJRLyAV//o2INXI6h1fw7+/UuBRGnG9Iw/4j64ReJRGX++oAv7D66JePFpjqffuDd/sioBHaYz13q7h21wF8CiNvd7fxjyCywQepb9d7zg2prsGeOCoF5DqZvUCeDioF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6AamoF5CKegGpqBeQinoBqagXkIp6Aan+A3BrsqnlXz9RAAAAAElFTkSuQmCC" alt="" />
概述
绘制一个控件需要绘制两部分内容,一是尺寸,二是内容,这通过两个方法来进行绘制,一个是onMeasure、一个是onDraw,整体结构如下所示
public class CustomView extends View { public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
//绘制内容
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
//计算尺寸大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} }
onMeasure
这个函数用来计算控件的大小尺寸,尺寸这个地方有一个概念为绘制模式
MeasureSpec.AT_MOST:父元素指定控件最大达到的尺寸,通过设定为wrap_content为此模式
MeasureSpec.EXACTLY:父元素指定控件精确的大小,比如设置为100dip,或者match_parent为此模式
MeasureSpec.UNSPECIFIED:父元素不控制控件的大小,其大小完全由内部控制
这个模式,可以通过int mode = MeasureSpec.getMode(widthMeasureSpec);方法来获取模式。
等计算好大小后,通过setMeasuredDimension(width, height);方法来设置宽高
onDraw
这个函数用来绘制控件的内容,这个函数传入了一个Canvas对象,这个是当前的Canvas对象,把需要绘制的内容绘制到这个Canvas上即可,可以通过Canvas中的drawCircle、drawLine、drawText等方法来绘制内容,如果需要设定笔线内容,通过paint对象来设定
源码
Java
public class CustomView extends View { int height=0,width=0;
private int cx; //圆心x
private int cy; //圆心y
private int padding=5; //控件边距 public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//计算圆心位置、半径
cx = width/2;
cy = height/2;
int radius = cx>cy?cy:cx; Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawCircle(cx, cy, radius, paint);
canvas.drawColor(Color.GRAY);
}
//计算尺寸大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); widthMeasureSpec = MeasureSpec.getSize(widthMeasureSpec);
heightMeasureSpec = MeasureSpec.getSize(heightMeasureSpec);
//计算宽度
int mode = MeasureSpec.getMode(widthMeasureSpec);
if(mode==MeasureSpec.EXACTLY){
width = widthMeasureSpec + padding;
}else{
width = widthMeasureSpec;
} //计算高度
mode = MeasureSpec.getMode(heightMeasureSpec);
if(mode==MeasureSpec.EXACTLY){
height = heightMeasureSpec + padding;
}else{
height = heightMeasureSpec;
}
setMeasuredDimension(width, height);
} }
布局文件
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > <com.example.customview.CustomView
android:id="@+id/customView1"
android:layout_width="50dip"
android:layout_height="50dip"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
/> </RelativeLayout>
后记
这篇文章主要是说了下绘制的一个整体过程,实现的功能比较简单,但是再复杂的内容其原理是相同的,通过这个过程可以发挥想象力来绘制控件,关于通过组合控件来进行绘制的情况再下篇文章中进行叙述。
原文地址:http://www.cnblogs.com/luoaz/p/3980651.html
自定义视图(继承View)的更多相关文章
- 自定义控件(视图)2期笔记10:自定义视图之View事件分发机制("瀑布流"的案例)
1. Touch事件的传递: 图解Touch事件的传递,如下: 当我们点击子View 02内部的Button控件时候,我们就触发了Touch事件. • 这个Touch事件首先传递给了顶级父View ...
- 自定义控件(视图)2期笔记14:自定义视图之View事件分发 dispatchTouchEvent,onTouch,onTouchEvent,onClick逻辑顺序过程
1. 这里我们先从案例角度说明dispatchTouchEvent,onTouch,onTouchEvent,onClick逻辑顺序过程: (1)首先我们重写一个MyButton 继承自 Button ...
- UI 自定义视图 ,视图管理器
一>自定义label - textField 视图 自定义视图:系统标准UI之外,自己组合而出的新的视图 iOS 提供了很多UI组件 ,借助它们,我们可以做各种程序 尽管如此,实际开发中,我们还 ...
- SpringMVC(二七) 自定义视图
可以参考博客http://www.cnblogs.com/parryyang/p/5683600.html,举例很清晰. 对自定义的视图名称匹配不同的解析器进行解析. 作用:自己定义视图,视图继承vi ...
- 自定义View 一 (继承VIew重写onDraw方法)
项目:具有圆形效果的自定义View 一.继承View并重写onDraw方法 public class CircleView extends View{ private static final int ...
- Android中的自定义视图控件
简介 当现有控件不能满足需求时,就需要自定义控件. 自定义控件属性 自定义控件首先要继承自View,重写两个构造函数. 第一个是代码中使用的: public MyRect(Context contex ...
- 自定义视图引擎,实现MVC主题快速切换
一个网站的主题包括布局,色调,内容展示等,每种主题在某些方面应该或多或少不一样的,否则就不能称之为不同的主题了.每一个网站至少都有一个主题,我这里称之为默认主题,也就是我们平常开发设计网站时的一个固定 ...
- (翻译)为你的MVC应用程序创建自定义视图引擎
Creating your own MVC View Engine For MVC Application 原文链接:http://www.codeproject.com/Articles/29429 ...
- 自定义视图一:扩展现有的视图,添加新的XML属性
这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! 简介 这个系列详细的介绍了如何穿件Android自定义视图.主要涉及的内容有如何绘制内容,layout和measure的原理,如何继承 ...
随机推荐
- JavaScript 之 执行前台函数
1.OnClientClick (vs2003不支持这个方法) <asp:Button ID="Button" runat="server" Text=& ...
- C语言第六节基本运算符
算术运算 C语言一共有34种运算符,包括了常见的加减乘除运算 加法运算+ 除开能做加法运算,还能表示正号:+5.+90 减法运算- 除开能做减法运算,还能表示符号:-10.-29 乘法运算* 注意符号 ...
- Handler发送消息
Handler发送消息小结 字数283 阅读210 评论0 喜欢1 obtainMessage()得到一个Message对象. 创建一个Message然后发送是这么写的: Message msg = ...
- MVC3+Linq to sql 显示数据库中数据表的数据
1:首先创建asp.net mvc3应用程序 2:创建项目完成后 找到controllers文件鼠标右击选择添加控制器 3 为models文件夹添加一个linq to sql类文件,然后把数据库中的数 ...
- Android(java)学习笔记66:实现Runnable接口创建线程 和 使用Callable和Future创建线程
1. 前面说的线程的实现是新写一个子类继承Thread: 是将类声明为 Thread 的子类.该子类应重写 Thread 类的 run 方法.接下来可以分配并启动该子类的实例 2. 这里说的方案2是指 ...
- react-redux-react-router直通车
简单说明 这篇文章是我学习react一个多月来的总结,从基础开始(包括编辑器设置,构建工具搭建),一步一步走向react开发.相信我,看完这篇文章,跟着文章的步骤走,保证让你入门react并爱上rea ...
- Jboss中不能正常的解析EL表达式
在写好EL表达是后发现在页面原封不动的现实成了${user.name}没有解析出来,我还以为那里出了问题,原来只要在页面添加上<%@ page isELIgnored="false&q ...
- html行内元素和块元素标签分组
转载 address - 地址blockquote - 块引用center - 举中对齐块dir - 目录列表div - 常用块级容易,也是CSS layout的主要标签dl - 定义列表fields ...
- CSS之侧边栏
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- ubuntu安装 ibus-google输入法
1.$sudo apt-get install ibus-googlepinyin //ibus 融合了许多种输入法,google便是一种,此步就是下载安装ibus-google拼音输入法. ...