使用DialogFragment 代替 Dialog

来源:互联网 发布:cosplay软件下载 编辑:程序博客网 时间:2024/05/16 13:54

自从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();    }}

源码奉上

0 0
原创粉丝点击