【android自己定义控件】自己定义View属性
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属性的更多相关文章
- Android自己定义控件之应用程序首页轮播图
如今基本上大多数的Android应用程序的首页都有轮播图.就是像下图这种(此图为转载的一篇博文中的图.拿来直接用了): 像这种组件我相信大多数的应用程序都会使用到,本文就是自己定义一个这种组件,能够动 ...
- 【Android】自己定义控件实现可滑动的开关(switch)
~转载请注明来源:http://blog.csdn.net/u013015161/article/details/46704745 介绍 昨天晚上写了一个Android的滑动开关, 即SlideSwi ...
- Android自己定义控件系列案例【五】
案例效果: 案例分析: 在开发银行相关client的时候或者开发在线支付相关client的时候常常要求用户绑定银行卡,当中银行卡号一般须要空格分隔显示.最常见的就是每4位数以空格进行分隔.以方便用户实 ...
- Android自定义控件1--自定义控件介绍
Android控件基本介绍 Android本身提供了很多控件比如我们常用的有文本控件TextView和EditText:按钮控件Button和ImageButton状态开关按钮ToggleButton ...
- Android自己定义控件(状态提示图表)
[工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处.尊重分享成果] 1 背景 前面分析那么多系统源代码了.也该暂停下来歇息一下,趁昨晚闲着看见一个有意思的需求就操 ...
- 【Android】自己定义控件——仿天猫Indicator
今天来说说类似天猫的Banner中的小圆点是怎么做的(图中绿圈部分) 在学习自己定义控件之前,我用的是很二的方法,直接在布局中放入多个ImageView,然后代码中依据Pager切换来改变图片.这样的 ...
- android学习七(创建自己定义控件)
前面学习的是android的基本控件和布局的使用,可是主要的控件和布局有时候并不能实现复杂的布局.我们来看下各种控件和布局的关系. 可见全部的控件都是直接或者间接的继承自View的,全部的布局都是直接 ...
- Android自己定义控件系列五:自己定义绚丽水波纹效果
尊重原创!转载请注明出处:http://blog.csdn.net/cyp331203/article/details/41114551 今天我们来利用Android自己定义控件实现一个比較有趣的效果 ...
- Android自己定义控件系列二:自己定义开关button(一)
这一次我们将会实现一个完整纯粹的自己定义控件,而不是像之前的组合控件一样.拿系统的控件来实现.计划分为三部分:自己定义控件的基本部分,自己定义控件的触摸事件的处理和自己定义控件的自己定义属性: 以下就 ...
- Android自己定义控件:进度条的四种实现方式
前三种实现方式代码出自: http://stormzhang.com/openandroid/2013/11/15/android-custom-loading/ (源代码下载)http://down ...
随机推荐
- Python 技巧
1.根据路径导入模块 如果想引用指定路径下的某个模块,则需要使用sys.path.append("module_directory") 来把这个路径添加到sys下,这就涉及到Pyt ...
- DLP底座(威创定制)
品牌:威创 型号:BC06730-1000 生产商:广东威创视讯科技股份有限公司 1.DLP底座说明 DLP底座由威创统一定制,确保了整套系统的完整性和可靠性.材质为钢结构,根据淄川地下管线中心的现场 ...
- 14.6.7?Limits on InnoDB Tables InnoDB 表的限制
14.6.7?Limits on InnoDB Tables InnoDB 表的限制 警告: 不要把MySQL system tables 从MyISAM 到InnoDB 表. 这是不支持的操作,如果 ...
- jd.py
#!/usr/bin/env python #coding:utf-8 import urllib2,re,sys,os,types #from bs4 import BeautifulSoup re ...
- 使用ServletFileUpload实现上传
1.首先我们应该为上传的文件建一个存放的位置,一般位置分为暂时和真是目录,那我们就须要获取这俩个目录的绝对路径,在servlet中我们能够这样做 ServletContext application ...
- 使用堆实现Top K 算法 JS 实现
1. 堆算法Top,时间复杂度 O(LogN) function top(arr,comp){ if(arr.length == 0){return ;} var i = arr.length / 2 ...
- Tomcat启动会遇到的问题部分解决方案
Tomcat的启动不一定会非常的顺利,这可以有多种原因 一.Tomcat是由Java所编写的,因此Tomcat的使用需要JDK的支持,如果没有配置环境变量,Tomcat当然无法启动,最明显的特征就是点 ...
- Visual Studio Code中文文档
Visual Studio Code中文文档 Visual Studio Code是一个轻量级但是十分强大的源代码编辑器,重要的是它在Windows, OS X 和Linux操作系统的桌面上均可运行. ...
- 关于IOCP,某些地方就是不让人彻底舒服(WSASend重叠post数据)
开门见山,直接就事论事. 假如有这么一个基于IOCP模型的Server,这个Server提供的所有服务中有这么一种服务……文件下载,我们再假设Server端存有一个20G的文件,客户端这时发送一个请求 ...
- Linux中more命令的实现
#include <stdio.h> #include <stdlib.h> #include <string.h> #define PAGELEN 24 #def ...