带你一起瞧瞧自定义属性以及自定义View的使用
都说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的使用相关推荐
- Android自定义View 之自定义属性
1 自定义属性值 自定义view的起步是自定义属性,并且正确的读取属性. 在res/values/attrs.xml的文件中创建属性: <declare-styleable name=" ...
- 超全的Android面经_安卓面经(20/30)之自定义View全解析
系列专栏: 安卓高频面经解析大全专栏链接:150道安卓高频面试题全解析 安卓高频面经解析大全目录详情 : 安卓面经_anroid面经_150道安卓常见基础面试题全解析 安卓系统Framework面经专 ...
- Android软件开发之盘点自定义View界面大合集(二)
Android软件开发之盘点自定义View界面大合集(二) - 雨松MOMO的程序世界 - 51CTO技术博客 雨松MOMO带大家盘点Android 中的自定义View界面的绘制 今天我用自己写的一个 ...
- android自定义计步器形状,Android自定义View仿QQ运动步数效果
本文实例为大家分享了Android QQ运动步数的具体代码,供大家参考,具体内容如下 今天我们实现下面这样的效果: 首先自定义属性: 自定义View代码如下: /** * Created by Mic ...
- android通过代码设置铃声_Android基础(5)—自定义View
自定义View 基本认知: 虽然Android已经自带来很多强大的UI控件,但是依旧不能满足所有开发人员的需求.通常开发人员需要实现设计师精心设计的视觉效果,这样情况下可能现有的控件就不能满足需求或者 ...
- android功能相同的view,Android自定义View实现扫描效果
本文实例为大家分享了Android自定义View实现扫描效果的具体代码,供大家参考,具体内容如下 演示效果如下: 实现内容: 1.控制动画是竖向或者横向 2.控制动画初始是从底部/左边开始,或者从上边 ...
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
转载请注明地址:http://blog.csdn.net/xiaanming/article/details/10298163 很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己 ...
- Andoid自定义View的OnMeasure详解和自定义属性
一,OnMeasure详解 Android开发中偶尔会用到自定义View,一般情况下,自定义View都需要继承View类的onMeasure方法,那么,为什么要继承onMeasure()函数呢?什么情 ...
- Android中的自定义view和自定义属性TypedArray的使用
先总结下自定义View的步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 [ 3.重写onMesure ] 4.重写onDraw 我把3用[]标出了,所以说3不一定是必 ...
最新文章
- 第一次,触碰Web App项目,栽过的那些坑。
- systemback-----做你折腾的后盾
- Linux性能监测工具Nmon介绍及其使用
- 神奇的nginx之https支持
- eclipse egit 报错 The current branch is not configured for pull No value for key branch.master
- poj3264Balanced Lineup(倍增ST表)
- 广搜 广搜 poj 3984
- Flutter 动态饼状图 让你的APP中无聊的统计图动起来 挻舒适的感觉瞬间提升一个档次 -深夜创作
- 如何安装mysql5.7.15_ubuntu16.04安装mysql5.7.15
- jsp中把js变量赋给java变量,或者将java变量赋给js变量怎么做?
- mysql 视图没主键,mysql创建视图后打开提示没有主键,mysql视图
- H.264 AVC 编解码标准
- PHP命名空间 namespace 及 use 的用法
- 紫微星情大全系列之紫微星
- ansys linux运行_ANSYS2020R1 产品Linux平台安装
- 支持十亿级密态数据、低代码,蚂蚁集团发布隐语开放平台
- 旧苹果短信导入新苹果手机上,iphone短信迁移
- 如何使用智能手机或Smartwatch重新配置睡眠周期
- 远光天擎 | 研发运维一体化智能云平台
- 前端 - excel导入 / 导出功能
热门文章
- 高影响力期刊iMeta扬帆起航(微生物组生物信息)
- 系统设计学习(一)Design Pastebin.com (or Bit.ly)
- Debian9 安装迅雷、百度网盘、微信、QQ、Tim等常用软件
- 黑提文案:卖黑提的水果文案,黑提水果发圈文案
- 周星驰影片经典台词之《唐伯虎点秋香》
- tensorflow实现triplet loss
- 《拖拉一点也无妨》小记
- 线段相交(快速排斥和跨立)
- 华为融合电信云解决方案包括_华为:电信云打造5G智慧大脑
- c语言new的作用,C语言中new的用法?