自从google在发布的3.0版本的安卓系统中引入了fragment之后,在google的官方文档中,我们会发现,官方建议我们使用DialogFragment 来代替原来的dialog,这样可以使我们的对话框具有更多的交互性,也更加符合面向对象的特性。
google官方文档原话
Honeycomb introduced Fragments to support reusing portions of UI and logic across multiple activities in an app. In parallel, the showDialog / dismissDialog methods in Activity are being deprecated in favor of DialogFragments.
(Honeycomb(蜂巢)——是安卓3.0系统的代号)
参考链接
官方文档地址:http://android-developers.blogspot.com/2012/05/using-dialogfragments.html
下面,将介绍如何用DialogFragment来代替原始的dialog.
在下面的实例中,我将使用DialogFragment来显示一个简单的编辑对话框,并且使用回调接口来调用activity。
dialog布局
在下面的布局文件中,我们仅包含一个文本提示和一个输入框。
fragment_edit_name.xml.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/edit_name"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:orientation="vertical" >
<TextView
android:id="@+id/lbl_your_name" android:text="Your name"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
<EditText
android:id="@+id/txt_your_name"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:inputType=”text”
android:imeOptions="actionDone" />
</LinearLayout>
注意EditText中的imeoOptions属性,如果对于这一属性不了解的同学可以到我以前关于这一属性的介绍http://blog.csdn.net/a253664942/article/details/45585795 中看看。
DialogFragment类
接下来实现我们的DialogFragment。编写一个EditDialog来继承DialogFragment,并且实现OnEditorActionListener接口。EditDialog跟普通的Fragment没什么太大的区别,只不过内部可以直接调用getDialog()方法来获取一个dialog实例而已。
EditDialog
public class EditDialog extends DialogFragment
implements OnEditorActionListener{
private EditText mEditText;
//自定义回调接口
public interface EditNameDialogListener {
//回调方法 当输入完成后将输入框中的内容返回给activity
void onFinishEditDialog(String inputText);
}
public EditNameDialog() {
//空构造方法 ,必须要有!
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_edit_name, container);
mEditText = (EditText) view.findViewById(R.id.txt_your_name);
getDialog().setTitle("Hello");
//获取焦点
mEditText.requestFocus();
// 自动显示软键盘
getDialog().getWindow().setSoftInputMode(
LayoutParams.SOFT_INPUT_STATE_VISIBLE);
mEditText.setOnEditorActionListener(this);
return view;
}
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
//判断ImeOptions的属性,即当按下键盘上的完成按钮时的操作
if (EditorInfo.IME_ACTION_DONE == actionId) {
// Return input text to activity
EditNameDialogListener activity = (EditNameDialogListener) getActivity();
// 调用回调函数 将输入框中的内容传递给activity
activity.onFinishEditDialog(mEditText.getText().toString());
//关闭对话框
this.dismiss();
return true;
}
return false;
}
}
出于用户的方便考虑,我们在程序中使用 mEditText.requestFocus()来使EditText获取焦点。当然,我们也可以在xml文件中使用标签来做同样的事。但是,有些情况下,在程序中获取焦点会更好。比如:如果在xml文件中使用标签来获取焦点,那么Fragment中的OnFocusChangeListener 事件将不会调用。
为了让EditText获取焦点时软键盘自动出现,我们调用getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE)方法设置软键盘自动出现。
注意,以前在Dialog中完成的许多Window窗口操作都可以在DialogFragment中完成,不过需要用
getDialog().getWindow()来代替getWindow()。
让我们来看看下面的这段代码。
当用户玩下键盘上的”完成“键时,onEditorAction()方法会被调用。在onEditorAction()方法中,我们将EditText中的内容传回给activity.为了实现此功能,我们声明了一个EditNameDialogListener接口,并在其中定义了onFinishEditDialog()方法用于当完成输入时将EditText中的内容传回给activity。
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
//判断ImeOptions的属性,即当按下键盘上的完成按钮时的操作
if (EditorInfo.IME_ACTION_DONE == actionId) {
EditNameDialogListener activity = (EditNameDialogListener) getActivity();
// 调用回调函数 将输入框中的内容传递给activity
activity.onFinishEditDialog(mEditText.getText().toString());
//关闭对话框
this.dismiss();
return true;
}
return false;
}
下面这行代码,我们将EditNameDialogListener 接口与我们的activity进行绑定。在MVC模式中,这是一种常见的方法,使View视图(我们的DialogFragment)和controller(Activity)进行通信。
EditNameDialogListener activity = (EditNameDialogListener) getActivity();
最后注意一点,EditDialog的空构造方法是必须的!!!
Activity的实现
在activity中代码就很简单了。我们让activity继承fragmentActivity并且实现我们自定义的EditNameDialogListener 接口。然后调用showEditDialog()方法显示我们的dialog.
在回调方法onFinishEditDialog中,我们直接输出输入框中返回的值。
public class FragmentDialogDemo extends FragmentActivity implements EditNameDialogListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showEditDialog();
}
private void showEditDialog() {
FragmentManager fm = getSupportFragmentManager();
EditDialog editDialog = new EditDialog();
editDialog.show(fm, "fragment_edit_name");
}
@Override
public void onFinishEditDialog(String inputText) {
Toast.makeText(this, "Hi, " + inputText, Toast.LENGTH_SHORT).show();
}
}