国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Androd自定義對話框Dialog視圖及參數傳遞的實現方法

2019-12-12 04:05:24
字體:
來源:轉載
供稿:網友

今天給大家講講有關自定義對話框的相關內容,前面兩篇都在在利用系統提供的函數來實現對話框,但局限性太大,當我們想自己定義視圖的時候,就不能利用系統函數了,就需要我們這里的自定義對話框了,有關自定義對話框的東東,以前有寫過一篇《android之Dialog相關》,寫的不好,今天給大家重新寫一篇

一、雛形構建

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

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

1、Dialog布局

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

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:id="@+id/log_in_layout"  android:layout_width="fill_parent"  android:layout_height="wrap_content"  android:orientation="horizontal">  <ImageView   android:layout_width="match_parent"   android:layout_height="100dip"   android:src="@drawable/animal1"   android:clickable="true"   android:layout_weight="1"/>  <ImageView   android:layout_width="match_parent"   android:layout_height="100dip"   android:src="@drawable/animal2"   android:clickable="true"   android:layout_weight="1"/>  <ImageView   android:layout_width="match_parent"   android:layout_height="100dip"   android:src="@drawable/animal3"   android:clickable="true"   android:layout_weight="1"/>  <ImageView   android:layout_width="match_parent"   android:layout_height="100dip"   android:src="@drawable/animal4"   android:clickable="true"   android:layout_weight="1"/> </LinearLayout> 

2、從Dialog派生對話框類

有關構造函數:

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

有關OnCreate()

在OnCreate()時,利用LayoutInflater獲取我們對話框的View,然后利用SetContentView指定為我們CustomDialog類的布局。

public class CustomDialog extends Dialog {  Context mContext;  public CustomDialog (Context context){   super(context);   mContext = context;  }  public CustomDialog(Context context, int theme) {   super(context, theme);   mContext = context;  }  @Override  protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   LayoutInflater inflater = (LayoutInflater) mContext     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);   View layout = inflater.inflate(R.layout.custom_dialog, null);   this.setContentView(layout);  } } 

3、主函數(MainActivity)

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

MainActivity的布局:(activity_main.xml)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  android:layout_width="match_parent"  android:layout_height="match_parent"  tools:context=".MainActivity">  <Button   android:id="@+id/btn_pop_dialog"   android:layout_width="fill_parent"   android:layout_height="wrap_content"   android:text="彈出對話框"/> </RelativeLayout> 

代碼中的處理:(MainActivity.java)

在點擊Btn的時候,創建CustomDialog類的實例,并顯示

public class MainActivity extends Activity {  @Override  protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.activity_main);   Button btn = (Button)findViewById(R.id.btn_pop_dialog);   btn.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View view) {     CustomDialog dialog = new CustomDialog(MainActivity.this);     dialog.show();    }   });  } } 

這部分源碼在文章最底部給出;

二、定義對話框樣式

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

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

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

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

1、自定義樣式

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

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

<style name="dialog" parent="android:Theme.Dialog">  <item name="android:windowFrame">@null</item>  <item name="android:windowIsFloating">true</item>  <item name="android:windowContentOverlay">@null</item>  <item name="android:windowNoTitle">true</item> </style> 

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

Android:windowFrame:界面對應的前景圖片;

android:windowIsFloating:表示浮在屏幕上的,如果在這里使用了,整個layout就會在 屏幕中心,相當于浮在屏幕上,所以這個只適用于dialog

android:windowContentOverlay:表示標題欄的陰影部分的樣式,使用圖片或者顏色

android:windowNoTitle:標題欄是否隱藏,這就是我們上面顯示的標題欄

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

2、使用樣式

方法一:

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

public class CustomDialog extends Dialog {  Context mContext;  public CustomDialog(Context context) {   super(context);   mContext = context;  }  public CustomDialog(Context context, int theme) {   super(context, theme);   mContext = context;  }  ………… } 

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

public class MainActivity extends Activity {  @Override  protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.activity_main);   Button btn = (Button)findViewById(R.id.btn_pop_dialog);   btn.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View view) {     CustomDialog dialog = new CustomDialog(MainActivity.this,R.style.dialog);     dialog.show();    }   });  } } 

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

方法二:

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

public class CustomDialog extends Dialog {  Context mContext;  public CustomDialog(Context context) {   super(context,R.style.dialog);   mContext = context;  }  ………… } 

這種情況一般用在我們封裝代碼時,不讓其它人在外部改變我們的樣式時使用的。

無論使用哪種方法,我們就已經指定我我們的對話框樣式,現在的效果是這樣的:

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

三、參數傳遞

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

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

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

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

1、傳進去

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

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

public class CustomDialog extends Dialog{  private Context mContext;  private String mStr;  public CustomDialog(Context context, String str, int theme) {   super(context, theme);   mContext = context;   mStr = str;  }  ………… }

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

Button btn2 = (Button)findViewById(R.id.btn_pop_dialog_2); btn2.setOnClickListener(new View.OnClickListener() {  @Override  public void onClick(View view) {   CustomDialog dialog = new CustomDialog(MainActivity.this,"From btn 2",R.style.dialog);   dialog.show();  } }); 

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

2、傳出來

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

在對話框中:

public class CustomDialog extends Dialog {  // 利用interface來構造一個回調函數  public interface ICustomDialogEventListener {   public void customDialogEvent(int valueYouWantToSendBackToTheActivity);  }  private ICustomDialogEventListener onCustomDialogEventListener;  // 在構造函數中,設置進去回調函數  public CustomDialog(Context context,       ICustomDialogEventListener onCustomDialogEventListener) {   super(context);   this.onCustomDialogEventListener = onCustomDialogEventListener;  }  //當你想把值傳回去的時候,調用回調函數將值設置進去  @Override  public void onCreate(Bundle savedInstanceState)  {   Button btnOk = (Button) findViewById(R.id.customDialogButton);   btnOk.setOnClickListener( new Button.OnClickListener()   {    public void onClick(View v) {     onCustomDialogEventListener.customDialogEvent(valueYouWantToSendBackToTheActivity);     dismiss();    }   });  } } 

在構造對話框時:

final CustomDialog dialog = new CustomDialog(this, new ICustomDialogEventListener() {  public void customDialogEvent(int value) {   //在這里就獲取到了從對話框傳回來的值  } }); 

大致使用流程就是這樣的,下面就把我們上面的效果利用回調函數實現出來;
首先在對話框中新建一個回調函數(接口),并且在對話框的構造方法中把回調函數傳進來:

public class CustomDialog extends Dialog implements View.OnClickListener {  //增加一個回調函數,用以從外部接收返回值  public interface ICustomDialogEventListener {   public void customDialogEvent(int id);  }  private ICustomDialogEventListener mCustomDialogEventListener;  private Context mContext;  private String mStr;  //把回調函數傳進來  public CustomDialog(Context context, String str, ICustomDialogEventListener listener, int theme) {   super(context, theme);   mContext = context;   mStr = str;   mCustomDialogEventListener = listener;  }  ………… } 

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

private void bindImageClickEvent(View layout){  ImageView img1 = (ImageView)layout.findViewById(R.id.dialog_image1);  ImageView img2 = (ImageView)layout.findViewById(R.id.dialog_image2);  ImageView img3 = (ImageView)layout.findViewById(R.id.dialog_image3);  ImageView img4 = (ImageView)layout.findViewById(R.id.dialog_image4);  img1.setOnClickListener(this);  img2.setOnClickListener(this);  img3.setOnClickListener(this);  img4.setOnClickListener(this); } @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  LayoutInflater inflater = (LayoutInflater) mContext    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  View layout = inflater.inflate(R.layout.custom_dialog, null);  TextView tv = (TextView)layout.findViewById(R.id.dialog_text);  tv.setText(mStr);  bindImageClickEvent(layout);//綁定ImageView點擊事件  this.setContentView(layout); } 

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

然后 就是在OnClick中的處理:

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

public void onClick(View view) {  int id = view.getId();  int drawableID = -1;  switch (id){   case R.id.dialog_image1:    drawableID = R.drawable.animal1;    break;   case R.id.dialog_image2:    drawableID = R.drawable.animal2;    break;   case R.id.dialog_image3:    drawableID = R.drawable.animal3;    break;   case R.id.dialog_image4:    drawableID = R.drawable.animal4;    break;  }  if (drawableID != -1) {   mCustomDialogEventListener.customDialogEvent(drawableID);  }  dismiss(); } 

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

public class CustomDialog extends Dialog implements View.OnClickListener{  //增加一個回調函數,用以從外部接收返回值  public interface ICustomDialogEventListener {   public void customDialogEvent(int id);  }  private ICustomDialogEventListener mCustomDialogEventListener;  private Context mContext;  private String mStr;  public CustomDialog(Context context) {   super(context);   mContext = context;  }  public CustomDialog(Context context, String str,ICustomDialogEventListener listener,int theme) {   super(context, theme);   mContext = context;   mStr = str;   mCustomDialogEventListener = listener;  }  private void bindImageClickEvent(View layout){   ImageView img1 = (ImageView)layout.findViewById(R.id.dialog_image1);   ImageView img2 = (ImageView)layout.findViewById(R.id.dialog_image2);   ImageView img3 = (ImageView)layout.findViewById(R.id.dialog_image3);   ImageView img4 = (ImageView)layout.findViewById(R.id.dialog_image4);   img1.setOnClickListener(this);   img2.setOnClickListener(this);   img3.setOnClickListener(this);   img4.setOnClickListener(this);  }  @Override  protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   LayoutInflater inflater = (LayoutInflater) mContext     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);   View layout = inflater.inflate(R.layout.custom_dialog, null);   TextView tv = (TextView)layout.findViewById(R.id.dialog_text);   tv.setText(mStr);   bindImageClickEvent(layout);   this.setContentView(layout);  }  @Override  public void onClick(View view) {   int id = view.getId();   int drawableID = -1;   switch (id){    case R.id.dialog_image1:     drawableID = R.drawable.animal1;     break;    case R.id.dialog_image2:     drawableID = R.drawable.animal2;     break;    case R.id.dialog_image3:     drawableID = R.drawable.animal3;     break;    case R.id.dialog_image4:     drawableID = R.drawable.animal4;     break;   }   if (drawableID != -1) {    mCustomDialogEventListener.customDialogEvent(drawableID);   }   dismiss();  } } 

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

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

Button btn = (Button)findViewById(R.id.btn_pop_dialog_1); btn.setOnClickListener(new View.OnClickListener() {  @Override  public void onClick(View view) {   CustomDialog dialog = new CustomDialog(MainActivity.this,"From btn 1",new CustomDialog.ICustomDialogEventListener() {    @Override    public void customDialogEvent(int id) {     ImageView imageView = (ImageView)findViewById(R.id.main_image);     imageView.setImageDrawable(getResources().getDrawable(id));    }   },R.style.dialog);   dialog.show();  } }); 

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

好了,本文就到這里了,有關對話框的東東基本上都講完了,一般還是我們自定義對話框的時間比較多,所以這里講的

主站蜘蛛池模板: 和平区| 龙南县| 芮城县| 边坝县| 峡江县| 菏泽市| 弥勒县| 海盐县| 雷波县| 莎车县| 清徐县| 广水市| 沂源县| 本溪市| 芮城县| 会泽县| 宁乡县| 芜湖县| 西乌珠穆沁旗| 盘山县| 勐海县| 杨浦区| 车致| 江陵县| 枞阳县| 炎陵县| 民和| 井研县| 轮台县| 宜君县| 盈江县| 丰原市| 尼勒克县| 夹江县| 巩义市| 宣化县| 长葛市| 永仁县| 伊宁县| 疏勒县| 双流县|