android之自定義Dialog
在參考了android提供的ApiDemos程式以後,這裡對如何實現自己定義的對話方塊進行一下總結。
在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
}
}
此自定義Dialog的效果圖如下:
全文結束,謝謝大家。