转自:http://www.eoeandroid.com/forum-viewthread-tid-70061-fromuid-106432.html 2011-04-20 13:58:30
一、如何实现自己定义的对话框
在android的ApiDemos中的com.example.android.apis.graphics包下,有一个ColorPickerDialog类,是经典的自定义对话框的例子,我们在去除一些代码,剩下的主框架代码如下(代码中的注释详细注明每个类和方法的用途):
public class ColorPickerDialog extends Dialog { /** * 监听接口,通过此接口,可以把自定义Dialog需要向外界传递的信息,传递出去 */ public interface OnColorChangedListener { void colorChanged(int color); } /** * 需要在对话框(ColorPickerDialog)上呈现的视图,我们自定义对话框的工作,主要就是构造出一个这样的视图 */ private static class ColorPickerView extends View { private OnColorChangedListener mListener; /** * ColorPickerView的构造函数,可以在这个构造函数里用android自带的控件,比如说LinearLayout、EditText和SeekBar等,把ColorPickerView构造出来。 * 也可以在onDraw(Canvas canvas)函数中,把ColorPickerView给绘制出来,ColorPickerView采用的就是这种方法。 */ ColorPickerView(Context c, OnColorChangedListener l, int color) { super(c); } /** * 在这个函数里把ColorPickerView给绘制出来 * @param canvas */ @Override protected void onDraw(Canvas canvas) { } /** * 通过此方法来设置ColorPickerView的宽度和高度 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(CENTER_X*2, CENTER_Y*2); } /** * 在这个函数里,调用监听接口OnColorChangedListener的方法,把此自定义Dialog需要向外界传递的信息设置进去 */ @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_UP: mListener.colorChanged(mCenterPaint.getColor());//这条语句调用了监听接口的方法,把信息设置了进去 } return true; } } /** * 自定义对话框的构造方法 */ public ColorPickerDialog(Context context, OnColorChangedListener listener, int initialColor) { } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); OnColorChangedListener l = new OnColorChangedListener() { public void colorChanged(int color) { mListener.colorChanged(color); dismiss(); } }; /** * 只要通过ColorPickerDialog的setContentView方法,即可把我们辛苦绘制的ColorPickerView视图在对话框上呈现出来。 */ setContentView(new ColorPickerView(getContext(), l, mInitialColor)); setTitle("Pick a Color");//这条语句设置对话框的标题 } }
二、创建自定义Dialog的关键只有两个步骤:
1.创建一个需要在自定义Dialog显示的自定义View,创建这个自定义View时,既可以在这个View的构造方法中用android自带的控件把自定义View构造出来;也可以在自定义View的@Override protected void onDraw(Canvas canvas)方法中,把自定义View绘制出来
2.在自定义Dialog的@Override protected void onCreate(Bundle savedInstanceState)方法中,通过setContentView(自定义View);方法,把我们的自定义View显示出来
在创建好自定义Dialog后,我们在别的类中,只要调用自定义Dialog的构造函数就可以把自定义Dialog显示出来。对于ColorPickerDialog这个类,调用语句如下:new ColorPickerDialog(getContext(), listener, mPaint.getColor()).show();
下面提供一个在自定义View的构造函数中把View构造出来的例子:
/** * 文字对话框 */ public class TextDialog extends Dialog implements SeekBar.OnSeekBarChangeListener{ private LinearLayout linearLayout; private EditText etForText; private SeekBar seekBar; private TextView tvForSeekBar; private Button btnOk; private Button btnCancel; private LinearLayout topChildLinearLayout; private LinearLayout bottomChildLinearLayout; private OnTextInputListener mListener; /** * 文字对话框标题 */ private String title = "请输入文字与选择文字大小"; public interface OnTextInputListener { void textInput(String text, int textSize); } public TextDialog(Context context, OnTextInputListener listener) { super(context); mListener = listener; linearLayout = new LinearLayout(getContext()); linearLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); linearLayout.setOrientation(LinearLayout.VERTICAL); linearLayout.setGravity(Gravity.CENTER); etForText = new EditText(context); etForText.setMinLines(5);//设置最大行数 seekBar = new SeekBar(context); seekBar.setLayoutParams(new LinearLayout.LayoutParams(200, LayoutParams.FILL_PARENT)); seekBar.setMax(100); seekBar.setProgress(50); seekBar.setOnSeekBarChangeListener(this); tvForSeekBar = new TextView(context); tvForSeekBar.setText("50"); btnOk = new Button(getContext()); btnOk.setText("确定"); btnCancel = new Button(getContext()); btnCancel.setText("取消"); linearLayout.addView(etForText); topChildLinearLayout = new LinearLayout(getContext()); topChildLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); topChildLinearLayout.setOrientation(LinearLayout.HORIZONTAL); topChildLinearLayout.addView(seekBar); topChildLinearLayout.addView(tvForSeekBar); linearLayout.addView(topChildLinearLayout); bottomChildLinearLayout = new LinearLayout(getContext()); bottomChildLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); bottomChildLinearLayout.setOrientation(LinearLayout.HORIZONTAL); bottomChildLinearLayout.setGravity(Gravity.CENTER); bottomChildLinearLayout.addView(btnOk); bottomChildLinearLayout.addView(btnCancel); linearLayout.addView(bottomChildLinearLayout); btnOk.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub //验证text是否为空 String text = etForText.getText().toString()/*.replace("/n", "")*/; if(text == null || text.trim().equals("")) { Toast.makeText(getContext(), "文字不能为空", Toast.LENGTH_SHORT).show(); return; } int textSizeInt = Integer.valueOf(tvForSeekBar.getText().toString()); mListener.textInput(text, textSizeInt); dismissDialog(); } }); btnCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub dismissDialog(); } }); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(linearLayout); setTitle(title); } public void dismissDialog() { this.dismiss(); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // TODO Auto-generated method stub tvForSeekBar.setText(progress + ""); } @Override public void onStartTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } @Override public void onStopTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } }