第一步:写出需要组合的布局:例如(登录)下图:
第二步:自定义属性,在value下新建一个 attts.xml 文件,写入如下代码:
<!--自定义属性-->
<declare-styleable name="customView">
<attr name="tv1" format="string" />
<attr name="tv2" format="string" />
</declare-styleable>
第三步:新建一个class文件,继承RelativeLayout,并实现其构造方法
public class CustomView extends RelativeLayout {
private final static String text1 = "测试1";
private final static String text2 = "测试2";
private Button btn;
private TextView tv1, tv2;
private EditText edt1, edt2;
private Context context;
private CustomCallBack customCallBack;
public CustomView(Context context) {
this(context, null);
}
public CustomView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
this.context = context;
//初始化布局
initView();
//填充初始数据
initData(attrs);
/**
* 初始化按钮的点击事件,并在点击事件中调用用户传入的接口
*/
initbtnClick();
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* =========定义一个set方法供外部传入callback
* @param customCallBack
*/
public void setCustomCallBack(CustomCallBack customCallBack) {
this.customCallBack = customCallBack;
}
/**
* =========设置button的点击事件
*/
private void initbtnClick() {
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//在按钮的点击事件中调用接口的方法
if (customCallBack != null) {
String str1 = edt1.getText().toString().trim();
String str2 = edt2.getText().toString().trim();
customCallBack.onclick(v, str1, str2);
}
}
});
}
/**
* ====定义接口
*/
public interface CustomCallBack {
void onclick(View v, String data1, String data2);
}
/**
* ===========填充数据
*
* @param attrs
*/
private void initData(AttributeSet attrs) {
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.customView);
if (attributes != null) {
String str1 = attributes.getString(R.styleable.customView_tv1);
String str2 = attributes.getString(R.styleable.customView_tv2);
//设置TextView的值,当用户没有设置的时候,就用默认的
tv1.setText((str1 == null ? text1 : str1) + ":");
tv2.setText((str2 == null ? text2 : str2) + ":");
}
}
/**
* =========初始化布局
*/
private void initView() {
LayoutInflater.from(context).inflate(R.layout.layout_custom, this, true);
tv1 = findViewById(R.id.tv1);
tv2 = findViewById(R.id.tv2);
edt1 = findViewById(R.id.edt1);
edt2 = findViewById(R.id.edt2);
btn = findViewById(R.id.btn);
}
}
第四步:在布局文件中使用:
<com.green.adjust.customview.CustomView
android:id="@+id/custom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tv1="用户名"
app:tv2="密 码" />
第五步:在activity中声名,初始化并使用:
CustomView custom = findViewById(R.id.custom);
custom.setCustomCallBack(new CustomView.CustomCallBack() {
@Override
public void onclick(View v, String data1, String data2) {
tv11.setText("用户名:" + data1);
tv12.setText("密 码:" + data2);
}
});
效果如下:
自定义组合控件的布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:orientation="vertical"
android:padding="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户名:"
android:textSize="20dp" />
<EditText
android:id="@+id/edt1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="20dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密 码:"
android:textSize="20dp" />
<EditText
android:id="@+id/edt2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="20dp" />
</LinearLayout>
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dp"
android:text="登 录"
android:textSize="20dp" />
</LinearLayout>