Android Dialog II-dialog的操作

来源:互联网 发布:初入职场 知乎 编辑:程序博客网 时间:2024/06/05 06:15

将Dialog的数据传回给Activity:

当用户点击了dialog上的按键或者选择了一个list中的项, DialogFragment或许可以处理这些动作, 但是还有很多的情况下我们可能希望将信息传递回给打开dialog的Activity或者Fragment. 为了实现这个功能, 我们需要定义一个接口, 接口里定义所有需要实现点击操作的button的点击事件. 然后再在Activity和Fragment中实现这些方法. 比如这是一个DialogFragment:

public class NoticeDialogFragment extends DialogFragment {
   
    /* The activitythat creates an instance of this dialog fragment must
     * implement this interface in order to receive eventcallbacks.
     * Each method passes the DialogFragment in case the hostneeds to query it. */

    public interfaceNoticeDialogListener {
        public void onDialogPositiveClick(DialogFragment dialog);
        public void onDialogNegativeClick(DialogFragment dialog);
    }
   
    // Use thisinstance of the interface to deliver action events
    NoticeDialogListener mListener;
   
    // Override theFragment.onAttach() method to instantiate the NoticeDialogListener
    @Override
    public void onAttach(Activity activity){
        super.onAttach(activity);
        // Verify that the host activity implements the callback interface
        try {
            // Instantiate the NoticeDialogListener sowe can send events to the host
            mListener = (NoticeDialogListener) activity;
        } catch(ClassCastException e){
            // The activity doesn't implement theinterface, throw exception
            throw new ClassCastException(activity.toString()
                    + " must implement NoticeDialogListener");
        }
    }
    ...
}

Activity则需要创建一个dialogfragment的实例, 并通过NoticeDialogListener接口的方法来接收dialog的事件.

public class MainActivity extends FragmentActivity
                         implements NoticeDialogFragment.NoticeDialogListener{
    ...
   
    public void showNoticeDialog(){
        // Create an instance of the dialog fragment and show it
        DialogFragment dialog = new NoticeDialogFragment();
        dialog.show(getSupportFragmentManager(),"NoticeDialogFragment");
    }

    // The dialogfragment receives a reference to this Activity through the
    //Fragment.onAttach() callback, which it uses to call the following methods
    // defined bythe NoticeDialogFragment.NoticeDialogListener interface
    @Override
    public void onDialogPositiveClick(DialogFragment dialog){
        // User touched the dialog's positive button
        ...
    }

    @Override
    public void onDialogNegativeClick(DialogFragment dialog){
        // User touched the dialog's negative button
        ...
    }
}

因为Activity实现了NoticeDialogListener接口, 所以dialog fragment可以通过该接口的方法来通知Activity点击事件:

public class NoticeDialogFragment extends DialogFragment {
    ...

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState){
        // Build the dialog and set up the button click handlers
        AlertDialog.Builder builder= new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.dialog_fire_missiles)
               .setPositiveButton(R.string.fire,new DialogInterface.OnClickListener(){
                   public void onClick(DialogInterface dialog,int id) {
                      // Send thepositive button event back to the host activity
                      mListener.onDialogPositiveClick(NoticeDialogFragment.this);
                   }
               })
               .setNegativeButton(R.string.cancel,new DialogInterface.OnClickListener(){
                   public void onClick(DialogInterface dialog,int id) {
                      // Send thenegative button event back to the host activity
                      mListener.onDialogNegativeClick(NoticeDialogFragment.this);
                   }
               });
        return builder.create();
    }
}

显示一个Dialog:

当我们想要显示自己的dialog, 只需要创建一个我们的DialogFragment类, 然后调用show()方法即可. 该方法需要两个参数, 一个是FragmentManager, 第二个是为dialog fragment指定的tag name. 我们可以通过FragmentActivity的getSupportFragmentManager()方法取得FragmentManager. 也可以通过Fragment的getFragmentManager()方法, 比如:

public void confirmFireMissiles() {
    DialogFragment newFragment = new FireMissilesDialogFragment();
    newFragment.show(getSupportFragmentManager(),"missiles");
}

第二个参数”missiles”, 是一个唯一的tag name, 当Android需要保存和恢复fragment的状态的时候, 需要用到这个值. 我们还可以通过这个tag name获取到fragment, 这个比较简单啦, 就是用findFragmentByTag()方法.

 

显示一个全屏的Dialog或者一个嵌入式的Fragment:

有时候我们可能需要面对这样的情况, 我们有一个UI片段, 我们希望它既可以作为dialog出现, 还可以作为全屏或者嵌入式的Fragment出现(这样可以适应不同尺寸的屏幕). 这样我们可以最大程度的重用它们. DialogFragment为我们提供了足够的灵活性, 它还可以作为嵌入式的Fragment来使用.

但是这跟普通的用法有所区别, 我们不能使用AlertDialog.Builder或者其它的Dialog对象来创建dialog. 如果我们希望DialogFragment作为嵌入式的Fragment, 那么我们必须在在一个layout中定义它的UI, 然后再onCreateView()中加载它.

这里是一个栗子, 其中DialogFragment既可以作为dialog也可以作为一个嵌入式的Fragment(并指定了一个叫purchase_items.xml的布局文件):

public class CustomDialogFragment extends DialogFragment {
    /** The systemcalls this to get the DialogFragment's layout, regardless
        of whether it's being displayed as a dialog or anembedded fragment. */

    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container,
            Bundle savedInstanceState){
        // Inflate the layout to use as dialog or embedded fragment
        return inflater.inflate(R.layout.purchase_items, container, false);
    }
 
    /** The systemcalls this only when creating the layout in a dialog. */
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState){
        // The only reason you might override this method when usingonCreateView() is
        // to modify any dialog characteristics. For example, the dialog includesa
        // title by default, but your custom layout might not need it. So here youcan
        // remove the dialog title, but you must call the superclass to get theDialog.
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        return dialog;
    }
}

然后这里是一些决定这个类是因该作为dialog还是作为Fragment来显示的代码:

public void showDialog() {
    FragmentManager fragmentManager = getSupportFragmentManager();
    CustomDialogFragment newFragment = new CustomDialogFragment();
   
    if (mIsLargeLayout){
        // The device is using a large layout, so show the fragment as a dialog
        newFragment.show(fragmentManager,"dialog");
    } else {
        // The device is smaller, so show the fragment fullscreen
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        // For a little polish, specify a transition animation
        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        // To make it fullscreen, use the 'content' root view as the container
        // for the fragment, which is always the root view for the activity
        transaction.add(android.R.id.content, newFragment)
                   .addToBackStack(null).commit();
    }
}

上述代码中, mIsLargeLayout是一个Boolean值, 它指定了当前设备是否应该使用APP的大的layout(如果是大屏就使用dialog, 小屏就用全屏). 最好的设置该值的方法是在不同的屏幕尺寸的资源文件下定义Boolean值, 栗子:

res/values/bools.xml

<!-- Default boolean values -->
<resources>
    <bool name="large_layout">false</bool>
</resources>

res/values-large/bools.xml

<!-- Large screen boolean values -->
<resources>
    <bool name="large_layout">true</bool>
</resources>

我们可以在onCreate()方法中初始化这个值:

boolean mIsLargeLayout;

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
}

这种方法真的很cool.

在大屏幕上将Activity作为dialog显示:

有别于在小屏幕上全屏显示dialog, 有时候我们可能需要在大屏幕上作为dialog显示一个Activity. 通常在我们已经设计好了手机版的APP, 但是需要扩展到平板上的时候, 我们可以考虑这样做. 很简单, 只要对相应的Activity指定一个主题Theme.Holo.DialogWhenLarge即可, 在<activity>中:

<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge">

更多关于主题的信息可以参考这里.

 

如何让一个Dialog消失:

当我们点击通过AlertDialog.Builder创建的dialog上的任何按键的时候, Android将会自动让dialog消失. 我们还可以手动通过DialogFragment的dismiss()方法让dialog消失.

如果我们需要在dialog消失的时候执行某些操作, 可以通过onDismiss()方法来实现.

还可以通过Dialog的cancel()方法来取消一个dialog, 相当于用户点击了cancel键. 并且可以在onCancel()中实现想要的操作.

每次调用onCancel()方法的时候系统都会调用onDismiss()方法, 但是如果我们调用Dialog.dismiss()或者DialogFragment.dismiss()方法的时候, 系统却不会调用到onCancel()方法, 所以我们应该考虑在用户点击OK的时候使用dismiss().

 

总结:

使用dialog很简单, 步骤如下:

1.      在DialogFragment的onCreateDialog()方法中, 通过AlertDialog.Builder来创建一个dialog.

2.      配置dialog的title, content area, button, 或者配置其它布局.

3.      调用DialogFragment对象的show()方法显示一个dialog.

4.      调用dismiss()方法让一个dialog消失.


参考: http://developer.android.com/guide/topics/ui/dialogs.html


0 0