首先,什么是Dialog.如图:
即:只占一部分屏幕的对话框.
主要用处:提醒用户,和收集用户输入信息.
Dialog类是基类.但一般不使用基类实例化对象,因为这样的目的性,功能性太弱.一般使用的子类:
1.AlertDialog
2.DatePickerDiaog,TimePickerDialog;
我们一般把它放在一个容器内使用,即DialogFragment。
好处:
1.它封装了方法,容易控制。而不是直接自己调用Dialog的方法。
2.当用户旋转屏幕时可保存当前状态并恢复。
3.管理dialog的生命周期
4.可重用ui。控制ui在大小屏幕上有不同的显示。(how?)
以下演示一个DialogFragment与AlertDialog组合的例子:
注:因为Fragment引进自3.0,所以如果兼容1.6以上,则使用support library中的DialogFragment,3.0以上则普通的DialogFragment
- 首先,创建Dialog Fragment
理论上,你可以实现多种多样的DialogFragment.利用系统自带的Dialog,或自己创建的Dialog。但,都要继承自DialogFragment,并在onCreateDialog中实例化指定的Dialog。
本例:FireMissilesDialogFragment 文件:
public class AlertDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle("DialogFragment示例"); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub // 对应操作 } }); builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub // 对应操作 } }); return builder.create(); }}
实例化并调用show()方法后如下:
但,这只是最简单的一种实现形式罢了。我们可以做的更复杂,实现DialogFragment的更多方法,包括fragment的生命周期的方法。
如果,你想让你的DialogFragment显示更精美的Dialog,那么,你所要做的是做你所能的一切去让你的Dialog更漂亮,Fragment不能让它更精美,它仅是容器。
同时,AlertDialog中有各种实现不同视图的api:设置确认取消中立等button、内容区域设置添加单选的List(RadioButtons),多选的List(CheckButtons),
普通的list,详情自行查阅api。
同样的,我们也可以创建自己的dialog布局。
简单的:
1.创建layout文件。
2.onCreateDialog中设置该layout文件为dialog的View。
例子:layout文件:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/ff" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="hello world" /> </LinearLayout>
dialog代码:
@Overridepublic Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setView( getActivity().getLayoutInflater().inflate(R.layout.dialog_mine, null)) .setTitle("TITLE") .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub // 对应操作 } }); builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub // 对应操作 } }); return builder.create();}
实例化并显示后,效果图是这样的:
结论:layout文件的布局是dialog中的中间Content位置的布局,我们在设置view后仍然可以添加title和button。
Tips:如果你想要title的布局不同,可以换一种方式:不定义title。相反,以自己的ImageView或其它来放在contentView的顶部,这样看起来就是title位置的部分了。
- 把DialogFragment中的事件传递给Activity去处理
很多时候,我们都会需要把onClick等事件传递给holdActivity去处理。常用方式为:定义一个接口,接口内有所有我们对应调用的方法。让hold Activity实现接口,在onAttach时实例化该接口的成员变量。在对应的方法中调用对应的方法。如mCallback.method1();诸如此类。
例:FragmentDialog中定义接口。
public interface NoticeDialogListener{ void onDialogPositiveClick(DialogFragment dialog); void onDialogNegativeClick(DialogFragment dialog);}private NoticeDialogListener mDialogListener;@Overridepublic void onAttach(Activity activity) { try{ mDialogListener = (NoticeDialogListener)activity; }catch(ClassCastException e){ throw new ClassCastException(activity.toString()+"must implements MyDialogFragment.NoticeDialogListener interface"); } super.onAttach(activity);}
例:activity实现接口
public class MainActivity extends ActionBarActivity implements MyDialogFragment.NoticeDialogListener{ @Override public void onDialogPositiveClick(DialogFragment dialog) { // TODO Auto-generated method stub } @Override public void onDialogNegativeClick(DialogFragment dialog) { // TODO Auto-generated method stub }
然后,在FragmentDialog中对应地方调用接口.方法();
例:FragmentDialog中接口的方法调用:
@Overridepublic Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setView( getActivity().getLayoutInflater().inflate(R.layout.dialog_mine, null)) .setTitle("TITLE") .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mDialogListener.onDialogPositiveClick(MyDialogFragment.this); } }); builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mDialogListener.onDialogNegativeClick(MyDialogFragment.this); } }); return builder.create();}
- 展示DialogFragment
很简单,实例化DialogFragment对象,而后调用DialogFragment的show()方法即可。
public void confirmFireMissiles() { DialogFragment newFragment = new FireMissilesDialogFragment(); newFragment.show(getSupportFragmentManager(), "missiles");}
FragmentManager可通过getFragmentManager或getSupportFragmentManager(继承了FragmentActivity才有这个方法)方法获取。
- 根据屏幕大小显示全屏或非全屏的DialogFragment
这对于我们产品开发的不同屏幕显示效果有很大的作用。因为小屏幕时如果也是弹出fragment的形式展示的话会太小,不利于用户的操作和阅读效果。
那么,怎么实现这种效果比较好?
答:通过判断屏幕的大小,小则通过FragmentTransition中添加fragment实现全屏,大屏则new YourDialogFragment.show(…);
判断屏幕大小的方法:
1.通过Context.getWindow()方法获取屏幕大小。感觉比较烦
2.通过在对应不同屏幕大小文件夹中定义resource文件定义boolean来判断是否屏幕小了。
如:res/values/bools.xml
<!-- Default boolean values --><resources> <bool name="large_layout">false</bool></resources>
和:res/values-large/bools.xml
<!-- Large screen boolean values --><resources> <bool name="large_layout">true</bool></resources>
然后在activity中获取资源值并分别进行对应值的操作。
---------------------------------------------------------学习自Guide---Dialogs