原创,转载请注明出处
这个标题实在是太拗口了,但是又实在找不到别的更好的描述的方法,暂时这样吧。在开发android应用的时候,经常要用到一些系统控件,如AlertDialog,EditTextPreference等等,但是往往这些系统控件无法完全满足自己需求,于是就要继承这些类,写一个自定义的控件。
图1
图2
以这两张图片中显示的自定义控件下面介绍两种布局方法:
方法一:
以AlertDialog作为父类的自定义控件为例。
BrightnessSettingDialog.java
2 import android.content.Context;
3 import android.content.DialogInterface;
4 import android.os.Bundle;
5 import android.view.LayoutInflater;
6 import android.view.View;
7 import android.widget.CheckBox;
8 import android.widget.ImageView;
9 import android.widget.SeekBar;
10
11 publicclass BrightnessSettingDialog extends AlertDialog implements DialogInterface
12 {
13
14 private SeekBar mSeekBar;
15 private CheckBox mCheckBox;
16 private ImageView mIcon;
17 privateint mProgress;
18
19 public BrightnessSettingDialog(Context context) {
20 super(context);
21 }
22
23 public BrightnessSettingDialog(Context context, int theme) {
24 super(context, theme);
25 }
26
27 @Override
28 protectedvoid onCreate(Bundle savedInstanceState) {
29 LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
30 Context.LAYOUT_INFLATER_SERVICE);
31 View view = inflater.inflate(R.layout.brightness_setting_dialog, null);
32 setView(view);
33 super.onCreate(savedInstanceState);
34 mSeekBar = (SeekBar)findViewById(R.id.seekbar);
35 mCheckBox = (CheckBox) findViewById(R.id.automatic_mode);
36 mIcon = (ImageView) findViewById(R.id.icon);
37 mIcon.setImageResource(R.drawable.brightness);
38 mListener.onBindBrightnessSettingDialog();
39 }
40
41 public SeekBar getSeekBar() {
42 return mSeekBar;
43 }
44
45 public CheckBox getCheckBox() {
46 return mCheckBox;
47 }
48 }
brightness_setting_dialog.xml
2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="wrap_content" android:layout_height="wrap_content">
4 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
5 android:id="@+id/screen" android:layout_width="fill_parent"
6 android:layout_height="wrap_content" android:orientation="vertical">
7 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
8 android:layout_width="fill_parent" android:layout_height="wrap_content"
9 android:orientation="vertical" android:gravity="center_horizontal"
10 android:paddingBottom="10dip">
11 <ImageView android:id="@+id/icon" android:layout_width="wrap_content"
12 android:layout_height="wrap_content" android:paddingTop="10dip"/>
13
14 <CheckBox android:id="@+id/automatic_mode"
15 android:layout_width="fill_parent" android:layout_height="wrap_content"
16 android:text="@string/automatic_brightness" android:textAppearance="?android:attr/textAppearanceSmall"
17 android:layout_marginTop="6dip" android:layout_marginLeft="10dip"
18 android:layout_marginRight="20dip"/>
19
20 <SeekBar android:id="@+id/seekbar" android:layout_width="fill_parent"
21 android:layout_height="wrap_content" android:padding="10dip"/>
22 </LinearLayout>
23 </ScrollView>
24 </RelativeLayout>
首先创建alertdialog的子类,在OnCreate方法中通过LayoutInflater来加载控件:
2 Context.LAYOUT_INFLATER_SERVICE);
3 View view = inflater.inflate(R.layout.brightness_setting_dialog, null);
接着调用setView方法,将加载的控件添加到父控件中,最后调用父类的onCreate方法即可。
要注意的是,xml中采用的是RelativeLayout布局。
方法二:
方法一中的AlertDialog的子类,确定和取消按钮由父类创建的,并且在布局中固定在整个控件的最底端,因此可以通过inflate RelativeLayout的方式来创建自定义控件,但是图二所示,如果这个控件中的编辑框是由父类创建的,那么如何在子类中控制这个编辑框恰好放在想放的位置呢?下以EditTextPreference作为父类的自定义控件为例实现这个自定义控件。
代码摘要:
EditPhoneNumberPreference.java
2publicclass EditPhoneNumberPreference extends EditTextPreference {
3…
4/**
5 * Overriding EditTextPreference's onAddEditTextToDialogView.
6 *
7 * This method attaches the EditText to the container specific to this
8 * preference's dialog layout.
9*/
10 @Override
11protectedvoid onAddEditTextToDialogView(View dialogView, EditText editText) {
12
13// look for the container object
14 ViewGroup container = (ViewGroup) dialogView
15 .findViewById(R.id.edit_container);
16
17// add the edittext to the container.
18if (container !=null) {
19 container.addView(editText, ViewGroup.LayoutParams.FILL_PARENT,
20 ViewGroup.LayoutParams.FILL_PARENT);
21 }
22 }
23…
24}
pref_dialog_editphonenumber.xml
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="wrap_content"
4 android:layout_height="wrap_content"
5 android:padding="5dip"
6 android:orientation="vertical">
7
8 <TextView android:id="@+android:id/message"
9 style="?android:attr/textAppearanceMedium"
10 android:layout_width="fill_parent"
11 android:layout_height="wrap_content"
12 android:textColor="?android:attr/textColorPrimary"
13 android:paddingLeft="10dip"
14 android:paddingRight="10dip"/>
15
16 <LinearLayout
17 android:id="@+id/number_field"
18 android:layout_width="fill_parent"
19 android:layout_height="0dip"
20 android:layout_weight="1.0"
21 android:addStatesFromChildren="true"
22 android:gravity="center_vertical"
23 android:baselineAligned="false"
24 android:paddingLeft="10dip"
25 android:paddingRight="10dip">
26
27 <LinearLayout android:id="@+id/edit_container"
28 android:layout_width="0dip"
29 android:layout_weight="1"
30 android:layout_height="wrap_content"/>
31
32 <ImageButton android:id="@+id/select_contact"
33 android:layout_width="wrap_content"
34 android:layout_height="fill_parent"
35 android:padding="10dip"
36 android:src="@drawable/ic_button_contacts"/>
37 </LinearLayout>
38
39 </LinearLayout>
继承EditTextPreference,并实现onAddEditTextToDialogView方法,这个方法会在onBindDialogView中调用,而onBindDialogView方法则会在父类显示dialog控件时调用,同时父类EditTextPreference会将自己创建的editText指针传递下来。
于是可以在onAddEditTextToDialogView方法中创建一个容器和父类的editText绑定:
2 ViewGroup container = (ViewGroup) dialogView
3 .findViewById(R.id.edit_container);
4
5 // add the edittext to the container.
6 if (container !=null) {
7 container.addView(editText, ViewGroup.LayoutParams.FILL_PARENT,
8 ViewGroup.LayoutParams.FILL_PARENT);
9 }
然后在布局文件中将绑定的container按照正确的方式布局即可:
2 android:id="@+id/number_field"
3 android:layout_width="fill_parent"
4 android:layout_height="0dip"
5 android:layout_weight="1.0"
6 android:addStatesFromChildren="true"
7 android:gravity="center_vertical"
8 android:baselineAligned="false"
9 android:paddingLeft="10dip"
10 android:paddingRight="10dip">
11
12 <LinearLayout android:id="@+id/edit_container"
13 android:layout_width="0dip"
14 android:layout_weight="1"
15 android:layout_height="wrap_content"/>
16
17 <ImageButton android:id="@+id/select_contact"
18 android:layout_width="wrap_content"
19 android:layout_height="fill_parent"
20 android:padding="10dip"
21 android:src="@drawable/ic_button_contacts"/>
22 </LinearLayout>
方法一相对简单,但是不能灵活调整布局,方法二需要自己实现方法将父类子控件的指针传递给子类,相对较麻烦,一般在实际开发当中都是通过两种方法结合在一起灵活使用。