管理DialogFragment的活动

时间:2012-11-12 03:43:09

标签: android android-dialogfragment

如何从创建它的活动中的DialogFragment调用finish()和其他非静态方法?我试过从DialogFragment中的OnClickLisener传递消息,但没有用。

我有一个非常简单的应用程序,包含MainActivity和DialogFragment:

    public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle arg0) {
    super.onCreate(arg0);
    setContentView(R.layout.activity);
    showDialog();
}
public void showDialog() {
    DialogFragment newFragment = new ConfirmDialog();
    newFragment.show(getFragmentManager(), "dialog");
}

} 对话再次非常简单:

public class ConfirmDialog extends DialogFragment {
@Override
public AlertDialog onCreateDialog(Bundle savedInstanceState) {
    // Use the Builder class for convenient dialog construction
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setMessage("Confirm you want to continue?")
           .setPositiveButton("Yes.", new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   //finish() MainActvity
                  }
               })
           .setNegativeButton("No.", new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                 //Do nothing in MainActity
               }
           });
    // Create the AlertDialog object and return it
    return builder.create();
}

}

4 个答案:

答案 0 :(得分:28)

有很多选择。其中一个是定义一个内部有单个方法的接口。

  1. 让对话框调用者实现该接口。
  2. 保持一个指向调用者的全局变量。
  3. onAttach(Activity activity)方法中设置变量。
  4. onDetach()方法中取消该变量。
  5. 调用onClick
  6. 中的变量(接口成员)方法

    示例:

    public class MainActivity extends Activity implements MyInterface { 
        // ...
    
        @Override
        public void onChoose() { finish(); }
    
    }
    

    ConfirmDialog内:

    public static interface MyInterface {
        public void onChoose();
    }
    
    private MyInterface mListener;
    
    @Override
    public void onAttach(Activity activity) {
        mListener = (MyInterface) activity;
        super.onAttach(activity);
    }
    
    @Override
    public void onDetach() {
        mListener = null;
        super.onDetach();
    }
    

    然后在课堂内的任何地方拨打mListener.onChoose()


    我知道这已被标记为已被接受,但我认为我可以为讨论提供更多反馈。

    关于使用或不是接口的说明。 Andy的回答就像一样,因此为什么我说“有很多选择。其中一个是......”

    然而,我更喜欢这个特定问题的接口的原因是因为大多数时候你要扩展和重用这样的简单/通用确认对话框。嘿太通用了,不会被“浪费”(或者更糟糕的是:如果出现不同的事件行为,就会重复)。

    除非你确定只打算使用一次,为了一个目的(完成),否则你通常应该避免在对话类中硬连接(并简化)Activity的实现细节。 灵活性,抽象性和效率。维护的代码更少。

    是的,有一个告密你可能需要:你正在使用的public关键字,特别是如果它在一个自包含的类文件中,它需要重用(也)。否则,您应该将该类隐藏在主Activity中,因为实现细节(仅)将与该类相关。此外,您将删除public关键字。

    是的,您可以使用多个Activity,但您只能使用finish()。界面将使您可以灵活地在每个Activity中执行任何操作。换句话说,由实现者来定义它本身应该如何处理该事件。您自己包含实现细节。

    作为旁注,我所做的是创建一个包含我应用程序可能需要的所有对话框的包。对于这样的确认对话框,我重复使用不同的消息和按钮。我提供默认值,但也允许使用setArguments进行更改。我保持接口相关,所以我不需要为每个对话框创建一个接口。实现者根据哪个对话框触发“对话框回调”来响应。灵活性,抽象性和效率,同时避免幽默地称为Hydra and Royal Family。所以。最后,就像我说的,很多选择。不要过度工程,但不要过早简化(为优雅扩展留出空间)。

    理解优势和陷阱比选择这个或其他答案更重要。

答案 1 :(得分:21)

即使创建界面所涉及的工作量很小,我也不明白为什么你需要从创建它的Activity中调用finish()。从DialogFragment本身调用finish()就足够了。如果由于某种原因需要使用它发回信息,您可以随时调用getActivity()并链接活动中存在的方法。最终无论你在哪里结束,它都会分离碎片并将其摧毁。

只是为了澄清如何从你的片段中的Activity中调用一个方法

((YourActivity)getActivity()).someMethod(param);

你必须加强它,因为Java不知道Activity有你想要的任何方法。你决定选择哪种方式,祝你好运:)

欢呼声

修改

我感谢你澄清大卫。一般来说,你是对的。但说实话,在这种情况下,由于Fragments的性质及其与Activity的关系,你是不正确的。同样,您将基本上创建一个侦听器,以便由Fragment调用,该片段与它所持有的Activity类已经具有非常密切的关系。 在这种情况下,通过听众无需通过硬连接提供任何好处。您仍将为每个Dialog重写自定义代码。在我的方法中,你可以用一般的方式在Activity类中编写一个方法,你只需要编写一次。

我认为需要使用Listener的原因只有两个:

1。如果您正在编写其他人将使用的代码。所以你提供了一种简单的方法来提供信息,同时保持一定的结构(如Androids DatePickerDialog)。

2. 如果您尝试保持连接的两个部分之间没有连接(如Java中的GUI)。

所以我并不想说大卫说这个是错的,我很感激他提出这个问题,因为人们了解何时使用它们非常重要。但同样,在这种情况下,由于Fragments和Activity类之间的联系,他提到的好处是不存在的。只是想澄清为什么我认为听众在这里没有必要。

答案 2 :(得分:0)

这可能不是最好的方法,但它确实有效。在创建引用您的Activity时,然后创建一个调用startActivity并完成的静态方法,并在对话框中调用此静态方法(如果它是“ok”)。代码如下:

private static Activity mActivity = null;
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mActivity = this;
}

public static void staticMethodToCall(){
         Intent intent = new Intent(mActivity,Second.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         mActivity.startActivity(intent);
         mActivity.finish();
    }

在对话框中

 builder.setMessage("Confirm you want to continue?")
           .setPositiveButton("Yes.", new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {

                   TheClassWithTheStaticMetod.staticMethodToCall();
                  }
               })

答案 3 :(得分:0)

而不是:

.setPositiveButton("Yes.", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int id) { 
        //finish() MainActvity
    }
})

使用:

.setPositiveButton("Yes.", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int id) { 
        // this gets the current activity.              
        Activity currentActivity = getActivity();
        // this finish() method ends the current activity.
        currentActivity.finish(); 
    }
})