使用xml进行布局,然后映射到自定义View中进行事件绑定是现在最常用的画UI的方式。
我一直以来的做法是,在java类的构造函数中inflate布局文件中的view,然后使用this.addView(view)的方法或者在inflate函数中进行关联。
最近一个同事的做法让我发现还存在另外一种做法,虽然本质上差不多,但是中间涉及到的一些知识还是值得注意的。
不知道你在开发过程中使用的是哪一种方式?
类内关联
这是最常用的方式,具体的代码如下
Custom2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custom2"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is Text2" />
</LinearLayout>
Custom2.java
import android.content.Context;
import android.graphics.Color;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.TextView;
public class Custom2 extends LinearLayout {
LinearLayout custom2;
TextView text2;
public Custom2(Context context) {
super(context);
initView(context);
}
public Custom2(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView(context);
}
private void initView(Context context) {
custom2 = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.custom2, this);
text2 = custom2.findViewById(R.id.text2);
text2.setTextColor(Color.BLUE);
}
}
总结:
- xml中是根标签是Android内的。
- 调用的时候需要使用类的构造函数进行构造。
类外关联
我同事的奇葩方法,主要是利用了OnFinishInflate()函数的特点
Custom1.xml
<?xml version="1.0" encoding="utf-8"?>
<com.demo.Custom1 xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custom1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is Text 1" />
</com.demo.Custom1>
Custom1.java
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.TextView;
public class Custom1 extends LinearLayout {
Custom1 custom1;
TextView textView;
public Custom1(Context context) {
super(context);
}
public Custom1(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
initViews();
}
private void initViews() {
textView = findViewById(R.id.text1);
textView.setTextColor(Color.RED);
}
}
总结:
- xml中的标签就是类的标签
- 调用的时候需要使用LayoutInflater进行初始化
调用方法
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
main.Java
public class MainActivity extends Activity {
LinearLayout container;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
container = findViewById(R.id.container);
Custom1 custom1_1 = (Custom1) LayoutInflater.from(this).inflate(R.layout.custom1, null, false);
Custom1 custom1_2 = (Custom1) LayoutInflater.from(this).inflate(R.layout.custom1, null, false);
container.addView(custom1_1);
container.addView(custom1_2);
Custom2 custom2_1 = new Custom2(this);
Custom2 custom2_2 = new Custom2(this);
container.addView(custom2_1);
container.addView(custom2_2);
}
}