Define a Custom Widget in Android App
在Android应用中定义个自定义控件
1. 使用XML自定义视图/控件
一个简单的例子,自定义单元条 CellBar
1、xml布局如下:
<code class="xml"><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white" android:padding="10dp"> <ImageView android:id="@+id/cell_bar_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent"/> <TextView android:id="@+id/cell_bar_label" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="5dp" android:textColor="@color/black" android:text="android:" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toEndOf="@id/cell_bar_icon"/> <TextView android:id="@+id/cell_bar_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android2:" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@id/cell_bar_go"/> <ImageView android:id="@+id/cell_bar_go" android:src="@drawable/ic_keyboard_arrow_right" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
2、代码如下(继承ConstraintLayout):
<code class="kotlin">class CellBar : ConstraintLayout { private var iconView: ImageView? = null private var labelView: TextView? = null private var contentView: TextView? = null @DrawableRes var icon: Int = 0 set(value) { field = value iconView?.setImageResource(value) } var label: CharSequence? = null set(value) { field = value labelView?.text = value } var text: CharSequence? = null set(value) { field = value contentView?.text = value } constructor(context: Context) : this(context, null) constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { init(context) attrs?.let { retrieveAttributes(attrs) } } fun init(context: Context) { val view = LayoutInflater.from(context).inflate(R.layout.widget_cell_bar,this) iconView = view.findViewById(R.id.cell_bar_icon) labelView = view.findViewById(R.id.cell_bar_label) contentView = view.findViewById(R.id.cell_bar_text) } private fun retrieveAttributes(attrs: AttributeSet) { val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CellBar) val iconRes = typedArray.getResourceId(R.styleable.CellBar_icon, 0) if (iconRes != 0) icon = iconRes label = typedArray.getText(R.styleable.CellBar_label) text = typedArray.getText(R.styleable.CellBar_text) typedArray.recycle() } }
上述代码 重写了构造器。在构造器中:1 加载xml布局文件,2 获取控件 ,3 获取属性 ,4 将属性赋值到控件上
3、添加自定义属性 res/values/attrs.xml
<code class="xml"><resources> <declare-styleable name="CellBar"> <attr name="icon" format="reference" /> <attr name="label" format="string" /> <attr name="text" format="string" /> </declare-styleable> </resources>
4、使用自定义控件
<code class="xml"> <com.edgar.movie.widget.CellBar android:layout_marginTop="20dp" android:layout_width="match_parent" android:layout_height="wrap_content" app:icon="@drawable/ic_sofa" app:label="看电影"/>
Reference 参考
- 本文示例