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. eclipse发布项目报错:Multiple Contexts hava a path of “/xxx“

    你的位置:首页 > Java编程 > eclipse发布项目报错:Multiple Contexts hava a path of “/xxx“ eclipse发布项目报错:Multipl ...

  2. 中文分词算法之最大正向匹配算法(Python版)

    最大匹配算法是自然语言处理中的中文匹配算法中最基础的算法,分为正向和逆向,原理都是一样的. 正向最大匹配算法,故名思意,从左向右扫描寻找词的最大匹配. 首先我们可以规定一个词的最大长度,每次扫描的时候 ...

  3. Android 通过wifi调试程序【转】

    1.首先让android手机监听指定的端口: 这一步需要使用shell,因此手机上要有终端模拟器,不过网上很多,随便找个就行了,依次敲入下列几行: ? su//获取root权限 setprop ser ...

  4. jquery控制动态生成的gridview中多列checkbox的全选反选及自动判断是否全选状态

    动态生成的Gridview的前台html代码如下:     <table class="usertableborder" cellspacing="0" ...

  5. VC++ WIN32 sdk实现按钮自绘详解 之二.

    网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说. 实例图片:    首先建立一个标准的Win32 Application 工程.选择a simple Wi ...

  6. Windows消息队列

    一 Windows中有一个系统消息队列,对于每一个正在执行的Windows应用程序,系统为其建立一个“消息队列”,即应用程序队列,用来存放该程序可能 创建的各种窗口的消息.应用程序中含有一段称作“消息 ...

  7. 与众不同 windows phone (10) - Push Notification(推送通知)之推送 Tile 通知, 推送自定义信息

    原文:与众不同 windows phone (10) - Push Notification(推送通知)之推送 Tile 通知, 推送自定义信息 [索引页][源码下载] 与众不同 windows ph ...

  8. Struts2 Action接收表单参数

    struts2 Action获取表单传值    1.通过属性驱动式    JSP:        <form action="sys/login.action" method ...

  9. 可运行jar包调用exe可运行文件,子进程阻塞

    背景: 须要在项目的測试工具中加入一个button,点击后直接打开某exe工具. 这个工具的功能是导入txt文件,转为excel报表输出. 无奈解析了两行之后就停止不动了,也不报错.关闭測试工具后,就 ...

  10. navicat for mysql 显示中文乱码解决办法

      最近遇到一个问题,用navicat for mysql 打开数据库时全都显示的是乱码(在用程序代码插入数据之前确保字符不是乱码),遇到问题就的寻求解决之道,百度了好长时间也没解决,网上那些解决办法 ...