DialogFragment
一个片段显示一个对话窗口,漂浮在其活动的窗口之上。该片段包含一个Dialog的对象,它基于片段的状态适当地显示。应通过这里的API来控制对话框(什么时候显示,隐藏,消失),而不是直接调用对话框。
实现类应该重写这个类,并实现onCreateView(LayoutInflater,ViewGroup的,Bundle)提供对话框的内容。此外,他们可以覆盖onCreateDialog(Bundle),以创建一个完全自定义的对话框,如作为一个有自身的内容的AlertDialog。
下面讨论以下几个方面:
1.生命周期
2.基本对话框
3.警告对话框
4.在对话框和嵌入之间选择
生命周期
DialogFragment做各种事情保持片段的生命周期的驱动,而不是对话框。需要注意的是,对话框是一般自治实体 - 他们自己的窗口,接受自己的输入事件,往往决定自己何时消失(通过接收返回键的事件或用户点击一个按钮)。
DialogFragment需求确保保持片段与对话框发生的状态的一致。要做到这一点,它观察来自对话框的撤销事件,并在他们出现的时候消除其自身的状态。这意味着你应该使用show(FragmentManager,String)或show(FragmentTransaction,String)添加一DialogFragment实例到你的UI,因为这些持续跟踪着当对话框被撤销DialogFragment应该如何删除它自己。
基本对话框
简单DialogFragment的用途是作为一个片段视图层次的浮动容器。一个简单的实现可能看起来像这样:
1.主Activity:
public class FragementDialogTestActivity extends Activity {
private int mStackLevel = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_dialog);
View tv = findViewById(R.id.text);
((TextView)tv).setText("Example of displaying dialogs with a DialogFragment. "
+ "Press the show button below to see the first dialog; pressing "
+ "successive show buttons will display other dialog styles as a "
+ "stack, with dismissing or back going to the previous dialog.");
// Watch for button clicks.
Button button = (Button)findViewById(R.id.show);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
showDialog();
}
});
if (savedInstanceState != null) {
mStackLevel = savedInstanceState.getInt("level");
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("level", mStackLevel);
}
void showDialog() {
mStackLevel++;
// DialogFragment.show() will take care of adding the fragment
// in a transaction. We also want to remove any currently showing
// dialog, so make our own transaction and take care of that here.
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
// Create and show the dialog.
DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
newFragment.show(ft, "dialog");
}
}
2.主Activity布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:id="@+id/show_dialog" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="显示对话框" /> </LinearLayout>
3.对话框fragment类:
public class MyDialogFragment extends DialogFragment {
int mNum;
/**
* Create a new instance of MyDialogFragment, providing "num"
* as an argument.
*/
static MyDialogFragment newInstance(int num) {
MyDialogFragment f = new MyDialogFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments().getInt("num");
// Pick a style based on the num.
int style = DialogFragment.STYLE_NORMAL, theme = 0;
switch ((mNum-1)%6) {
case 1: style = DialogFragment.STYLE_NO_TITLE; break;
case 2: style = DialogFragment.STYLE_NO_FRAME; break;
case 3: style = DialogFragment.STYLE_NO_INPUT; break;
case 4: style = DialogFragment.STYLE_NORMAL; break;
case 5: style = DialogFragment.STYLE_NORMAL; break;
case 6: style = DialogFragment.STYLE_NO_TITLE; break;
case 7: style = DialogFragment.STYLE_NO_FRAME; break;
case 8: style = DialogFragment.STYLE_NORMAL; break;
}
switch ((mNum-1)%6) {
case 4: theme = android.R.style.Theme_Holo; break;
case 5: theme = android.R.style.Theme_Holo_Light_Dialog; break;
case 6: theme = android.R.style.Theme_Holo_Light; break;
case 7: theme = android.R.style.Theme_Holo_Light_Panel; break;
case 8: theme = android.R.style.Theme_Holo_Light; break;
}
setStyle(style, theme);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_dialog, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText("Dialog #" + mNum + ": using style "
+ getNameForNum(mNum));
// Watch for button clicks.
Button button = (Button)v.findViewById(R.id.show);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// When button is clicked, call up to owning activity.
((FragementDialogTestActivity)getActivity()).showDialog();
}
});
return v;
}
public String getNameForNum(int num) {
switch ((num-1)%6) {
case 1: return "STYLE_NO_TITLE";
case 2: return "STYLE_NO_FRAME";
case 3: return "STYLE_NO_INPUT (this window can't receive input, so "
+ "you will need to press the bottom show button)";
case 4: return "STYLE_NORMAL with dark fullscreen theme";
case 5: return "STYLE_NORMAL with light theme";
case 6: return "STYLE_NO_TITLE with light theme";
case 7: return "STYLE_NO_FRAME with light theme";
case 8: return "STYLE_NORMAL with light fullscreen theme";
}
return "STYLE_NORMAL";
}
}
4.对话框fragment的布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" /> <Button android:id="@+id/show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> </LinearLayout>
警告对话框
取代实现onCreateView(LayoutInflater,ViewGroup,Bundle)方法生成一个对话框内的视图层次,而是实现onCreateDialog(Bundle)创建自己的自定义对话框对象。
这是最有用的,创建一个AlertDialog,让您显示一个由fragment管理的标准的用户警告。一个简单的例子的实现是:
1.主Activity:
public class FragementDialogTestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.show_dialog);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
showDialog();
}
});
}
void showDialog() {
DialogFragment newFragment = MyAlertDialogFragment.newInstance("Alert Dialog");
newFragment.show(getFragmentManager(), "dialog");
}
public void doPositiveClick() {
// Do stuff here.
Log.i("FragmentAlertDialog", "Positive click!");
}
public void doNegativeClick() {
// Do stuff here.
Log.i("FragmentAlertDialog", "Negative click!");
}
}
2.主Activity布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="我的自定义警告框"/> <Button android:id="@+id/show_dialog" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="显示警告框" /> </LinearLayout>
3.我的Alert 对话框类:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="我的自定义警告框"/>
<Button
android:id="@+id/show_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="显示警告框" />
</LinearLayout>
对话和嵌入之间的选择
一个DialogFragment仍然可以使用作为一个正常的fragment,如果需要的话。如果你有一个片段,在某些情况下,应被视为一个对话框而在其他情况下嵌入在一个更大的用户界面中显示,这是非常有用的。这种行为通常会被自动为您选择,取决于你是如何使用片段的,但你也可以使用setShowsDialog(boolean)进行定制。
例如,这里是一个简单的对话片段:
public class MyDialogFragment extends DialogFragment {
static MyDialogFragment newInstance() {
return new MyDialogFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.hello_world, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText("This is an instance of MyDialogFragment");
return v;
}
}
一个fragment的实例可以被创建并被显示为一个对话框:
void showDialog() {
// Create the fragment and show it as a dialog.
DialogFragment newFragment = MyDialogFragment.newInstance();
newFragment.show(getFragmentManager(), "dialog");
}
它也可以被当做内容添加到视图层次中:
FragmentTransaction ft = getFragmentManager().beginTransaction();
DialogFragment newFragment = MyDialogFragment.newInstance();
ft.add(R.id.embedded, newFragment);
总结:
1.