在实际开发中,可能会用到将几个系统控件组合到一起,形成一个新的控件使用的情况。例如下面的例子:
在该例中,我们将两个TextView 和一个CheckBox组合成一个控件,一起使用。下面来介绍实现步骤
1. 将组合控件作为一个item个写在一个xml中 如下的 setting_item_view.xml
<?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">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自动更新设置"
android:textColor="#000"
android:textSize="18sp" />
<TextView
android:id="@+id/tv_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_title"
android:text="自动更新已关闭"
android:textColor="#000"
android:textSize="18sp" />
<!--经过测试发现,以下两个属性加不加都不影响checkbox的事件传递-->
<!--android:focusable="false"-->
<!--android:focusableInTouchMode="false"-->
<CheckBox
android:clickable="false"
android:id="@+id/cb_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true" />
<View
android:layout_width="match_parent"
android:layout_height="1sp"
android:layout_below="@id/tv_desc"
android:layout_marginTop="5dp"
android:background="#000" />
</RelativeLayout>
</LinearLayout>
2. 新建一个SettingItemView 类,继承自RelativeLayout
public class SettingItemView extends RelativeLayout {
private CheckBox cb_box;
private TextView tv_desc;
public SettingItemView(Context context) {
this(context,null);
}
public SettingItemView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public SettingItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context,attrs,defStyleAttr);
View.inflate(context, R.layout.setting_item_view,this);
TextView tv_title = findViewById(R.id.tv_title);
tv_desc = findViewById(R.id.tv_desc);
cb_box = findViewById(R.id.cb_box);
}
在上面的类中重写了3个构造方法,将原来的构造方法中super(content) 修改为this(context,null),代表的含义是当系统调用第一个构造方法时,父类的构造方法自动调用this(Context,context , AttributeSet attrs )方法,只是第二个参数传入null,以此类推,当调用第二个构造方法时,自动调用第三个构造方法。此时我们只需要重新第三个构造方法即可
在第三个构造方法中,我们首先调用了系统的父类构造方法,然后通过View.inflate()方法 将xml文件渲染成一个view对象,注意第三位的参数传入的this,代表生成的view对象需要挂载在父类对象中,即SettingItemView 这个控件上。
3. 在layout文件中调用生成的组合控件
<?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="match_parent"
android:orientation="vertical">
<TextView
style="@style/TitleStyle"
android:text="设置中心" />
<com.opple.mobilsafe.activity.SettingItemView
android:id="@+id/siv_update"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.opple.mobilsafe.activity.SettingItemView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
注意上面代码中的SettingItemView控件的标签必须写全路径才可以,其他的使用方法和常规的控件使用方法相同。
4. 在自定义的组合控件上绑定点击事件
public class SettingActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
initUpdate();
}
private void initUpdate() {
final SettingItemView siv_update = findViewById(R.id.siv_update);
siv_update.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean isCheck = siv_update.isCheck();
siv_update.setChecked(!isCheck);
}
});
}
}
绑定点击事件的方法和常规的控件使用方法类似,第一步,先通过findViewById()方法找到控件,第二部通过setOnClickListener方法绑定一个事件给组合控件。