一、概念
1.2 自定义控件的不同实现方式
复用已有控件 | 复用布局文件 | |
组合现有的控件 | ||
扩展已有的控件 | 继承特定的View(如TextView) | |
继承特定的ViewGroup(如LinearLayout) | ||
完全自定义 | 直接继承 View | 主要是实现 onMeasure() + onDraw(),因为没有子元素需要布局。 |
需要自己实现 wrap_content、padding,不需要自己实现 margin 该属性是由父容器决定的。 | ||
直接继承 ViewGroup | 主要是实现 onMeasure() + onLayout(),因为子元素都绘制好了父容器不需要额外绘制。 | |
需要自己实现 wrap_content、padding、margin。 |
-
对于 wrap_content 需要在 onMeasure() 中处理。
-
对于自定义View,padding 是在 draw() 中处理。
-
对于自定义ViewGroup,padding 和 margin 需要在 onMeasure() 和 onLayout() 中处理。
二、复用已有控件
2.1 复用布局文件
- 新建一个 layout_title.xml 文件,编写需要复用的布局。
- 在要使用的 activity_main.xml布局中,通过 <include layout="@layout/title" /> 引用。
- 在 MainActivity 中,可通过复用布局的实例 title.findViewById 查找 子View ID来拿到实例进行配置。
2.2 组合现有的 View 控件
- 新建一个 layout_title.xml 文件,将 view 控件组合起来。
- 新建一个TitleLayout.class,继承自LinearLayout,在 init{} 初始化代码块中通过 LayoutInflater 对布局文件进行加载和配置。
- 在要使用的 activity_main.xml布局中,通过完整包名引用。
layout_title.xml
<LinearLayout>
<Button...>
<TextView...>
<Button...>
</LinearLayout>
TitleLayout.class
class TitleLayout(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
init {
LayoutInflater.from(context).inflate(R.layout.layout_title, this)
leftButton.setOnClickListener{
val activity = context as Activity
activity.finish()
}
titleText.text = "Title"
rightButton.setOnClickListener {
Toast.makeText(context, "Hello World", Toast.LENGTH_SHORT).show()
}
}
}
activity_main.xml
<LinearLayout>
<com.example.TitleLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout/>