Android自定义view(初级篇)

Q1:为什么要自定义view?
A:由于很多系统自带的view满足不了当前设计需求或者为了达到更良好的用户体验,增加UI的美化效果,就需要自定view
Q2:自定义view有那几个步骤?
A:>用户可根据需要extends View这个父类,然后重写父类的方法;如:onDraw();onMeasure()等;
  >如果用户在自定义View事需要添加属性,则必须在values文件夹下新建"attrs.xml"文件,在其中添加自定义属性。
 下面来进行自定义view的学习。

一、最基本的自定义view;例如:新建一个类CustomEditText 继承EditText
其特点:拥有EditText的全部方法,就和EditText一模一样,只是名字不同了而已。
使用方法有两种:
>在代码中调用,CustomEditText cet=new CustomEditText(context);
>在xml中调用,需要写全包名及类名,否则会报The following classes could not be found;
关键代码如下:
自定义view:
public class CustomEditText extends EditText {

	public CustomEditText(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public CustomEditText(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}

}
xml中使用:
<! -- com.anqiansong.views为CustomEditText所在位置的包名-->
<com.anqiansong.views.CustomEditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="自定义EditText" />

二、在上面的CustomEditText中重写onDraw()方法实现删除线text效果;
@Override
protected void onDraw(Canvas canvas) {
	// TODO Auto-generated method stub
	super.onDraw(canvas);
	Paint paint=new Paint();//新建画笔对象
	paint.setColor(Color.BLACK);//设置画笔颜色
	paint.setAntiAlias(true);//设置是否抗锯齿
	paint.setStrokeWidth(2);//设置画笔的粗细
	//设置线条的x轴方向的起始点,y轴方向的起始点
	canvas.drawLine(this.getLeft(), (this.getBottom()-this.getTop())/2, this.getRight(), (this.getBottom()-this.getTop())/2, paint);
}

三、比如我们现在在xml中使用时添加一个lineColor属性(删除线的颜色),该怎么实现呢?
>首先需要在values下新建attrs.xml文件;
>然后根据需要添加相应的属性及属性所属类型
>使用
关键代码:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--declare-styleable:声明样式类型;attr name=""声明属性名;format="属性的类型"  -->
    <declare-styleable name="CustomEditText">
        <attr name="lineColor" format="color" />
    </declare-styleable>

</resources>
备注:format的属性值见*附录一
在xml中调用:
以下代码必须声明,否则找不到之前定义的属性名,则不能用,可以声明在根布局中,也可以在调用时声明
xmlns:CustomEditText="http://schemas.android.com/apk/res/com.anqiansong.androidcustomview"(如果没有声明,在引用属性时系统也会提示然后根据提示自动生成将是已xmlns:app=.....这种模式)
说明:xmlns:***="http://schemas.android.com/apk/res/packagename"
***主要是在调用时需要,如android:textColor="#ffffff";这里的“android”
方式1中的CustomEditText:lineColor="#ff0000"的CustomEditText,方式2中的mylinecolor
而packagename则为当前工程包名
如果这两个不是这种格式,则也引用不了自定义的属性
此外,既然在xml中设置的lineColor的值,在自定义view中的构造方法中就要去获取这个属性的颜色值;如代码:
public class CustomEditText extends EditText {
	private int lineColor;//删除线颜色全局变量
	public CustomEditText(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public CustomEditText(Context context, AttributeSet attrs) {
		super(context, attrs);
		Paint paint=new Paint();
		TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CustomEditText);
		lineColor=array.getColor(R.styleable.CustomEditText_lineColor, Color.BLACK);//获取xml中设置的删除线的颜色值,这里的CustomEditText_lineColor是由attrs中的styleable中的名字和属性名加"_"组合而成
		array.recycle();
	}

	public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		Paint paint=new Paint();//新建画笔对象
		paint.setColor(lineColor);//设置画笔颜色
		paint.setAntiAlias(true);//设置是否抗锯齿
		paint.setStrokeWidth(2);//设置画笔的粗细
		//设置线条的x轴方向的起始点,y轴方向的起始点
		canvas.drawLine(this.getLeft(), (this.getBottom()-this.getTop())/2, this.getRight(), (this.getBottom()-this.getTop())/2, paint);
	}
}

方式1:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:CustomEditText="http://schemas.android.com/apk/res/com.anqiansong.androidcustomview"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.anqiansong.views.CustomEditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="自定义EditText"
        CustomEditText:lineColor="#ff0000"
        />
</RelativeLayout>

方式2:
<com.anqiansong.views.CustomEditText
        xmlns:mylinecolor="http://schemas.android.com/apk/res/com.anqiansong.androidcustomview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="自定义EditText"
        mylinecolor:lineColor="#ff0000"
        />
同样的原理,我们可以对删除线的粗细添加一个属性lineHeight,代码如下:
添加属性:<attr name="lineHeight" format="dimension"/>
引用属性:mylinecolor:lineHeight="5dp"
自定义view中获取lineHeight并设置粗细:lineHeight=array.getDimension(R.styleable.CustomEditText_lineHeight, 2);在ondraw()方法中paint.setStrokeWidth(lineHeight);//设置画笔的粗细

附录一:
附:Android中自定义属性的格式详解(引自:http://www.cnblogs.com/zhangs1986/p/3243040.html,作者:欢醉,请尊重原创)
1. reference:参考某一资源ID。
    (1)属性定义:
            <declare-styleable name = "名称">
                   <attr name = "background" format = "reference" />
            </declare-styleable>
    (2)属性使用:
             <ImageView
                     android:layout_width = "42dip"
                     android:layout_height = "42dip"
                     android:background = "@drawable/图片ID"
                     />
2. color:颜色值。
    (1)属性定义:
            <declare-styleable name = "名称">
                   <attr name = "textColor" format = "color" />
            </declare-styleable>
    (2)属性使用:
            <TextView
                     android:layout_width = "42dip"
                     android:layout_height = "42dip"
                     android:textColor = "#00FF00"
                     />
3. boolean:布尔值。
    (1)属性定义:
            <declare-styleable name = "名称">
                   <attr name = "focusable" format = "boolean" />
            </declare-styleable>
    (2)属性使用:
            <Button
                    android:layout_width = "42dip"
                    android:layout_height = "42dip"
                    android:focusable = "true"
                    />
4. dimension:尺寸值。
    (1)属性定义:
            <declare-styleable name = "名称">
                   <attr name = "layout_width" format = "dimension" />
            </declare-styleable>
    (2)属性使用:
            <Button
                    android:layout_width = "42dip"
                    android:layout_height = "42dip"
                    />
5. float:浮点值。
    (1)属性定义:
            <declare-styleable name = "AlphaAnimation">
                   <attr name = "fromAlpha" format = "float" />
                   <attr name = "toAlpha" format = "float" />
            </declare-styleable>
    (2)属性使用:
            <alpha
                   android:fromAlpha = "1.0"
                   android:toAlpha = "0.7"
                   />
6. integer:整型值。
    (1)属性定义:
            <declare-styleable name = "AnimatedRotateDrawable">
                   <attr name = "visible" />
                   <attr name = "frameDuration" format="integer" />
                   <attr name = "framesCount" format="integer" />
                   <attr name = "pivotX" />
                   <attr name = "pivotY" />
                   <attr name = "drawable" />
            </declare-styleable>
    (2)属性使用:
            <animated-rotate
                   xmlns:android = "http://schemas.android.com/apk/res/android"
                   android:drawable = "@drawable/图片ID"
                   android:pivotX = "50%"
                   android:pivotY = "50%"
                   android:framesCount = "12"
                   android:frameDuration = "100"
                   />
7. string:字符串。
    (1)属性定义:
            <declare-styleable name = "MapView">
                   <attr name = "apiKey" format = "string" />
            </declare-styleable>
    (2)属性使用:
            <com.google.android.maps.MapView
                    android:layout_width = "fill_parent"
                    android:layout_height = "fill_parent"
                    android:apiKey = "0jOkQ80oD1JL9C6HAja99uGXCRiS2CGjKO_bc_g"
                    />
8. fraction:百分数。
    (1)属性定义:
            <declare-styleable name="RotateDrawable">
                   <attr name = "visible" />
                   <attr name = "fromDegrees" format = "float" />
                   <attr name = "toDegrees" format = "float" />
                   <attr name = "pivotX" format = "fraction" />
                   <attr name = "pivotY" format = "fraction" />
                   <attr name = "drawable" />
            </declare-styleable>
    (2)属性使用:
            <rotate  xmlns:android = "http://schemas.android.com/apk/res/android"
               android:interpolator = "@anim/动画ID"
                 android:fromDegrees = "0"
               android:toDegrees = "360"
                 android:pivotX = "200%"
                 android:pivotY = "300%"
               android:duration = "5000"
                 android:repeatMode = "restart"
                 android:repeatCount = "infinite"
                   />
9. enum:枚举值。
    (1)属性定义:
            <declare-styleable name="名称">
                   <attr name="orientation">
                          <enum name="horizontal" value="0" />
                          <enum name="vertical" value="1" />
                   </attr>
            </declare-styleable>
    (2)属性使用:
            <LinearLayout
                    xmlns:android = "http://schemas.android.com/apk/res/android"
                    android:orientation = "vertical"
                    android:layout_width = "fill_parent"
                    android:layout_height = "fill_parent"
                    >
            </LinearLayout>
10. flag:位或运算。
     (1)属性定义:
             <declare-styleable name="名称">
                    <attr name="windowSoftInputMode">
                            <flag name = "stateUnspecified" value = "0" />
                            <flag name = "stateUnchanged" value = "1" />
                            <flag name = "stateHidden" value = "2" />
                            <flag name = "stateAlwaysHidden" value = "3" />
                            <flag name = "stateVisible" value = "4" />
                            <flag name = "stateAlwaysVisible" value = "5" />
                            <flag name = "adjustUnspecified" value = "0x00" />
                            <flag name = "adjustResize" value = "0x10" />
                            <flag name = "adjustPan" value = "0x20" />
                            <flag name = "adjustNothing" value = "0x30" />
                     </attr>
             </declare-styleable>
     (2)属性使用:
            <activity
                   android:name = ".StyleAndThemeActivity"
                   android:label = "@string/app_name"
                   android:windowSoftInputMode = "stateUnspecified | stateUnchanged | stateHidden">
                   <intent-filter>
                          <action android:name = "android.intent.action.MAIN" />
                          <category android:name = "android.intent.category.LAUNCHER" />
                   </intent-filter>

             </activity>
     注意:
     属性定义时可以指定多种类型值。
    (1)属性定义:
            <declare-styleable name = "名称">
                   <attr name = "background" format = "reference|color" />
            </declare-styleable>
    (2)属性使用:
             <ImageView
                     android:layout_width = "42dip"
                     android:layout_height = "42dip"
                     android:background = "@drawable/图片ID|#00FF00"
                     />

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 03:30:50

Android自定义view(初级篇)的相关文章

【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象

前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五)Android事件分发机制(上)Touch三个重要方法的处理逻辑][下文简称(五),请先阅读完(五)再阅读本文],我们通过示例和log来分析了Android的事件分发机制.这些,我们只是看到了现象,如果要进一步了解事件分发机制,这是不够的,我们还需要透过现象看本质,去研究研究源码.本文将从源码(基

【朝花夕拾】Android自定义View篇之(八)多点触控(上)基础知识

前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/11155259.html],谢谢! 在前面的文章中,介绍了不少触摸相关的知识,但都是基于单点触控的,即一次只用一根手指.但是在实际使用App中,常常是多根手指同时操作,这就需要用到多点触控相关的知识了.多点触控是在Android2.0开始引入的,在现在使用的Android手机上都是支持多点触控的.本系列文章将对常见的多点触控相关的重点知识进行总结,并使用多点触控来实现一些常见的效果,从而达到将

Android自定义View——圆形进度条式按钮

介绍 今天上班的时候有个哥们问我怎么去实现一个按钮式的进度条,先来看看他需要实现的效果图. 和普通的圆形进度条类似,只是中间的地方有两个状态表示,未开始,暂停状态.而且他说圆形进度的功能已经实现了.那么我们只需要对中间的两个状态做处理就行了. 先来看看实现的效果图: 上面说了我们只需要处理中间状态的变化就可以了,对于进度的处理直接使用了弘洋文章中实现: http://blog.csdn.net/lmj623565791/article/details/43371299 下面开始具体实现. 具体实

android 自定义View【2】对话框取色&amp;色盘取色的实现

android 自定义View[2]对话框取色&色盘取色的实现    上一篇文章基本介绍了android自定义view的流程:继承view,复写view的一些方法.实现简单的自定义view.这篇文章主要介绍的是系统对话框取色功能,然后顺便介绍升级版,色盘取色[类似于ps中的吸管,对图片点击相应位置,获取那个位置的颜色]. 一.概述:通过该例子了解以下内容: 1.进一步了解android 自定义view. 2.知道如何获取图片上的颜色值. 3.监听屏幕touch,实现移动的时候自动取色.[onDr

Android自定义View(二、深入解析自定义属性)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51468648 本文出自:[openXu的博客] 目录: 为什么要自定义属性 怎样自定义属性 属性值的类型format 类中获取属性值 Attributeset和TypedArray以及declare-styleable ??在上一篇博客<Android自定义View(一.初体验)>中我们体验了自定义控件的基本流程: 继承View,覆盖构造方法 自定义属性 重写onMeasure方法测量宽

Android 自定义 view(三)&mdash;&mdash; onDraw

前言: 上一篇已经介绍了用自己定义的属性怎么简单定义一个view<Android 自定义view(二) -- attr 使用>,那么接下来我们继续深究自定义view,下一步将要去简单理解自定义view的两个比较重要的方法 onDraw(Canvas canvas) ,在探究 onDraw方法之前,我们必须先深入了解两个类Paint和Canvas .   第一:认识Paint 在探究onDraw之前首先必须要认识两个类,这里给出非常不错的两个资料参考网站,我也是从这里得到想要知道的东西,简单的说

Android自定义View(CustomCalendar-定制日历控件)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/54020386 本文出自:[openXu的博客] 目录: 1分析 2自定义属性 3onMeasure 4onDraw 绘制月份 绘制星期 绘制日期及任务 5事件处理 源码下载 ??应项目需求,需要做一个日历控件,效果图如下: ???? ??接到需求后,没有立即查找是否有相关开源日历控件可用.系统日历控件是否能满足 ,第一反应就是这个控件该怎么画?谁叫咱自定义控件技术牛逼呢O(∩_∩)O哈哈~

Android自定义View,你必须知道的几点

为什么我们觉得自定义View是学习Android的一道坎? 为什么那么多Android大神却认为自定义View又是如此的简单? 为什么google随便定义一个View都是上千行的代码? 以上这些问题,相信学Android的同学或多或少都有过这样的疑问. 那么,看完此文,希望对你们的疑惑有所帮助. 回到主题,自定义View ,需要掌握的几个点是什么呢? 我们先把自定义View细分一下,分为两种 1) 自定义ViewGroup 2) 自定义View 其实ViewGroup最终还是继承之View,当然

android自定义View之NotePad出鞘记

现在我们的手机上基本都会有一个记事本,用起来倒也还算方便,记事本这种东东,如果我想要自己实现,该怎么做呢?今天我们就通过自定义View的方式来自定义一个记事本.OK,废话不多说,先来看看效果图. 整个页面还是很简单的. 1.自定义View的分类 OK,那么在正文开始之前,我想先来说说自定义View的分类,自定义View我们一共分为三类 1.自绘控件 自绘控件就是我们自定义View继承自已有控件,然后扩展其功能,之前两篇自定义View的博客(android自定义View之钟表诞生记,android

Android自定义View学习笔记04

Android自定义View学习笔记04 好长时间没有写相关的博客了,前几周在帮学姐做毕设,所以博客方面有些耽误.过程中写了一个类似wp的磁贴的view,想再写个配套的layout,所以昨天看了一下自定义viewGroup的相关知识-晚上睡觉想了一下可行性不是很高-代码量还不如直接自己在xml上写来得快,速度上也是个问题.今天看了一下张鸿洋老师的Android 自定义View (三) 圆环交替 等待效果这篇博文,再加上前一段时间看到的一幅图,结合之前写的一个圆形imageView的实现博文And