本片博客重点解决上篇博客 未解决的问题以及一些方法的讲解
问题
自定义属性的xml文件写法
构造函数的调用时机
mPaint.getTextBounds(mTitleText,0,mTitleText.length(),mBound);这个方法
VIew的三种长宽模式
canvas.drawText()这个方法的用法
自定义属性的xml文件写法
<resources >
<attr name ="titleText" format ="string" />
<attr name ="titleTextColor" format ="color" />
<attr name ="titleTextSize" format ="dimension" />
<declare-styleable name ="MyTextView1" >
<attr name ="titleText" />
<attr name ="titleTextColor" />
<attr name ="titleTextSize" />
</declare-styleable >
</resources >
<resources >
<declare-styleable name ="MyTextView1" >
<attr name ="titleText" format ="string" />
<attr name ="titleTextColor" format ="color" />
<attr name ="titleTextSize" format ="dimension" />
</declare-styleable >
</resources >
嗯,两种都可以,第一种我想应该是当你的多个自定义控件用同一种属性名称且类型相同的话就可以用第一种写,但是就不能在declare-styleable结点中再次声明类型了,比如这个样子
<attr name ="titleText" format ="string" />
<declare-styleable name ="MyTextView1" >
<attr name ="titleText" format ="string" />
</declare-styleable >
这样的话会报错
第二种很好理解,直接将需要的属性名称及类型声明即可
另外declare-styleable的结点名字即为你定义的View名字
再来说一下format这个类型,如下
reference:参考某一资源ID 当你给自定义的属性生命这种类型时,意为你在使用定义的VIew的时候可以给View的这个名称的属性引用Drawable,color,mipmap,styles … 等这些东西
color:颜色值 这个容易理解,设置为颜色代码或者直接引用color里面数据
boolean:布尔值
dimension:尺寸值
float:浮点值
integer:整型值
string:字符串
fraction:百分数
enum:枚举值 这个需要你在自定义类型中提前声明,然后使用时直接使用 或者我们还可以为我们的属性设置枚举值那么就可以直接引用,如下:
<declare-styleable name ="MyTextView1" >
<attr name ="sssss" >
<enum name ="qqqqq" value ="0" />
<enum name ="aaaaa" value ="1" />
</attr >
</declare-styleable >
这样就可以直接在使用属性的时候直接使用 qqqqq 和 aaaaa这两个值
flag : 位或运算
<declare-styleable name ="MyTextView1" >
<attr name ="adsfggh" >
<flag name = "adjustUnspecified" value = "0x00" />
<flag name = "adjustResize" value = "0x10" />
<flag name = "adjustPan" value = "0x20" />
<flag name = "adjustNothing" value = "0x30" />
</attr>
</declare-styleable>
这样就可以在使用这种属性的时候给用 | 运算赋多个值
还有,也可以在声明属性类型的时候声明多个值哦 在format后面用 | 或运算跟多个类型就可以啦 在使用此属性的时候也需要配置多个属性相或
最后再来说一下xml文件中引用资源文件的方法
一般我们用@drawable/111/222 这种方法来引用,其实还可以用 ? 的形式来引用,具体方法就是讲@ 换成?即可
区别
使用@表示使用固定的style,而不会跟随Theme改变,这个style可以在style.xml中找到
而?表示从Theme中查找引用的资源名,众所周知,我们app引用的Theme可以是不同的,而在不同的theme下一些资源文件也是不一样的,用?代表不同的主题下采用的样式会不一样
构造函数的调用时机
public class MyTextView1 extends View {
public MyTextView1 (Context context) {
this (context,null );
}
public MyTextView1 (Context context, @Nullable AttributeSet attrs) {
this (context, attrs,0 );
}
public MyTextView1 (Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super (context, attrs, defStyleAttr);
}
}
在代码中直接new一个实例的时候,会调用第一个构造函数。
在xml布局文件调用的时候,会调用第二个构造函数。
在xml布局文件中调用,并且还使用了自定义属性时,这里调用的还是第二个构造函数.
也就是说,系统默认只会调用前两个构造函数,至于第三个构造函数的调用,通常是我们自己在构造函数中主动调用的(例如,在第二个构造函数中调用第三个构造函数).(我自己用代码敲得,应该是正确的)
再来说下这几个参数吧
第一个不用讲,第二个参数就是你在xml文件中使用的自定义属性的集合,也就是说,在使用控件的时候,我们使用了几个自定义的属性,那么第二个参数拿到的就是这几个参数的集合,在代码中,我们可以通过context.obtainStyledAttributes(attrs, R.styleable.MyTextView1,defStyleAttr,0);获取到包装好的集合,遍历集合,就可以得到用户设置的值
第三个参数defStyleAttr,这个是当前Theme中的一个attribute,是指向style的一个引用,当在layout xml中和style中都没有为View指定属性时,会从Theme中这个attribute指向的Style中查找相应的属性值,这就是defStyle的意思
就是说当我们没有为view指定属性的时候,我们还为它制定了一套默认属性,此时用这套默认属性就ok
mPaint.getTextBounds(mTitleText,0,mTitleText.length(),mBound);这个方法
public void getTextBounds (String text,int start,int end ,Rect bounds)
返回边界(由调用者分配)包含所有字符的最小矩形,其中隐含的原点为(0 ,0 )。
文本 测量并返回其界限的字符串
开始 要测量的字符串中的第一个字符的索引
结束 1 超过字符串度量中的最后一个字符
界限 返回所有文本的联合边界。必须由主叫方分配。
emmmmmmmmmm,自动忽略谷歌翻译的尿性,但是大体意思还是看出来了
第一个参数传一个字符串
第二个和第三个参数传的是要测量的字符串中的字符串边界,比如说我要测量第五个到第九个字符这样子
第四个参数传的是一个矩形,也就是测量文本的联合边界,嗯 就是我们测量的文本的外边框,所以他是一个矩形,根据官方文档所说,这个矩形需要我们自己分配,而他为我们返回的信息就包含在了这个矩形当中
VIew的三种长宽模式
UNSPECIFIED 未指定,View可以达到他所想要的任何尺寸
EXACTLY 已确定,如在layout xml文件中直接指定多大数字之类的,那么这个View就只能这么大
AT_MOST ,能达到的最大尺寸
canvas.drawText()这个方法的用法
四个参数,第一个是要绘制的文本,第四个参数是Paint,没啥说的
重点看一下第二个和第三个参数,也就是x和y值
x -> 表示要绘制的文本的最左边(默认左边)的x坐标
在说y之前,先来说一下英语本中的四线三格,那么这个y值就是第三格的高度,叫做基准线,
而在我们汉字的写法当中,汉字的高度最低就是这个第三格,但是在英文中,像g 这些字母的话他的下边是在第四格的
当我们在设置的时候将这个y值设置为0的时候 去绘制一个英文字符串时,就会导致一些字母的下边就会看不到
所以基于这个线,小伙伴们在设置y值的时候就需要考虑一下这类情况咯
最后附上这个效果图
可以看到,当我用相同的y值画Text和line时,g的下边毫不客气的被暴露在了下面,而汉字都是全部在第三格
完
就写这么多吧,初学,如果哪里有错的,欢迎指出来,谢谢