本文用于记录自定义View的基础步骤以及一些基础的信息,后期可能针对具体的点写一些补充性的文章。
一 、View中关于四个构造函数参数
自定义View中View的构造函数有四个
// 主要是在java代码中生命一个View时所调用,没有任何参数,一个空的View对象
public ChildrenView(Context context) {
super(context);
}
// 在布局文件中使用该自定义view的时候会调用到,一般会调用到该方法
public ChildrenView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
//如果你不需要View随着主题变化而变化,则上面两个构造函数就可以了
//下面两个是与主题相关的构造函数
public ChildrenView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
//
public ChildrenView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
四个参数解释:
context:上下文
AttributeSet attrs:从xml中定义的参数
intdefStyleAttr:主题中优先级最高的属性
intdefStyleRes: 优先级次之的内置于View的style(这里就是自定义View设置样式的地方)
- 多个地方定义属性,优先级排序 Xml直接定义 > xml中style引用 > defStyleAttr>defStyleRes > theme直接定义 (参考文章:www.jianshu.com/p/7389287c0…)
二、自定义属性说明
除了基本类型的不说 讲一下其它几个吧:
-
color :引用颜色
-
dimension: 引用字体大小
//定义
<attr name = "text_size" format = "dimension" />
//使用:
app:text_size = "28sp"
或者
app:text_size = "@android:dimen/app_icon_size"
- enum:枚举值
//定义
<attr name="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
//使用:
app:orientation = "vertical"
- flags:标志 (位或运行) 主要作用=可以多个值
//定义
<attr name="gravity">
<flag name="top" value="0x01" />
<flag name="bottom" value="0x02" />
<flag name="left" value="0x04" />
<flag name="right" value="0x08" />
<flag name="center_vertical" value="0x16" />
</attr>
// 使用
app:gravity = Top|left
- fraction:百分数:
//定义:
<attr name = "transparency" format = "fraction" />
//使用:
app:transparency = "80%"
- reference:参考/引用某一资源ID
//定义:
<attr name="leftIcon" format="reference" />
//使用:
app:leftIcon = "@drawable/图片ID"
- 混合类型:属性定义时指定多种类型值
//属性定义
<attr name = "background" format = "reference|color" />
//使用
android:background = "@drawable/图片ID"
//或者
android:background = "#FFFFFF"
三、自定义控件类型
1. 自定义属性
在res/values
目录下的attrs.xml
文件中
<resources>
<declare-styleable name="CustomView">
<attr name="leftIcon" format="reference" />
<attr name="state" format="boolean"/>
<attr name="name" format="string"/>
</declare-styleable>
</resources>
2. 布局中使用自定义属性
在布局中使用
<com.myapplication.view.CustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:leftIcon="@mipmap/ic_temp"
app:name="温度"
app:state="false" />
3. view的构造函数获取自定义属性
class DigitalCustomView : LinearLayout {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
LayoutInflater.from(context).inflate(R.layout.view_custom, this)
var ta = context.obtainStyledAttributes(attrs, R.styleable.CustomView)
mIcon = ta.getResourceId(R.styleable.CustomView_leftIcon, -1) //左图像
mState = ta.getBoolean(R.styleable.DigitalCustomView_state, false)
mName = ta.getString(R.styleable.CustomView_name)
ta.recycle()
initView()
}
}
上面给出大致的代码 记得获取context.obtainStyledAttributes(attrs, R.styleable.CustomView)
最后要调用ta.recycle()
利用对象池回收ta加以复用
就是继承系统已经提供好给我们的控件例如TextView、LinearLayout等,分为View类型或者ViewGroup类型的两种。主要根据业务需求进行实现,实现重写的空间也很大 主要看需求。
比如需求 :在文字后面加个颜色背景
根据需要一般这种情况下我们是希望可以复用系统的onMeaseur
和onLayout
流程.直接复写onDra