android 使用DialogFragment 自定义Dialog

时间:2022-12-26 13:09:37

这是个展示dialog窗口的fragment。这个fragment包含了一个Dialog对象,它的展示是基于fragment的状态。控制dialog(决定要show,hide,dismiss等)应该通过dialogfragment的api而不是dialog的

实现这个类需要通过override方法onCreateView(LayoutInflater, ViewGroup, Bundle)来填充dialog的内容。另外,可以override方法onCreateDialog(Bundle)来创建一个完全自定义的dialog。


生命周期:

DialogFragment做了很多事情来控制fragment的生命周期,而不是dialog的。注意dialog是完全自主的,它有自己的window,接收自己的输入事件,经常自己决定什么时候消失(通过back键或者用户点击dialog上的button)。

DialogFragment需要保证Fragment和Dialog的状态保持一致。它监听dialog的dissmiss event,并且去处理自己的状态。这意味着应该调用 show(FragmentManager, String)或者show(FragmentTransaction, String)来添加一个DialogFragment的实例给UI层,并且它自主将remove当dialog消失的时候。


DialogFragment说到底还是个fragment,它爹能干的事情它也都能做,所以也可以是 通过ft.addToBackStack(null)压倒栈中,通过back键逐个resume,也可以被嵌套到更大层的UI中。

下面是个简单的dialog fragment:

[java] view plaincopyprint?
  1. public static class MyDialogFragment extends DialogFragment {  
  2.     static MyDialogFragment newInstance() {  
  3.         return new MyDialogFragment();  
  4.     }  
  5.   
  6.     @Override  
  7.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  8.             Bundle savedInstanceState) {  
  9.         View v = inflater.inflate(R.layout.hello_world, container, false);  
  10.         View tv = v.findViewById(R.id.text);  
  11.         ((TextView)tv).setText("This is an instance of MyDialogFragment");  
  12.         return v;  
  13.     }  
  14. }  

下面是按照dialog形式来显示:

[java] view plaincopyprint?
  1. void showDialog() {  
  2.     // Create the fragment and show it as a dialog.  
  3.     DialogFragment newFragment = MyDialogFragment.newInstance();  
  4.     newFragment.show(getFragmentManager(), "dialog");  
  5. }  


下面是添加到另一个view布局中

[java] view plaincopyprint?
  1. FragmentTransaction ft = getFragmentManager().beginTransaction();  
  2. DialogFragment newFragment = MyDialogFragment.newInstance();  
  3. ft.add(R.id.embedded, newFragment);  
  4. ft.commit();  


看了百度新闻的dialog和自身UI框架是挺一致的。下面是根据它的样式的模拟的代码。

先看看style

[html] view plaincopyprint?
  1. <style name="DialogStyle" parent="@android:style/Theme.Dialog">  
  2.         <item name="android:windowBackground">@drawable/settings_window</item>  
  3.         <item name="android:windowFrame">@null</item>  
  4.         <item name="android:windowNoTitle">true</item>  
  5.         <item name="android:windowIsFloating">true</item>  
  6.         <item name="android:windowIsTranslucent">true</item>  
  7.         <item name="android:background">@android:color/background_light</item>  
  8.         <item name="android:windowFullscreen">true</item>  
  9.         <item name="android:backgroundDimEnabled">true</item>  
  10.     </style>  


Style:是一个包含一种或者多种格式化属性的集合,我们可以将其用为一个单位用在布局XML单个元素当中。比如,我们可以定义一种风格来定义文本的字号大小和颜色,然后将其用在View元素的一个特定的实例。
Theme:是一个包含一种或者多种格式化属性的集合,我们可以将其为一个单位用在应用中所有的Activity当中或者应用中的某个Activity当 中。比如,我们可以定义一个Theme,它为window frame和panel 的前景和背景定义了一组颜色,并为菜单定义可文字的大小和颜色属性,可以将这个Theme应用在你程序当中所有的Activity里。

定义Style和Theme我觉得主要是可重用性


dialog的自定义的view

[html] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="300.0dip"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <TextView  
  8.         android:id="@+id/title_text_view"  
  9.         android:layout_width="300.0dip"  
  10.         android:layout_height="wrap_content"  
  11.         android:layout_gravity="center_horizontal"  
  12.         android:layout_marginBottom="10.0dip"  
  13.         android:layout_marginTop="20.0dip"  
  14.         android:gravity="center_horizontal"  
  15.         android:text="@string/dialog_default_title"  
  16.         android:textColor="@color/dialog_title_text_color"  
  17.         android:textSize="16.0sp" />  
  18.   
  19.     <TextView  
  20.         android:id="@+id/content_text_view"  
  21.         android:layout_width="fill_parent"  
  22.         android:layout_height="wrap_content"  
  23.         android:layout_gravity="center_horizontal"  
  24.         android:layout_marginBottom="20.0dip"  
  25.         android:layout_marginLeft="15.0dip"  
  26.         android:layout_marginRight="15.0dip"  
  27.         android:gravity="left"  
  28.         android:text="@string/dialog_latest_prompt"  
  29.         android:textColor="@color/dialog_content_text_color"  
  30.         android:textSize="16.0sp" />  
  31.   
  32.     <View  
  33.         android:layout_width="300.0dip"  
  34.         android:layout_height="1.0dip"  
  35.         android:background="#ffdddddd" />  
  36.   
  37.     <LinearLayout  
  38.         android:id="@+id/option_bar"  
  39.         android:layout_width="fill_parent"  
  40.         android:layout_height="wrap_content"  
  41.         android:background="@color/dialog_btn_bg_color"  
  42.         android:orientation="horizontal" >  
  43.   
  44.         <TextView  
  45.             android:id="@+id/dialog_ok"  
  46.             android:layout_width="0.0dip"  
  47.             android:layout_height="wrap_content"  
  48.             android:layout_weight="1.0"  
  49.             android:background="@drawable/dialog_btn_selector"  
  50.             android:gravity="center"  
  51.             android:paddingBottom="14.0dip"  
  52.             android:paddingTop="14.0dip"  
  53.             android:text="@string/dialog_ok"  
  54.             android:textColor="@color/dialog_content_text_color"  
  55.             android:textSize="18.0sp" />  
  56.   
  57.         <View  
  58.             android:layout_width="1.0dip"  
  59.             android:layout_height="fill_parent"  
  60.             android:background="#ffdddddd" />  
  61.   
  62.         <TextView  
  63.             android:id="@+id/dialog_cancel"  
  64.             android:layout_width="0.0dip"  
  65.             android:layout_height="wrap_content"  
  66.             android:layout_weight="1.0"  
  67.             android:background="@drawable/dialog_btn_selector"  
  68.             android:gravity="center"  
  69.             android:paddingBottom="14.0dip"  
  70.             android:paddingTop="14.0dip"  
  71.             android:text="@string/dialog_cancel"  
  72.             android:textColor="@color/dialog_content_text_color"  
  73.             android:textSize="18.0sp" />  
  74.     </LinearLayout>  
  75.   
  76.     <TextView  
  77.         android:id="@+id/ok_text_view"  
  78.         android:layout_width="fill_parent"  
  79.         android:layout_height="wrap_content"  
  80.         android:background="@drawable/dialog_btn_selector"  
  81.         android:gravity="center"  
  82.         android:paddingBottom="14.0dip"  
  83.         android:paddingTop="14.0dip"  
  84.         android:text="@string/dialog_ok_label"  
  85.         android:textColor="@color/dialog_content_text_color"  
  86.         android:textSize="18.0sp"  
  87.         android:visibility="gone" />  
  88.   
  89. </LinearLayout>  


DialogFragment

[java] view plaincopyprint?
  1. public static class CustomDialogFragment extends DialogFragment{  
  2.    
  3.  public static interface DialogClickListener{  
  4.   public void doPositiveClick();  
  5.   public void doNegativeClick();  
  6.  }  
  7.    
  8.  static DialogClickListener mListener;  
  9.    
  10.  public CustomDialogFragment(){  
  11.    
  12.  }  
  13.    
  14.  public static CustomDialogFragment newInstance(String title, String message, DialogClickListener listener){  
  15.   CustomDialogFragment frag = new CustomDialogFragment();  
  16.   Bundle b = new Bundle();  
  17.   b.putString("title", title);  
  18.   b.putString("message", message);  
  19.   frag.setArguments(b);         
  20.   mListener = listener;  
  21.     
  22.   return frag;  
  23.  }  
  24.    
  25.    
  26.     @Override  
  27. public Dialog onCreateDialog(Bundle savedInstanceState) {  
  28.     final Dialog dialog = new Dialog(getActivity(), R.style.DialogStyle);  
  29.   
  30.     LayoutInflater inflater = (LayoutInflater) getActivity()  
  31.             .getSystemService(LAYOUT_INFLATER_SERVICE);  
  32.     View view = inflater.inflate(R.layout.dialog_layout, nullfalse);  
  33.   
  34.     String title = getArguments().getString("title");  
  35.     String message = getArguments().getString("message");  
  36.     if (title != null && title.length() > 0) {  
  37.         TextView t = (TextView) view.findViewById(R.id.title_text_view);  
  38.         t.setText(title);  
  39.     }  
  40.   
  41.     if (message != null && message.length() > 0) {  
  42.         TextView m = (TextView) view  
  43.                 .findViewById(R.id.content_text_view);  
  44.         m.setText(message);  
  45.     }  
  46.   
  47.     View ok = view.findViewById(R.id.dialog_ok);  
  48.     View cancel = view.findViewById(R.id.dialog_cancel);  
  49.   
  50.     ok.setOnClickListener(new OnClickListener() {  
  51.   
  52.         @Override  
  53.         public void onClick(View v) {  
  54.             dialog.dismiss();  
  55.             if (mListener != null) {  
  56.                 mListener.doPositiveClick();  
  57.             }  
  58.   
  59.         }  
  60.   
  61.     });  
  62.   
  63.     cancel.setOnClickListener(new OnClickListener() {  
  64.   
  65.         @Override  
  66.         public void onClick(View v) {  
  67.             dialog.dismiss();  
  68.             if (mListener != null) {  
  69.                 mListener.doNegativeClick();  
  70.             }  
  71.         }  
  72.   
  73.     });  
  74.   
  75.     dialog.setContentView(view);  
  76.   
  77.     return dialog;  
  78. }  
  79. }  



 

在合适的实际调用showDialog

[java] view plaincopyprint?
  1. CustomDialogFragment newFragment = CustomDialogFragment.newInstance("title""message"null);  
  2.    newFragment.show(getSupportFragmentManager(), "dialog");