【问题标题】:Managing activity from DialogFragment从 DialogFragment 管理活动
【发布时间】:2018-11-13 04:12:17
【问题描述】:

如何在创建它的活动中从 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");
}

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

}

【问题讨论】:

    标签: android android-dialogfragment


    【解决方案1】:

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

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

    例子:

    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()


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

    关于使用或接口的说明。安迪的回答和我的一样正确,因此我说“有很多选择。其中之一是......”

    但是,我之所以更喜欢使用接口来解决这个特定问题,是因为大多数时候您要扩展和重用类似的简单/常见确认对话框。嘿,太笼统了,不会被“浪费”(或更糟的是:如果出现不同的事件动作,就会重复)。

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

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

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

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

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

    【讨论】:

    • 谢谢你的帮助,伙计。我尝试了这两种解决方案,但这一种效果非常好。你是对的 - 这只是一个小测试应用程序,在我的真实应用程序中我计划一次又一次地使用它,所以我认为接口是正确的解决方案。
    • 添加了一个编辑来阐明为什么我提到在这种情况下使用监听器是不必要的。无论如何,任何一种方式都很好,你不会被其他开发者责骂 Hennaz :)
    【解决方案2】:

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

    只是为了阐明如何从 Fragment 中的 Activity 调用方法

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

    您必须强制转换它,因为 Java 不知道 Activity 有您想要调用的任何方法。无论您决定采用哪种方式,祝您好运:)

    干杯

    编辑

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

    我认为需要使用监听器的原因只有两个:

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

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

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

    【讨论】:

    • +1 表示“已经与它所持有的 Activity 类有极其密切关系的 Fragment
    【解决方案3】:

    代替:

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

    【讨论】:

      猜你喜欢
      • 2012-07-27
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 2016-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多