1. 程式人生 > >android之自定義Dialog

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的效果圖如下:

對話方塊

全文結束,謝謝大家。