1、自己定义View的属性

2、在View的构造方法中获得我们自己定义的属性

3、重写onMesure

4、重写onDraw

3这个步骤不是必须,当然了大部分情况下还是须要重写的。

1、自己定义View的属性,首先在res/values/  下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。

<?xml version="1.0" encoding="utf-8"?>
<resources> <attr name="txtName" format="string"/>
<attr name="txtColor" format="color"/>
<attr name="txtSize" format="dimension" /> <declare-styleable name="titleStyle">
<attr name="txtName"/>
<attr name="txtColor"/>
<attr name="txtSize"/>
</declare-styleable>
</resources>

定义了字体,字体颜色,字体大小3个属性,format是值该属性的取值类型:

一共同拥有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;

编写的时候工具会提醒你使用哪种,不知道也能够Google搜索下

接下来就自己定义View

public class CustomTitleView extends View{

    private  String txtName;
private int txtColor,txtSize;
private Paint mPaint;
private Rect mBounds; public CustomTitleView(Context context) {
this(context, null);
} public CustomTitleView(Context context, AttributeSet attrs) {
this(context, attrs, 0); } public CustomTitleView(Context context, AttributeSet attrs, int defStyleAttr) {
//详细操作
}
}

定义完自己定义的View ,就该调用我们自己定义的View了。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:title="http://schemas.android.com/apk/res/com.example.androidDemo" 《》
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"> <com.example.androidDemo.View.CustomTitleView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:padding="5dp"
title:txtName="你好"
title:txtColor="#ffffff"
title:txtSize="16sp"/>
</RelativeLayout>

注意代码中的这行,自己定义命名空间,com.example.androidDemo是项目包路径

xmlns:title="http://schemas.android.com/apk/res/com.example.androidDemo"

使用自己定义命名空间:

        title:txtName="你好"
title:txtColor="#ffffff"
title:txtSize="16sp"

在View的构造方法中,获得我们的自己定义的样式

public class CustomTitleView extends View{

    private  String txtName;
private int txtColor,txtSize;
private Paint mPaint;
private Rect mBounds; public CustomTitleView(Context context) {
this(context, null);
} public CustomTitleView(Context context, AttributeSet attrs) {
this(context, attrs, 0); } public CustomTitleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs,R.styleable.titleStyle,defStyleAttr,0); int n = typedArray.getIndexCount(); for (int i = 0; i < n; i++){
int attr = typedArray.getIndex(i);
switch (attr){ case 0: txtName = typedArray.getString(attr);
break;
case 1: txtColor = typedArray.getColor(attr, Color.BLACK);
break;
case 2:
txtSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break; }
}
typedArray.recycle(); /**
* 获得绘制文本的宽和高
*/
mPaint = new Paint();
mPaint.setTextSize(txtSize);
// mPaint.setColor(mTitleTextColor);
mBounds = new Rect();
mPaint.getTextBounds(txtName, 0, txtName.length(), mBounds);
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height ;
if (widthMode == MeasureSpec.EXACTLY)
{
width = widthSize;
} else
{
mPaint.setTextSize(txtSize);
mPaint.getTextBounds(txtName, 0, txtName.length(), mBounds);
float textWidth = mBounds.width();
int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
width = desired;
} if (heightMode == MeasureSpec.EXACTLY)
{
height = heightSize;
} else
{
mPaint.setTextSize(txtSize);
mPaint.getTextBounds(txtName, 0, txtName.length(), mBounds);
float textHeight = mBounds.height();
int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());
height = desired;
} setMeasuredDimension(width, height); } @Override
protected void onDraw(Canvas canvas) {
mPaint.setColor(Color.YELLOW);
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint); mPaint.setColor(txtColor);
canvas.drawText(txtName, getWidth() / 2 - mBounds.width() / 2, getHeight() / 2 + mBounds.height() / 2, mPaint); }
}

当中

MeasureSpec.EXACTLY推断你传人的宽,高是不是精确赋值

android:layout_width="wrap_content"

 android:layout_height="wrap_content"

假设是wrap_content,

 mPaint.setTextSize(txtSize);
mPaint.getTextBounds(txtName, 0, txtName.length(), mBounds);
float textWidth = mBounds.width();
int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
width = desired;

假设是200dp这类精确的宽高值,

if (widthMode == MeasureSpec.EXACTLY)
{
width = widthSize;
}

效果图 ,是不是非常好用呢

【android自己定义控件】自己定义View属性的更多相关文章

  1. Android自己定义控件之应用程序首页轮播图

    如今基本上大多数的Android应用程序的首页都有轮播图.就是像下图这种(此图为转载的一篇博文中的图.拿来直接用了): 像这种组件我相信大多数的应用程序都会使用到,本文就是自己定义一个这种组件,能够动 ...

  2. 【Android】自己定义控件实现可滑动的开关(switch)

    ~转载请注明来源:http://blog.csdn.net/u013015161/article/details/46704745 介绍 昨天晚上写了一个Android的滑动开关, 即SlideSwi ...

  3. Android自己定义控件系列案例【五】

    案例效果: 案例分析: 在开发银行相关client的时候或者开发在线支付相关client的时候常常要求用户绑定银行卡,当中银行卡号一般须要空格分隔显示.最常见的就是每4位数以空格进行分隔.以方便用户实 ...

  4. Android自定义控件1--自定义控件介绍

    Android控件基本介绍 Android本身提供了很多控件比如我们常用的有文本控件TextView和EditText:按钮控件Button和ImageButton状态开关按钮ToggleButton ...

  5. Android自己定义控件(状态提示图表)

    [工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处.尊重分享成果] 1 背景 前面分析那么多系统源代码了.也该暂停下来歇息一下,趁昨晚闲着看见一个有意思的需求就操 ...

  6. 【Android】自己定义控件——仿天猫Indicator

    今天来说说类似天猫的Banner中的小圆点是怎么做的(图中绿圈部分) 在学习自己定义控件之前,我用的是很二的方法,直接在布局中放入多个ImageView,然后代码中依据Pager切换来改变图片.这样的 ...

  7. android学习七(创建自己定义控件)

    前面学习的是android的基本控件和布局的使用,可是主要的控件和布局有时候并不能实现复杂的布局.我们来看下各种控件和布局的关系. 可见全部的控件都是直接或者间接的继承自View的,全部的布局都是直接 ...

  8. Android自己定义控件系列五:自己定义绚丽水波纹效果

    尊重原创!转载请注明出处:http://blog.csdn.net/cyp331203/article/details/41114551 今天我们来利用Android自己定义控件实现一个比較有趣的效果 ...

  9. Android自己定义控件系列二:自己定义开关button(一)

    这一次我们将会实现一个完整纯粹的自己定义控件,而不是像之前的组合控件一样.拿系统的控件来实现.计划分为三部分:自己定义控件的基本部分,自己定义控件的触摸事件的处理和自己定义控件的自己定义属性: 以下就 ...

  10. Android自己定义控件:进度条的四种实现方式

    前三种实现方式代码出自: http://stormzhang.com/openandroid/2013/11/15/android-custom-loading/ (源代码下载)http://down ...

随机推荐

  1. Effective C++_笔记_条款02_尽量以const、enum、inline替换#define

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 这个条款或许改为“宁可以编译器替换预处理器”比较好,因为或许#d ...

  2. FairScheduler的任务调度机制——assignTasks

    首先需要了解FairScheduler是如何在各个Pool之间分配资源,以及每个Pool如何在Job之间分配资源的.FairScheduler的分配资源发生在update()方法中,而该方法由一个线程 ...

  3. Lucene.Net 2.3.1开发介绍 —— 四、搜索(一)

    原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(一) 既然是内容筛选,或者说是搜索引擎,有索引,必然要有搜索.搜索虽然与索引有关,那也只是与索引后的文件有关,和索引的程序是无关的,因此 ...

  4. [置顶] head first 设计模式之----Observer pattern

    浅谈设计模式之----观察者模式      观察者模式也是我们日常程序编写中碰到比较多的一种设计模式.首先,所谓观察者模式定义就是指:在对象之间定义了一对多的依赖,这样一来,当一个对象的状态发生变化的 ...

  5. 自己定义UITabBarController

    网上大多的自己定义TabBar都是继承View的,项目中要用到path+Tabbat这种话(path用的MMDrawerController这个框架),继承View的Tabbar是无法满足条件的(不是 ...

  6. vc2008构建和使用libcurl静态库

    1>下载CURL源代码curl-7.26.0.zip 2>用VC2008/2005打开工程curl-7.26.0\lib\libcurl.vcproj,转换下工程并构建,可以直接编译成功! ...

  7. hdu 4715

    #include<stdio.h> #include<string.h> int prime[1100000],p[1000000],ans; void pri() {     ...

  8. 呜呼!Node.js是什么?

    近期看到非常多站点都使用node.js.開始感到非常好奇.就開始推測这是个什么东西,大概就是个js文件吧,所以開始根本 没有在意,可是越感觉就认为越不正确劲,为什么大家都在用它呢?所以我决定搞个明确. ...

  9. SVNKit getFileFromSVN

    /* * ==================================================================== * Copyright (c) 2004-2011 ...

  10. Windows8和MacOS10.9双系统安装及Mac经常使用软件安装--联想E49A

    前提 本篇内容所描写叙述的内容仅仅适合联想E49A笔记本,经过本篇的内容之后,对于Mac OS 10.9的使用达到正常工作使用的标准,完美度已经比較好了. 结果例如以下:显卡.网卡(RTL8168). ...