都说Android技术博大精深,Android控件强大无比,想想也确实如此。随着Android的不断发展,Android控件日趋强大以及完善化。But,有些还是满足不了公司多变的需求。遇到这种情况,咋办?凉拌,我们只能自定义一些自定义控件了。今天就和大家一起来聊聊自定义属性以及自定义控件的使用。开始之前我们来看看下面的效果。

效果图

看到这效果图有啥想法,心里会不会有点放烟花的节奏.....so easy。看到这图,想必你心中肯定已经闪过无数的实现方式。那,怎么用自定义View的方式来实现呢?有人说先画个背景Bitmap圆,然后在圆上画上Text就Ok啦,还有人说直接自定义一个CircleTextView就Ok了。当然条条大路通罗马,Just like it。这里选择自定义CirlceTextView作为Demo来说明自定义View属性以及自定义View的使用。好费话不多说,下面开始正式介绍。自定义CircleTextView主要有下面几个步骤:

1.自定义属性

2.自定义View中获取自定义属性

3.添加控制自定义属性的条件

4.在layout中添加自定义控件以及自定义属性

下面分别从这四个方面来介绍自定义属性以及自定义View的使用。

1.自定义属性

自定义属性首先在values文件加下,新建一attrs.xml文件,其具体的代码如下所示。

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="CircleTextView"><attr name="text" format="string|reference" /><attr name="textColor" format="color|reference" /><attr name="textSize" format="dimension|reference" /><attr name="bacground" format="color|reference" /><attr name="radius" format="dimension" /></declare-styleable><!--    <declare-styleable name="CircleTextView"><attr name="text"  /><attr name="textColor" /><attr name="textSize"  />
<attr name="bacground"  /><attr name="radius"  /></declare-styleable> --></resources>

文件说明:

当然自定义属性也有很多中方式。可以在上部分先添加属性以及属性的类型,下部分declare-styleable即可。也可以直接declare-styleable的时,直接添加并声明属性。其中string | reference表示既可以是String类型,也可以引用,比如@string/ID。其他的以此类推。

2.获取自定义属性

获取自定义属性一般在CircleTextView的两个或三个参数的构造方法中获取。其具体的代码片段如下所示。

<pre name="code" class="java">   public CircleTextView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);//获取对应的自定义属性TypedArray a = null;try{a = context.obtainStyledAttributes(attrs, R.styleable.CircleTextView, defStyle, 0);int n = a.getIndexCount();for(int i=0;i<n;i++){int attr = a.getIndex(i);switch (attr) {case R.styleable.CircleTextView_radius:mRadius = (int) a.getDimension(attr, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,14, getResources().getDisplayMetrics()));break;case R.styleable.CircleTextView_text:mText = a.getString(attr);break;case R.styleable.CircleTextView_textSize:mTextSize = (int) a.getDimension(attr, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 14,getResources().getDisplayMetrics()));break;case R.styleable.CircleTextView_textColor:mTextColor = a.getColor(attr, 0x000000);break;case R.styleable.CircleTextView_bacground:mBacground = a.getColor(attr, 0x000000);break;}}}finally{if(null!=a){a.recycle();}}}



3. 控制自定义属性的条件

控制自定义属性也就是提供一些set和get方法,供开发者随心所欲的设置一些自定义的属性,其具体的代码片段如下所示。

 /*** 设置CircleTextView的内容* @param mText*/public void setText(String mText){this.mText = mText;invalidate();}/*** 获取CircleTextView的内容* @param mText*/public String getText(){return mText;}/*** 设置CircleTextView的文字颜色* @param mText*/public void setTextColor(int mTextColor){this.mTextColor = mTextColor;invalidate();}/*** 设置CircleTextView的文字大小* @param mText*/public void setTextSize(int mTextSize) {mTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mTextSize,getResources().getDisplayMetrics());this.mTextSize = mTextSize;invalidate();}/*** 设置CircleTextView的背景色* @param mBacground*/public void setBacground(int mBacground){this.mBacground = mBacground;invalidate();}

这里需要注意两点。一是setTextSize时,TypeValue.COMPLEX_UNIT_SP单位,不然没有效果,因为Text文字一般都是设置SP单位。二是每设置完一个属性必须调用下invalidate()方法,控件属性才会生效。

4.在layout中添加自定义控件以及自定义属性

       上面的三步都逐渐完成了,下面我们要在layout文件中添加自定义控件以及自定义属性。其具体的Layout文件如下所示。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:jamy="http://schemas.android.com/apk/res/com.example.testcircletextview"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.testcircletextview.MainActivity" ><com.example.testcircletextview.CircleTextViewandroid:id="@+id/mTextView"android:layout_width="300dp"android:layout_height="200dp"jamy:text="" jamy:textSize="18sp"android:layout_centerInParent="true"jamy:textColor="#ff0000"jamy:bacground="@android:color/holo_green_dark"/></RelativeLayout>

好了上面的自定View的一些系统的步骤已经介绍完毕,下面整体来看下CircleTextView.java这个类。其具体的代码如下所示。

package com.example.testcircletextview;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Rect;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;public class CircleTextView extends TextView{private int mTextSize;private int mTextColor;private String mText;private int mBacground;private int mRadius;private Paint mBacPaint;private Paint mTextPaint;// 文字的宽和高private Rect mTextBound;public CircleTextView(Context context) {super(context,null);}public CircleTextView(Context context, AttributeSet attrs) {this(context, attrs,0);}public CircleTextView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);//获取对应的自定义属性TypedArray a = null;try{a = context.obtainStyledAttributes(attrs, R.styleable.CircleTextView, defStyle, 0);int n = a.getIndexCount();for(int i=0;i<n;i++){int attr = a.getIndex(i);switch (attr) {case R.styleable.CircleTextView_radius:mRadius = (int) a.getDimension(attr, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,14, getResources().getDisplayMetrics()));break;case R.styleable.CircleTextView_text:mText = a.getString(attr);break;case R.styleable.CircleTextView_textSize:mTextSize = (int) a.getDimension(attr, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 14,getResources().getDisplayMetrics()));break;case R.styleable.CircleTextView_textColor:mTextColor = a.getColor(attr, 0x000000);break;case R.styleable.CircleTextView_bacground:mBacground = a.getColor(attr, 0x000000);break;}}}finally{if(null!=a){a.recycle();}}}/*** 初始化背景画笔以及文字画笔*/private void init() {mBacPaint = new Paint();mBacPaint.setColor(mBacground);mBacPaint.setAntiAlias(true);  mTextBound = new Rect();mTextPaint = new Paint();mTextPaint.setColor(mTextColor);mTextPaint.setTextSize(mTextSize);mTextPaint.setStyle(Style.FILL);mTextPaint.getTextBounds(mText,0,mText.length(),mTextBound);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);init();mRadius = Math.min(getWidth(),getHeight());System.out.println("onDraw   Width:"+getWidth()+"Height:"+getHeight()+"mRadius:"+mRadius);canvas.drawCircle(getWidth()/2, getHeight()/2, mRadius/2, mBacPaint);  canvas.drawText(mText, getWidth()/2-mTextBound.width()/2, getHeight()/2+mTextBound.height()/2, mTextPaint);}/*** 设置CircleTextView的内容* @param mText*/public void setText(String mText){this.mText = mText;invalidate();}/*** 获取CircleTextView的内容* @param mText*/public String getText(){return mText;}/*** 设置CircleTextView的文字颜色* @param mText*/public void setTextColor(int mTextColor){this.mTextColor = mTextColor;invalidate();}/*** 设置CircleTextView的文字大小* @param mText*/public void setTextSize(int mTextSize) {mTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mTextSize,getResources().getDisplayMetrics());this.mTextSize = mTextSize;invalidate();}/*** 设置CircleTextView的背景色* @param mBacground*/public void setBacground(int mBacground){this.mBacground = mBacground;invalidate();}}

按照上面的步骤走完,自定义CircleTextView剩下最核心的OnDraw()绘制View了。下面仔细来瞧瞧这个方法。

在OnDraw()主要进行了对背景画笔以及文本画笔进行初始化,其次获取我们设置的宽高中的最小值,作为所画圆的直径。紧随绘制我们的圆形背景(即DrawCircle())以及Text内容(即drawText()),由此绘制完成。

经过上面的一系列步骤还不知道自定义的CircleTextView会呈现啥效果,下面来正式测试下。运行其效果如下所示。

           

运行效果图

经过上面的介绍,现在对自定义View属性以及自定义View有了点了解吧。虽然这里的自定义View so easy不过有些细节不容忽视。下面我们就稍微做下总结,看看那些地方需要注意下。

1.自定义声明属性时,最好加上declare-styleable(因为加上declare-styleable相当于在xml中加上控件id类似,系统会默认生成一些对应属性的常量,方便我们获取属性时查找)。

2.代码控制自定义属性时必须invalidate(),假如单位是dp或sp的属性必须设置对应的属性单位。

3.设置画笔的一些属性,最好写在onDraw(),方便属性的刷新(因为每执行一次invalidate就执行一次onDraw())。

4.在layout.xml文件中引用自定义属性以及自定义View必须加入   xmlns:jamy="http://schemas.android.com/apk/res/+应用包名"(其中jamy可以为任意命名,假如命名jamy下面属性必须是jamy:属性名)

由此自定义View属性和自定义View介绍到此完毕,好久没有更新博客了,有点小激动咋办?哈哈,上面自定义View可能介绍的还不是很全面,欢迎各位给出批评与建议。

带你一起瞧瞧自定义属性以及自定义View的使用相关推荐

  1. Android自定义View 之自定义属性

    1 自定义属性值 自定义view的起步是自定义属性,并且正确的读取属性. 在res/values/attrs.xml的文件中创建属性: <declare-styleable name=" ...

  2. 超全的Android面经_安卓面经(20/30)之自定义View全解析

    系列专栏: 安卓高频面经解析大全专栏链接:150道安卓高频面试题全解析 安卓高频面经解析大全目录详情 : 安卓面经_anroid面经_150道安卓常见基础面试题全解析 安卓系统Framework面经专 ...

  3. Android软件开发之盘点自定义View界面大合集(二)

    Android软件开发之盘点自定义View界面大合集(二) - 雨松MOMO的程序世界 - 51CTO技术博客 雨松MOMO带大家盘点Android 中的自定义View界面的绘制 今天我用自己写的一个 ...

  4. android自定义计步器形状,Android自定义View仿QQ运动步数效果

    本文实例为大家分享了Android QQ运动步数的具体代码,供大家参考,具体内容如下 今天我们实现下面这样的效果: 首先自定义属性: 自定义View代码如下: /** * Created by Mic ...

  5. android通过代码设置铃声_Android基础(5)—自定义View

    自定义View 基本认知: 虽然Android已经自带来很多强大的UI控件,但是依旧不能满足所有开发人员的需求.通常开发人员需要实现设计师精心设计的视觉效果,这样情况下可能现有的控件就不能满足需求或者 ...

  6. android功能相同的view,Android自定义View实现扫描效果

    本文实例为大家分享了Android自定义View实现扫描效果的具体代码,供大家参考,具体内容如下 演示效果如下: 实现内容: 1.控制动画是竖向或者横向 2.控制动画初始是从底部/左边开始,或者从上边 ...

  7. Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

    转载请注明地址:http://blog.csdn.net/xiaanming/article/details/10298163 很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己 ...

  8. Andoid自定义View的OnMeasure详解和自定义属性

    一,OnMeasure详解 Android开发中偶尔会用到自定义View,一般情况下,自定义View都需要继承View类的onMeasure方法,那么,为什么要继承onMeasure()函数呢?什么情 ...

  9. Android中的自定义view和自定义属性TypedArray的使用

    先总结下自定义View的步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 [ 3.重写onMesure ] 4.重写onDraw 我把3用[]标出了,所以说3不一定是必 ...

最新文章

  1. 第一次,触碰Web App项目,栽过的那些坑。
  2. systemback-----做你折腾的后盾
  3. Linux性能监测工具Nmon介绍及其使用
  4. 神奇的nginx之https支持
  5. eclipse egit 报错 The current branch is not configured for pull No value for key branch.master
  6. poj3264Balanced Lineup(倍增ST表)
  7. 广搜 广搜 poj 3984
  8. Flutter 动态饼状图 让你的APP中无聊的统计图动起来 挻舒适的感觉瞬间提升一个档次 -深夜创作
  9. 如何安装mysql5.7.15_ubuntu16.04安装mysql5.7.15
  10. jsp中把js变量赋给java变量,或者将java变量赋给js变量怎么做?
  11. mysql 视图没主键,mysql创建视图后打开提示没有主键,mysql视图
  12. H.264 AVC 编解码标准
  13. PHP命名空间 namespace 及 use 的用法
  14. 紫微星情大全系列之紫微星
  15. ansys linux运行_ANSYS2020R1 产品Linux平台安装
  16. 支持十亿级密态数据、低代码,蚂蚁集团发布隐语开放平台
  17. 旧苹果短信导入新苹果手机上,iphone短信迁移
  18. 如何使用智能手机或Smartwatch重新配置睡眠周期
  19. 远光天擎 | 研发运维一体化智能云平台
  20. 前端 - excel导入 / 导出功能

热门文章

  1. 高影响力期刊iMeta扬帆起航(微生物组生物信息)
  2. 系统设计学习(一)Design Pastebin.com (or Bit.ly)
  3. Debian9 安装迅雷、百度网盘、微信、QQ、Tim等常用软件
  4. 黑提文案:卖黑提的水果文案,黑提水果发圈文案
  5. 周星驰影片经典台词之《唐伯虎点秋香》
  6. tensorflow实现triplet loss
  7. 《拖拉一点也无妨》小记
  8. 线段相交(快速排斥和跨立)
  9. 华为融合电信云解决方案包括_华为:电信云打造5G智慧大脑
  10. c语言new的作用,C语言中new的用法?