android-自定義對話框視圖及參數傳遞


一、雛形構建

先給大家看下這小節的效果圖:

自定義一個對話框,內容是四個ImageView橫排;

1、Dialog布局

根據上圖的對話框樣式,我們看一下Dialog的布局定義(custom_dialog.xml)

 

[html]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.   
  3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  4.     android:id="@+id/log_in_layout"  
  5.     android:layout_width="fill_parent"  
  6.     android:layout_height="wrap_content"  
  7.     android:orientation="horizontal">  
  8.   
  9.     <ImageView  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="100dip"  
  12.         android:src="@drawable/animal1"  
  13.         android:clickable="true"  
  14.         android:layout_weight="1"/>  
  15.     <ImageView  
  16.         android:layout_width="match_parent"  
  17.         android:layout_height="100dip"  
  18.         android:src="@drawable/animal2"  
  19.         android:clickable="true"  
  20.         android:layout_weight="1"/>  
  21.     <ImageView  
  22.         android:layout_width="match_parent"  
  23.         android:layout_height="100dip"  
  24.         android:src="@drawable/animal3"  
  25.         android:clickable="true"  
  26.         android:layout_weight="1"/>  
  27.     <ImageView  
  28.         android:layout_width="match_parent"  
  29.         android:layout_height="100dip"  
  30.         android:src="@drawable/animal4"  
  31.         android:clickable="true"  
  32.         android:layout_weight="1"/>  
  33.   
  34. </LinearLayout>  

2、從Dialog派生對話框類

 

有關構造函數:
有三種構造函數,現在我這里使用重寫了兩個,這里只需要使用第一個,即傳進去context即可;

有關OnCreate()
在OnCreate()時,利用LayoutInflater獲取我們對話框的View,然后利用SetContentView指定為我們CustomDialog類的布局。
[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. public class CustomDialog extends Dialog {  
  2.     Context mContext;  
  3.     public CustomDialog (Context context){  
  4.         super(context);  
  5.         mContext = context;  
  6.     }  
  7.     public CustomDialog(Context context, int theme) {  
  8.         super(context, theme);  
  9.         mContext = context;  
  10.     }  
  11.   
  12.     @Override  
  13.     protected void onCreate(Bundle savedInstanceState) {  
  14.         super.onCreate(savedInstanceState);  
  15.   
  16.         LayoutInflater inflater = (LayoutInflater) mContext  
  17.                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  18.         View layout = inflater.inflate(R.layout.custom_dialog, null);  
  19.         this.setContentView(layout);  
  20.     }  
  21. }  

3、主函數(MainActivity)

在MainActivity中,我們寫一個Button,當用戶點擊的時候彈出我們自定義的對話框實例

MainActivity的布局:(activity_main.xml)

 

[html]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     tools:context=".MainActivity">  
  6.   
  7.     <Button  
  8.         android:id="@+id/btn_pop_dialog"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="彈出對話框"/>  
  12.   
  13. </RelativeLayout>  

代碼中的處理:(MainActivity.java)
在點擊Btn的時候,創建CustomDialog類的實例,並顯示

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. public class MainActivity extends Activity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.   
  8.         Button btn = (Button)findViewById(R.id.btn_pop_dialog);  
  9.         btn.setOnClickListener(new View.OnClickListener() {  
  10.             @Override  
  11.             public void onClick(View view) {  
  12.                 CustomDialog dialog = new  CustomDialog(MainActivity.this);  
  13.                 dialog.show();  
  14.             }  
  15.         });  
  16.     }  
  17.   
  18. }  
這部分源碼在文章最底部給出;

二、定義對話框樣式

這里再回頭看看上面彈出的對話框:

在布局中,我們只定義了一個水平布局,里面放了四個ImageView,即那四個小動物,那上面那一坨是哪來的呢(我用紅筆圈出來的那塊)?能不能去掉?這節,我們就說說有關樣式的問題。

第一個問題,只所有上面那一坨,是因為我們沒有指定對話框樣式,系統會使用默認樣式,那一坨就是標題欄。

要去掉的話,我們就需要自定義樣式。

1、自定義樣式

我們的樣式是寫在res/values文件夾下的style.xml文件中的,如圖,如果沒有style.xml,自已新建一個,位置如圖:

這里定義的樣式代碼是這樣的:

 

[html]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. <style name="dialog" parent="android:Theme.Dialog">  
  2.     <item name="android:windowFrame">@null</item>  
  3.     <item name="android:windowIsFloating">true</item>  
  4.     <item name="android:windowContentOverlay">@null</item>  
  5.     <item name="android:windowNoTitle">true</item>  
  6. </style>  

先對這幾個參數解釋一下:

 

android:windowFrame:界面對應的前景圖片;
android:windowIsFloating:表示浮在屏幕上的,如果在這里使用了,整個layout就會在 屏幕中心,相當於浮在屏幕上,所以這個只適用於dialog
android:windowContentOverlay:表示標題欄的陰影部分的樣式,使用圖片或者顏色
android:windowNoTitle:標題欄是否隱藏,這就是我們上面顯示的標題欄

有關樣式的內容很多很雜,這里有篇文章大家可以參考下《Andriod中Style/Theme原理以及Activity界面文件選取過程淺析》,有機會給大家總結一下有關樣式和主題的內容,到時再細講,這里不是本篇的重點,就不再細講了。

2、使用樣式

方法一:

這里有兩種方法來使用樣式,主要還是利用構造函數,還記得我們上面說過,對話框的兩個構造函數:

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. public class CustomDialog extends Dialog {  
  2.     Context mContext;  
  3.   
  4.     public CustomDialog(Context context) {  
  5.         super(context);  
  6.         mContext = context;  
  7.     }  
  8.   
  9.     public CustomDialog(Context context, int theme) {  
  10.         super(context, theme);  
  11.         mContext = context;  
  12.     }  
  13.   
  14.     …………  
  15. }  

看第二個就是我們的Theme樣式,所以第一種使用樣式的方法是在構造時直接將樣式傳進來,如果這樣使用,那我們在構造對話框時應該是這樣的“:

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. public class MainActivity extends Activity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.   
  8.         Button btn = (Button)findViewById(R.id.btn_pop_dialog);  
  9.         btn.setOnClickListener(new View.OnClickListener() {  
  10.             @Override  
  11.             public void onClick(View view) {  
  12.                 CustomDialog dialog = new  CustomDialog(MainActivity.this,R.style.dialog);  
  13.                 dialog.show();  
  14.             }  
  15.         });  
  16.     }  
  17. }  

即在新建CustomDialog實例時,第二個參數傳進來我們上面定義的樣式。

 

方法二:

第二種方法,就是我們在構造時,不讓別人傳樣式,只讓傳進來Context,但在內部,我們利用Super(context,theme)來指定樣式,代碼如下:

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. public class CustomDialog extends Dialog {  
  2.     Context mContext;  
  3.   
  4.     public CustomDialog(Context context) {  
  5.         super(context,R.style.dialog);  
  6.         mContext = context;  
  7.     }  
  8.   
  9.     …………  
  10. }  

這種情況一般用在我們封裝代碼時,不讓其它人在外部改變我們的樣式時使用的。
無論使用哪種方法,我們就已經指定我我們的對話框樣式,現在的效果是這樣的:

 

看到了沒,上面的標題欄沒了,下面再看看有關參數傳遞的問題

三、參數傳遞

這里涉及到兩個問題:傳進去和傳出來;

傳進去:下面有兩個按鈕,當用戶點第一個按鈕時,在對話框中顯示"From btn 1",如果用戶點擊第二個按鈕,在對話框中顯示“From btn 2”

傳出來:這四個圖片都是可以點擊的,當用戶點擊任何一個圖片,把它的ID傳出來,並設置到我們的MainActivity中;

這里為了好理解,更改了對話框的布局,將水平布局改成了垂直布局。並且在MainActiviy下面加了一個ImageView.

1、傳進去

往對話框里傳參數,一般就是利用構造函數來完成的,很簡單,即在對話框的構造函數上加上我們自己想要傳的參數,這里我們需要額外傳一個字符串,來表示從哪個BTN來的。

所以對話框的構造函數就變成了這樣:

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. public class CustomDialog extends Dialog{  
  2.     private Context mContext;  
  3.     private String mStr;  
  4.   
  5.     public CustomDialog(Context context, String str, int theme) {  
  6.         super(context, theme);  
  7.         mContext = context;  
  8.         mStr = str;  
  9.     }  
  10.   
  11.     …………  
  12. }  

在使用的時候,也很簡單:

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. Button btn2 = (Button)findViewById(R.id.btn_pop_dialog_2);  
  2. btn2.setOnClickListener(new View.OnClickListener() {  
  3.     @Override  
  4.     public void onClick(View view) {  
  5.         CustomDialog dialog = new  CustomDialog(MainActivity.this,"From btn 2",R.style.dialog);  
  6.         dialog.show();  
  7.     }  
  8. });  

直接利用構造函數傳參即可

 

 

2、傳出來

利用構造函數傳參數大家都知道,但要怎么把用戶的操作信息傳出來就不是那么簡單了,這里就要利用回調來實現了!

 

回調函數的使用主要依照下面這些步驟:

在對話框中:

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. public class CustomDialog extends Dialog {  
  2.   
  3.     // 利用interface來構造一個回調函數  
  4.     public interface ICustomDialogEventListener {  
  5.         public void customDialogEvent(int valueYouWantToSendBackToTheActivity);  
  6.     }  
  7.   
  8.     private ICustomDialogEventListener onCustomDialogEventListener;  
  9.   
  10.     // 在構造函數中,設置進去回調函數  
  11.     public CustomDialog(Context context,  
  12.                         ICustomDialogEventListener onCustomDialogEventListener) {  
  13.         super(context);  
  14.         this.onCustomDialogEventListener = onCustomDialogEventListener;  
  15.     }  
  16.   
  17.     //當你想把值傳回去的時候,調用回調函數將值設置進去  
  18.     @Override  
  19.     public void onCreate(Bundle savedInstanceState)  
  20.     {  
  21.         Button btnOk = (Button) findViewById(R.id.customDialogButton);  
  22.         btnOk.setOnClickListener( new Button.OnClickListener()  
  23.         {  
  24.             public void onClick(View v) {  
  25.                 onCustomDialogEventListener.customDialogEvent(valueYouWantToSendBackToTheActivity);  
  26.                 dismiss();  
  27.             }  
  28.         });  
  29.     }  
  30. }  

在構造對話框時:

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. final CustomDialog dialog = new CustomDialog(this, new ICustomDialogEventListener() {  
  2.     public void customDialogEvent(int value) {  
  3.         //在這里就獲取到了從對話框傳回來的值  
  4.     }  
  5. });  

大致使用流程就是這樣的,下面就把我們上面的效果利用回調函數實現出來;

 

首先在對話框中新建一個回調函數(接口),並且在對話框的構造方法中把回調函數傳進來:

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. public class CustomDialog extends Dialog implements View.OnClickListener {  
  2.   
  3.     //增加一個回調函數,用以從外部接收返回值  
  4.     public interface ICustomDialogEventListener {  
  5.         public void customDialogEvent(int id);  
  6.     }  
  7.   
  8.     private ICustomDialogEventListener mCustomDialogEventListener;  
  9.     private Context mContext;  
  10.     private String mStr;  
  11.     //把回調函數傳進來  
  12.     public CustomDialog(Context context, String str, ICustomDialogEventListener listener, int theme) {  
  13.         super(context, theme);  
  14.         mContext = context;  
  15.         mStr = str;  
  16.         mCustomDialogEventListener = listener;  
  17.     }  
  18.   
  19.     …………  
  20. }  

然后在OnCreate() 函數中設定ImageView的點擊事件,我們將CustomDialog類繼承View.OnClickListener接口,對點擊事件統一處理:

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. private void bindImageClickEvent(View layout){  
  2.     ImageView img1 = (ImageView)layout.findViewById(R.id.dialog_image1);  
  3.     ImageView img2 = (ImageView)layout.findViewById(R.id.dialog_image2);  
  4.     ImageView img3 = (ImageView)layout.findViewById(R.id.dialog_image3);  
  5.     ImageView img4 = (ImageView)layout.findViewById(R.id.dialog_image4);  
  6.     img1.setOnClickListener(this);  
  7.     img2.setOnClickListener(this);  
  8.     img3.setOnClickListener(this);  
  9.     img4.setOnClickListener(this);  
  10. }  
  11.       
  12. @Override  
  13. protected void onCreate(Bundle savedInstanceState) {  
  14.     super.onCreate(savedInstanceState);  
  15.   
  16.     LayoutInflater inflater = (LayoutInflater) mContext  
  17.             .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  18.     View layout = inflater.inflate(R.layout.custom_dialog, null);  
  19.   
  20.     TextView tv = (TextView)layout.findViewById(R.id.dialog_text);  
  21.     tv.setText(mStr);  
  22.   
  23.     bindImageClickEvent(layout);//綁定ImageView點擊事件  
  24.      
  25.     this.setContentView(layout);  
  26. }  

在OnCreate()中,首先將傳進來的String字符串設置到對話框的TextView中;然后綁定各個ImageView的點擊事件
然后 就是在OnClick中的處理:

 

主要是根據用戶當前點擊的ImageView的ID,把這個ImageView所用的圖片的DrawableID返回給MainActivity,代碼如下:

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. public void onClick(View view) {  
  2.     int id = view.getId();  
  3.     int drawableID = -1;  
  4.     switch (id){  
  5.         case R.id.dialog_image1:  
  6.             drawableID = R.drawable.animal1;  
  7.             break;  
  8.         case R.id.dialog_image2:  
  9.             drawableID = R.drawable.animal2;  
  10.             break;  
  11.         case R.id.dialog_image3:  
  12.             drawableID = R.drawable.animal3;  
  13.             break;  
  14.         case R.id.dialog_image4:  
  15.             drawableID = R.drawable.animal4;  
  16.             break;  
  17.     }  
  18.     if (drawableID != -1) {  
  19.         mCustomDialogEventListener.customDialogEvent(drawableID);  
  20.     }  
  21.     dismiss();  
  22. }  

這樣就把對話框的構造過程講完了,完整的對話框代碼是這樣的:

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. public class CustomDialog extends Dialog implements View.OnClickListener{  
  2.   
  3.     //增加一個回調函數,用以從外部接收返回值  
  4.     public interface ICustomDialogEventListener {  
  5.         public void customDialogEvent(int id);  
  6.     }  
  7.   
  8.     private ICustomDialogEventListener mCustomDialogEventListener;  
  9.     private Context mContext;  
  10.     private String mStr;  
  11.   
  12.     public CustomDialog(Context context) {  
  13.         super(context);  
  14.         mContext = context;  
  15.     }  
  16.   
  17.     public CustomDialog(Context context, String str,ICustomDialogEventListener listener,int theme) {  
  18.         super(context, theme);  
  19.         mContext = context;  
  20.         mStr = str;  
  21.         mCustomDialogEventListener = listener;  
  22.     }  
  23.     private void bindImageClickEvent(View layout){  
  24.         ImageView img1 = (ImageView)layout.findViewById(R.id.dialog_image1);  
  25.         ImageView img2 = (ImageView)layout.findViewById(R.id.dialog_image2);  
  26.         ImageView img3 = (ImageView)layout.findViewById(R.id.dialog_image3);  
  27.         ImageView img4 = (ImageView)layout.findViewById(R.id.dialog_image4);  
  28.         img1.setOnClickListener(this);  
  29.         img2.setOnClickListener(this);  
  30.         img3.setOnClickListener(this);  
  31.         img4.setOnClickListener(this);  
  32.     }  
  33.   
  34.     @Override  
  35.     protected void onCreate(Bundle savedInstanceState) {  
  36.         super.onCreate(savedInstanceState);  
  37.   
  38.         LayoutInflater inflater = (LayoutInflater) mContext  
  39.                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  40.         View layout = inflater.inflate(R.layout.custom_dialog, null);  
  41.   
  42.         TextView tv = (TextView)layout.findViewById(R.id.dialog_text);  
  43.         tv.setText(mStr);  
  44.   
  45.         bindImageClickEvent(layout);  
  46.   
  47.         this.setContentView(layout);  
  48.     }  
  49.   
  50.     @Override  
  51.     public void onClick(View view) {  
  52.         int id = view.getId();  
  53.         int drawableID = -1;  
  54.         switch (id){  
  55.             case R.id.dialog_image1:  
  56.                 drawableID = R.drawable.animal1;  
  57.                 break;  
  58.             case R.id.dialog_image2:  
  59.                 drawableID = R.drawable.animal2;  
  60.                 break;  
  61.             case R.id.dialog_image3:  
  62.                 drawableID = R.drawable.animal3;  
  63.                 break;  
  64.             case R.id.dialog_image4:  
  65.                 drawableID = R.drawable.animal4;  
  66.                 break;  
  67.         }  
  68.         if (drawableID != -1) {  
  69.             mCustomDialogEventListener.customDialogEvent(drawableID);  
  70.         }  
  71.         dismiss();  
  72.     }  
  73. }  

下面就是構造對話框的過程了:

 

在MainAcitivity中,當點擊一個按鈕時,new一個ICustomDialogEventListener實例來接收傳過來的值;

 

[java]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
  1. Button btn = (Button)findViewById(R.id.btn_pop_dialog_1);  
  2. btn.setOnClickListener(new View.OnClickListener() {  
  3.     @Override  
  4.     public void onClick(View view) {  
  5.         CustomDialog dialog = new  CustomDialog(MainActivity.this,"From btn 1",new CustomDialog.ICustomDialogEventListener() {  
  6.             @Override  
  7.             public void customDialogEvent(int id) {  
  8.                 ImageView imageView = (ImageView)findViewById(R.id.main_image);  
  9.                 imageView.setImageDrawable(getResources().getDrawable(id));  
  10.             }  
  11.         },R.style.dialog);  
  12.         dialog.show();  
  13.     }  
  14. });  

在我們收到傳過來的DrawableID時,把它設置gc主頁面ImageVIew里顯示出來,這就完成了我們上面的功能。

轉自:http://blog.csdn.net/harvic880925/article/details/42712777


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM