自定义View之BottomTitleImageView
自定义View之BottomTitleImageView
效果图
View生命周期
- 主要由三部分操作完成,分别是measure,layout,draw:
- measure:计算视图大小
- layouty:设置视图在屏幕中显示的位置
- draw:绘制视图.其中onDraw()方法会花费大量时间,布局变化会重绘视图,所以在onDraw()中要避免对象分配.
- invalidate() 和requsetLaytout()作用如下:
- invalidate():重新绘制view,执行draw()操作。
- requsetLaytout():重新请求绘制view,执行measure()和layout()过程,但不执行draw()操作。
定义和加载自定义属性
在values文件夹中定义属性文件attrs_wcircle_view.xml。
1
2
3
4
5
6
7
8
9
10<resources>
<declare-styleable name="WBottomTitleView">
<attr name="textString" format="string" />
<attr name="textDimension" format="dimension" />
<attr name="textColor" format="color" />
<attr name="mAlpha" format="integer" />
<attr name="mTextBgColor" format="color" />
<attr name="textDrawable" format="color|reference" />
</declare-styleable>
</resources>在自定义布局的构造方法中加载自定义属性,根据属性更新画笔。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43public WBottomTitleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
//加载 attributes
final TypedArray typedArray = getContext().obtainStyledAttributes(
attrs, R.styleable.WBottomTitleView, defStyle, 0);
mTextString = typedArray.getString(
R.styleable.WBottomTitleView_textString);
mTextColor = typedArray.getColor(
R.styleable.WBottomTitleView_textColor,
mTextColor);
mTextDimension = typedArray.getDimension(
R.styleable.WBottomTitleView_textDimension,
mTextDimension);
mAlpha = typedArray.getInt(R.styleable.WBottomTitleView_mAlpha, mAlpha);
mTextBgColor = typedArray.getInt(R.styleable.WBottomTitleView_mTextBgColor, mTextBgColor);
if (typedArray.hasValue(R.styleable.WBottomTitleView_textDrawable)) {
mTextDrawable = typedArray.getDrawable(
R.styleable.WBottomTitleView_textDrawable);
mTextDrawable.setCallback(this);
}
typedArray.recycle();
mTextPaint = new TextPaint();
mTextPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextAlign(Paint.Align.LEFT);
p = new Paint();
invalidateTextPaintAndMeasurements();
}
//根据attributes更新TextPaint
private void invalidateTextPaintAndMeasurements() {
mTextPaint.setTextSize(mTextDimension);
mTextPaint.setColor(mTextColor);
if (TextUtils.isEmpty(mTextString)) {
mTextString = "";
}
Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
mTextHeight = fontMetrics.bottom;
}
- TypedArray是一个数组容器,用于存储加载的属性。记住:用完必须recycle(),不然会发生内存泄漏。
- Paint.FontMetrics解析:
1) top是一行文字的上边界
2)ascent是文字可视区域的上边界
3)descent是文字可视区域的下边界
4)bottom是一行文字的下边界
5)leading是行与行之间的间距(通常为0,bottom与descent及top与ascent之间的间距足够间隔行行)
从上图中可以发现文字的可视区域在ascent与descent之间,top与bottom见的距离是整个文字所占空间的高度。
onDraw()绘制视图
1 | @Override |
完整代码
1 | package cn.studyou.myviewdeep.view; |
开始使用自定义View
- 在布局文件中引入View
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorAccent"
>
<cn.studyou.myviewdeep.view.WBottomTitleView
android:layout_width="match_parent"
android:layout_height="170dp"
android:id="@+id/wCircleView"
android:scaleType="fitXY"
app:textDimension="18sp"
app:textColor="#ffffff"
/>
</RelativeLayout> - Activity中设置图片和标题
1 | package cn.studyou.myviewdeep; |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 DLLCNX BLOG!
评论
GitalkTwikoo