自从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(); } }
源码奉上