以前因为年少无知,以为自定义ViewGroup时一定要自己安排其中子View的布局,幻想着要是能直接继承某个布局从而不用自己再安排子View的布局该有多好,今天无意间看了一段源码之后,才知道这原来不是梦!!!#-#
自定义的Card
public class Card extends LinearLayout {
private TextView mFirstName;
private TextView mLastName;
private TextView mAge;
public Card(Context context) {
this(context, null);
}
public Card(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public Card(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inflate(context, R.layout.card, this);
setOrientation(VERTICAL);
//因为Data binding 不支持直接包含 merge 节点,所以这里只能通过findViewById
mFirstName = (TextView) findViewById(R.id.firstname);
mLastName = (TextView) findViewById(R.id.lastname);
mAge = (TextView) findViewById(R.id.age);
}
// 自动 Setter
public void setObject(User user) {
mFirstName.setText(user.getFirstName());
mLastName.setText(user.getLastName());
mAge.setText(String.valueOf(user.getAge()));
}
}
对应的card布局:
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/firstname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/lastname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</merge>
当然这里还涉及到了Data Binding使得内容,顺便提一下(Data Binding 在对应名称的属性不存在的时候也能继续工作。你可以轻而易举地使用 Data Binding 为任何 setter “创建” 属性。):
<路径名.Card
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:object="@{user}"/>
上述自定义布局 Card,并没有添加 declare-styleable,但是可以使用自动 setter 的特性来调用这些函数。