[置顶] 使用DialogFragment 代替 Dialog

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

源码奉上

你可能感兴趣的:(android,dialog,Fragment,对话框)