使用接口在Activity和Fragment之间进行通信

6
我在SO上搜索了这个问题,但是没有找到任何可以解决我的问题的东西。我的问题是,我有一个包含FrameLayout的活动,它不断地更新着不同的片段。顶部视图和底部视图将保持不变,因此它们位于活动的布局中。
正如您所看到的,底部视图有一个按钮,当点击它时,我想对FrameLayout中存在的片段进行更改。

enter image description here

我已创建一个接口

public interface ShowFormula {

    void showFormula(boolean show);

}

我将用它来在片段中实现。现在,我的MainActivity类中的主要问题是我正在尝试初始化接口,但由于获取到了类转换异常,因此无法进行。

showFormula = (ShowFormula) this;//yes i know this is wrong

我该如何初始化以便与片段通信。 主要目标是在活动中的按钮单击时在片段中切换视图。
提前致谢。

1
在片段上实现您的接口,并在片段创建时将其分配给您的接口变量。您正在反向执行它,这没有意义,因为您已经在片段中实现了接口(没关系)。但是如果您存储对此的引用,则会导致崩溃。 - Nanoc
使用接口通知您的片段按钮点击。 - Nanoc
2
你不需要使用接口来从活动中调用片段。只需保留对当前片段的引用,并调用片段中的公共方法。 - Daniel Nugent
是的,这就是我想做的,但是我在Activity中遇到了类转换异常,因为我无法初始化接口。请参考我问题中的最后一段代码片段。 :) - Swapnil Kadam
@DanielNugent 好的,我会尝试这种方法并告诉你结果。 - Swapnil Kadam
显示剩余3条评论
6个回答

19
你不需要使用接口来从Activity调用Fragment。只需保留当前Fragment的引用,然后从Activity调用Fragment中的公共方法。
如果你有多个Fragment而且不想为每个Fragment都保留一个引用,可以创建一个继承自Fragment的基类,并在基类中声明通用方法,然后在所有继承自基类Fragment中覆盖该方法实现。接着,只需保留一个基类Fragment类型的引用,并始终将其设置为当前显示的Fragment即可。

6

Activity ---> Fragment

从 Activity 到 Fragment 的通信非常简单。您真的不需要一个监听器。

假设您在 Fragment 中有一个方法 share()

public class MyFragment extends Fragment{

   public static MyFragment getInstance()
   {
       return new MyFragment();
   }

   ........

   public void share()
   {
        // do something
   }

}

如何从Activity中调用share()方法?

获取Fragment的引用并调用该方法。简单易行!

MyFragment myFragment = MyFragment.getInstance();
myFragment.share();

您可以查看完整的工作代码,用于 Fragment 与 Fragment 之间的通信。 点击此处

我试图展示一个最小的代码。getInstance()是实例化Fragment的方法。但是为了您,我已经更新了代码。 @user1804084。请查看Git存储库以获得更好的理解。 - Rohit Singh
如果你想知道我为什么以这种方式创建实例,你可以阅读这篇文章 https://dev59.com/rGox5IYBdhLWcg3wYzQt - Rohit Singh
当我从Activity调用Fragment获取Editext值时,出现了空值。请问你可以帮我吗? - Sayed Rizwan Hashmi

1

补充一下Daniel Nugent的精彩回答,这里是我工作代码中将调用从Activity委派到Fragment的片段。

我有一个MVP架构,并在BaseView类上定义了错误处理方法showError。下面的代码演示了如何在TargetFragment类上处理UI。对于任何错误情况,我需要在片段上隐藏进度旋转器。以下是基础类的代码片段:

public interface BaseView {
   void showError(ErrorResponse errorResponse);
}

public abstract class BaseActivity implements BaseView {
   @Override
   public void showError(ErrorResponse errorResponse) {
       // Check error condition or whatever
       // ...
       MaterialDialog dialog = new MaterialDialog.Builder(this)
                .title(R.string.dialog_error_title)
                .content(R.string.error_no_internet)
                .positiveText(R.string.dialog_action_ok)
                .build();
       dialog.show();
   }
}

public abstract class BaseFragment implements BaseView {
   @Override
   public void showError(ErrorResponse errorResponse) {
      ((BaseView) getActivity()).showError(errorResponse);
   }
}

而这就是我在TargetFragment类中处理UI的方式:

public final class TargetFragment extends BaseFragment implements TargetView {
   @Override
   public void showError(ErrorResponse errorResponse) {
        super.showError(errorResponse);
        hideSpinner();
        
        // Do other UI stuff
        // ...
   }

   private void hideSpinner() {
       spinner.setVisibility(View.INVISIBLE);
   }
}

0
一个简洁的解决方案:
public interface ShowFormula {
   public void showFormula(boolean show);
 }  

public class MyActivity implements ShowFormula {
   ...
   @Override
   public void showFormula(boolean show) {
     /** Your Code **/
   }
   ...
 }

public class MyFragment {
   private ShowFormula listener;
   ...
   @Override
   public void onAttach(Activity activity) {
     super.onAttach(activity);
     try {
       listener = (ShowFormula) activity;
       // listener.showFormula(show?);
     } catch (ClassCastException castException) {
       /** The activity does not implement the listener. **/
     }
   }
   ...
 }

10
这是Fragment->Activity的关系,而不是Activity->Fragment。 - Linxy

0

简单的事情是在片段中创建公共方法,然后从活动中调用它。

MyFragment fragment = new MyFragment(); fragment.doSomeThing();

doSomeThing()MyFragment 中的一个公共方法。


-2

通过接口实现Activity与Fragment之间的通信:

public class MyActivity {

   private ShowFormula showFormulaListener;

   public interface ShowFormula {
      public void showFormula(boolean show);
  }

  public void setListener(MyFragment myFragment) {
      try {
      showFormulaListener = myFragment;
      } catch(ClassCastException e) {
     }
   }
 }

public class MyFragment implements ShowFormula{

     @Override
     public void onAttach(Activity activity) {
       super.onAttach(activity);
       try {
        ((MyActivity) activity).setListener(this);
        } catch (ClassCastException e) {
        Log.e(TAG, e.toString());
    }
}
     @Override
     public void showFormula(boolean show) {
     /** Your Code **/
     }
}

设置完成后,您可以调用“showFormulaListener.showFormula(boolVal)”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接