自定义视图(继承View)_移动开发_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > 移动开发 > 自定义视图(继承View)

自定义视图(继承View)

 2014/9/19 10:39:10  江湖郎中.luoaz  程序员俱乐部  我要评论(0)
  • 摘要:前言Android提供了丰富的控件,但是有时候还是不能满足自己的需求,这时候就需要自定义视图了,自定义视图分为几种,一种为继承为View的,一种为继承于ViewGroup的。继承于View的需要我们自己去绘制控件,继承于ViewGroup的可以组织已有的控件,下面就先介绍下继承于View的情况。效果图下面就是自定义了一个简单的圆形图来介绍整个的绘制过程,如下所示概述绘制一个控件需要绘制两部分内容,一是尺寸,二是内容,这通过两个方法来进行绘制,一个是onMeasure、一个是onDraw
  • 标签:view 继承 自定义

前言

  Android提供了丰富的控件,但是有时候还是不能满足自己的需求,这时候就需要自定义视图了,自定义视图分为几种,一种为继承为View的,一种为继承于ViewGroup的。继承于View的需要我们自己去绘制控件,继承于ViewGroup的可以组织已有的控件,下面就先介绍下继承于View的情况。

效果图

  下面就是自定义了一个简单的圆形图来介绍整个的绘制过程,如下所示

  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ljXl2EOqWcN9qfc5zX/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,整体结构如下所示

  

 1 public class CustomView extends View {
 2
 3     public CustomView(Context context, AttributeSet attrs) {
 4         super(context, attrs);
 5     }
 6     //绘制内容
 7     @Override
 8     protected void onDraw(Canvas canvas) {
 9         super.onDraw(canvas);
10     }
11     //计算尺寸大小
12     @Override
13     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
14         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
15     }
16
17 }

 

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

  

 1 public class CustomView extends View {
 2
 3     int height=0,width=0;
 4     private int cx;    //圆心x
 5     private int cy;    //圆心y
 6     private int padding=5;    //控件边距
 7     
 8     public CustomView(Context context, AttributeSet attrs) {
 9         super(context, attrs);
10     }
11     @Override
12     protected void onDraw(Canvas canvas) {
13         super.onDraw(canvas);
14         //计算圆心位置、半径
15         cx = width/2;
16         cy = height/2;
17         int radius = cx>cy?cy:cx;
18         
19         Paint paint = new Paint();
20         paint.setColor(Color.RED);
21         canvas.drawCircle(cx, cy, radius, paint);
22         canvas.drawColor(Color.GRAY);
23     }
24     //计算尺寸大小
25     @Override
26     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
27         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
28         
29         widthMeasureSpec = MeasureSpec.getSize(widthMeasureSpec);
30         heightMeasureSpec = MeasureSpec.getSize(heightMeasureSpec);
31         //计算宽度
32         int mode = MeasureSpec.getMode(widthMeasureSpec);
33         if(mode==MeasureSpec.EXACTLY){
34             width = widthMeasureSpec + padding;
35         }else{
36             width = widthMeasureSpec;
37         }
38         
39         //计算高度
40         mode = MeasureSpec.getMode(heightMeasureSpec);
41         if(mode==MeasureSpec.EXACTLY){
42             height = heightMeasureSpec + padding;
43         }else{
44             height = heightMeasureSpec;
45         }
46         setMeasuredDimension(width, height);
47     }
48
49 }

  布局文件

  

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:paddingBottom="@dimen/activity_vertical_margin"
 6     android:paddingLeft="@dimen/activity_horizontal_margin"
 7     android:paddingRight="@dimen/activity_horizontal_margin"
 8     android:paddingTop="@dimen/activity_vertical_margin"
 9     tools:context=".MainActivity"
10     
11     >
12
13     <com.example.customview.CustomView
14         android:id="@+id/customView1"
15         android:layout_width="50dip"
16         android:layout_height="50dip"
17         android:layout_alignParentLeft="true"        
18         android:layout_alignParentTop="true"
19         />
20
21 </RelativeLayout>

 

后记

  这篇文章主要是说了下绘制的一个整体过程,实现的功能比较简单,但是再复杂的内容其原理是相同的,通过这个过程可以发挥想象力来绘制控件,关于通过组合控件来进行绘制的情况再下篇文章中进行叙述。

 原文地址:http://www.cnblogs.com/luoaz/p/3980651.html

  

 

发表评论
用户名: 匿名