android 自定義對話框

前段時間,做了一個android塗鴉板項目(http://mm.10086.cn/1007/300001153536.html?fw=411130 ),在項目中,用到了一些自定義的對話框,如圖所示。

對話框

        在參考了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的效果圖如下:

對話框

全文結束,謝謝大家。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

說到對話框你肯定會想到AlertDialog.Builder。當然這次不是用AlertDialog.Builder來實現的!而是Dialog類

AlertDialog.Builder提供的方法有:
setTitle():給對話框設置title.
setIcon():給對話框設置圖標。
setMessage():設置對話框的提示信息
setItems():設置對話框要顯示的一個list,一般用於要顯示幾個命令時
setSingleChoiceItems():設置對話框顯示一個單選的List
setMultiChoiceItems():用來設置對話框顯示一系列的複選框。
setPositiveButton():給對話框添加”Yes”按鈕。
setNegativeButton():給對話框添加”No”按鈕。
那麼在Dialog類怎樣實現的呢?當然是layout啦,你可以自定義一個xml來佈置你對話框
看看例子和源碼吧
package com.hl;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
public class MyDialog extends Activity implements android.view.View.OnClickListener {
 Button btn1=null;
    Button btn2=null;
    Button btn3=null;
 @Override
  public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
         btn1=(Button)findViewById(R.id.b1);
         btn2=(Button)findViewById(R.id.b2);
         btn3=(Button)findViewById(R.id.b3);
         btn1.setOnClickListener(this);
         btn2.setOnClickListener(this);
         btn3.setOnClickListener(this);
     }
 @Override
 public void onClick(View v) {
  switch(v.getId()){
        case R.id.b1:
            break;
        case R.id.b2:
        case R.id.b3:
            new MyDialogs(this).setDisplay();
            break;
        default:
  
 }
}
class MyDialogs extends Dialog implements android.view.View.OnClickListener{
 private Button b1;
    private Window window=null;
    
    public MyDialogs(Context context){
        super(context);
    }
    public void setDisplay(){
     setContentView(R.layout.dialog);//設置對話框的佈局
     b1=(Button)findViewById(R.id.clo);
     b1.setOnClickListener(this);
     setProperty();
        setTitle("自定義對話框");//設定對話框的標題
        show();//顯示對話框   
    }
     //要顯示這個對話框,只要創建該類對象.然後調用該函數即可.
    public void setProperty(){
         window=getWindow();//   得到對話框的窗口.
         WindowManager.LayoutParams wl = window.getAttributes();
         wl.x =0;//這兩句設置了對話框的位置.0爲中間
         wl.y =180;
         wl.alpha=0.6f;//這句設置了對話框的透明度
         wl.gravity=Gravity.BOTTOM;         
         window.setAttributes(wl); 
    }
  @Override
  public void onClick(View v) {
   dismiss();//取消   
  }
  }
}

附件下載:
MyDialog.rar  40.76KB

 

自定義Android對話框的顯示位置

系統中所有對話框,默認佈局方式都是居中顯示,如果想自定義顯示位置可以考慮如下方式:

  1. ……
  2. Window mWindow = dialog.getWindow();
  3.     WindowManager.LayoutParams lp = mWindow.getAttributes();
  4.     lp.x= xxx;
  5.     lp.y= xxx;
複製代碼

缺省居中lp.x=0,lp.y=0

新座標 x小於0左移,大於0右移;y小於0上移,大於0下移

  1. @Override
  2. protected void onDestroy() {
  3. super.onDestroy();
  4. android.os.Process.killProcess(android.os.Process.myPid());
  5. }
  6.     public static String wrap(String str, int wrapLength, String newLineStr, boolean wrapLongWords) {
  7.         if (str == null) {
  8.             return null;
  9.         }
  10.         if (newLineStr == null) {
  11.             newLineStr = System.getProperty("line.separator");
  12.         }
  13.         if (wrapLength < 1) {
  14.             wrapLength = 1;
  15.         }
  16.         int inputLineLength = str.length();
  17.         int offset = 0;
  18.         StringBuffer wrappedLine = new StringBuffer(inputLineLength + 32);
  19.       
  20.         while ((inputLineLength - offset) > wrapLength) {
  21.             if (str.charAt(offset) == ' ') {
  22.                 offset++;
  23.                 continue;
  24.             }
  25.             int spaceToWrapAt = str.lastIndexOf(' ', wrapLength + offset);
  26.             if (spaceToWrapAt >= offset) {
  27.                 // normal case
  28.                 wrappedLine.append(str.substring(offset, spaceToWrapAt));
  29.                 wrappedLine.append(newLineStr);
  30.                 offset = spaceToWrapAt + 1;
  31.               
  32.             } else {
  33.                 // really long word or URL
  34.                 if (wrapLongWords) {
  35.                     // wrap really long word one line at a time
  36.                     wrappedLine.append(str.substring(offset, wrapLength + offset));
  37.                     wrappedLine.append(newLineStr);
  38.                     offset += wrapLength;
  39.                 } else {
  40.                     // do not wrap really long word, just extend beyond limit
  41.                     spaceToWrapAt = str.indexOf(' ', wrapLength + offset);
  42.                     if (spaceToWrapAt >= 0) {
  43.                         wrappedLine.append(str.substring(offset, spaceToWrapAt));
  44.                         wrappedLine.append(newLineStr);
  45.                         offset = spaceToWrapAt + 1;
  46.                     } else {
  47.                         wrappedLine.append(str.substring(offset));
  48.                         offset = inputLineLength;
  49.                     }
  50.                 }
  51.             }
  52.         }
  53.         // Whatever is left in line is short enough to just pass through
  54.         wrappedLine.append(str.substring(offset));
  55.         return wrappedLine.toString();
  56.     }

 

Android自定義對話框(Dialog)

實現的效果是:

“長按圖標可移動位置或刪除

下次不再提示

確定   取消

Acitivity

01 LayoutInflater inflater = LayoutInflater.from(this );
02              checkView = inflater.inflate(R.layout.dialog,  null);
03  
04              //實例化複選框
05              cb = (CheckBox)checkView.findViewById(R.id.cb1);
06              //對複選框設置事件監聽
07              cb.setOnCheckedChangeListener( new CheckBox.OnCheckedChangeListener(){
08                  @Override
09                  public  void  onCheckedChanged(CompoundButton arg0, boolean arg1) {
10                      if (cb.isChecked()){
11                          //設置爲不顯示提示
12                          editor.putBoolean( "showMoveTip" false );
13                      }
14                      else {
15                          //設置爲顯示提示
16                          editor.putBoolean( "showMoveTip" true );
17                      }
18                  }
19              });
20  
21              final  AlertDialog dialog= new  AlertDialog.Builder( this )
22              .setTitle( "提示" )
23              .setView(checkView)
24              .setPositiveButton( "確定" ,new  DialogInterface.OnClickListener() {
25                  @Override
26                  public  void  onClick(DialogInterface dialog, int  which) {
27                      editor.commit();
28                  }
29              })
30              .setNegativeButton( "取消" new  DialogInterface.OnClickListener() {
31                  @Override
32                  public  void  onClick(DialogInterface dialog, int  which) {
33  
34                  }
35              }).create();
36              dialog.show();

發佈了40 篇原創文章 · 獲贊 3 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章