首页 文章

Android MVP - 如何在活动演示者和片段演示者之间进行通信

提问于
浏览
23

我有一个包含3个片段的活动,目前我使用的是ViewPager . 我想实现MVP并在活动演示者和片段演示者之间进行通信,即:

  • 将数据从活动演示者传递到片段演示者

  • 从片段演示者向活动演示者发送事件

  • ......

但我不知道如何以官方方式做到这一点 . 我可以使用BusEvent,但我认为这不是一个好习惯 .

5 回答

  • 0

    根据我的理解,对于你的UseCase,假设ActivityA有一个viewPager有3个片段(FragmentA,FragmentB,FragmentC) .

    ActivityA有ActivityPresenterA

    FragmentA有FragmentPresenterA

    根据MVP,FragmentPresenterA应仅负责FragmentA的所有逻辑和业务流,并且只应与FragmentA通信 . 因此,FragmentPresenterA无法直接与ActivityPresenterA通信 .

    对于从Fragment到Activity的通信,不应该介绍演示者,这应该像我们在非MVP架构中进行通信一样,即在界面的帮助下进行 .

    同样适用于活动到片段通信 .

    对于Activity和Fragment之间的通信,请阅读here

  • 0

    您可以为该案例使用一个演示者 .

    使用Activity Presenter获取片段所需的所有数据 . 然后创建一个接口类并将其实现到您的片段 .

    For example:

    PageAFragment 创建公共接口(此接口将是从活动到片段的数据桥) . 并使用您的界面方法处理演示者要查看的结果 .

    这是我为接收的数据创建的接口类的示例 . 对于参数,你可以选择你想要的东西,这取决于你的需要,但对我来说,我选择模型 .

    public interface CallbackReceivedData {
        void onDataReceived(YourModel model);
    }
    

    MainActivity Class 中,检查附加到您的活动中的片段实例 . 在提交片段后放置检查实例 .

    public class MainActivity extends AppCompatActivity{
    
      private CallbackReceivedData callbackReceivedData;
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
    
          //after commit the fragment
        if (fragment instanceof PageAFragment){
                callbackReceivedData = (CallbackReceivedData)fragment;
        }
    
      }
      //this is the example method of MainActivity Presenter, 
      //Imagine it, as your view method.
      public void receivedDataFromPresenter(YourModel model){
          callbackReceivedData.onDataReceived(model);
      }
    
    }
    

    我假设 receivedDataFromPresenter 是我们视图的接收方法并将数据提供给演示者 .

    现在我们将把演示者的数据传递给 callbackReceivedData

    PageAFragment 中实现 CallbackReceivedData 并覆盖 onDataReceived 方法 . 现在,您可以将活动中的数据传递给片段 .

    public class PageAFragment extends Fragment implements CallbackReceivedData{
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
        }
    
        @Override
        public void onDataReceived(YourModel model) {
    
        }
    }
    

    Note: Alternative way, you can use Bundle and pass the data with the use of setArguments.

    如果你想从 Fragment to Activity 发送活动,你可以按照这个想法 .

    创建一个Interface类并将其实现到MainActivity并覆盖从接口到活动的方法,对于我的情况,我这样做 .

    这是我的 CallbackSendData Class .

    public interface CallbackSendData {
        void sendDataEvent(String event);
    }
    

    实现 CallbackSendData 接口 CallbackSendData 并覆盖 sendDataEvent 方法 .

    public class MainActivity extends AppCompatActivity implements CallbackSendData{
    
      private CallbackReceivedData callbackReceivedData;
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
    
         //after commit the fragment
         if (fragment instanceof PageAFragment){
             callbackReceivedData = (CallbackReceivedData)fragment;
         }
    
      }
    
      //this is the example method of MainActivity Presenter, 
      //Imagine it, as your view method.
      public void receivedDataFromPresenter(YourModel model){
          callbackReceivedData.onDataReceived(model);
      }    
    
    
      @Override
      public void sendDataEvent(String event){
         //You can now send the data to your presenter here.
      }
    
    
    
    }
    

    对于你的 PageAFragment ,你需要使用attach方法来转换你的界面 . 一旦片段与其活动相关联,就调用attach方法 . 如果您想了解片段的生命周期,请单击此链接:https://developer.android.com/reference/android/app/Fragment.html .

    public class PageAFragment extends Fragment implements CallbackReceivedData{
    
        private CallbackSendData callbackSendData;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
    
        }
    
        @Override
        public void onDataReceived(YourModel model) {
            //Received the data from Activity to Fragment here.
        }
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup 
        container, @Nullable Bundle savedInstanceState) {
            return inflater.inflate(R.layout.PagerAFragment, container, 
        false);
        }
    
        @Override
        public void onViewCreated(View view, @Nullable Bundle 
        savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            Button Eventbutton;
    
            Eventbutton = view.findViewById(R.id.event_button);
            Eventbutton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    callbackSendData.sendDataEvent("send Data sample");
                }
            });
        }
    
       @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            try{
                callbackSendData = (CallbackSendData) context;
            }catch (ClassCastException e){
                e.printStackTrace();
            }
        }
    

    }

    现在您可以使用 CallbackSendData 将活动数据发送到片段 .

    Note: It's much easier if you are using Dependency Injection to your project, you can use Dagger2 library.

    Goodluck.

  • 0

    要在 FragmentActivity 之间进行通信(无论是在他们的演示者或他们的类之间),您需要一个您的活动实现的接口(如 ShoppingInteractor ) .

    这样你就可以在片段中调用 ((ShoppingInteractor)getActivity()).doSomething() . 如果您希望活动的演示者处理任务,则需要在活动内的 doSomething 中调用演示者 .

    您可以使用另一个接口对片段执行相同操作,并在活动内部调用片段的交互器 .

    您甚至可以在这些界面中使用 Presenter getPresenter() 来访问实际的演示者 . ( ((ShoppingInteractor)getActivity()).getPresenter().sendData(data) ) . 片段也一样 .

  • 0

    动态数据:

    以下是使用rxjava2,dagger2和moxy的示例 .

    附加条件:

    • 演示者不依赖于视图的生命周期

    • 一位主持人 - 一个观点 . 这些视图不会相互分享演示者,一个视图只有一个演示者 .

    该解决方案类似于EventBus,但使用具有有限生命周期的Subject . 它位于活动开始时创建的组件中,并在退出时被销毁 . 活动和片段都具有对它的隐式访问权限,它们可以更改值并以自己的方式响应它 .

    示例项目:https://github.com/Anrimian/ViewPagerMvpExample

    这只是一个例子,永远不会以这种方式改变主题 .

    静态数据:

    只需在片段中使用参数就可以了 .

  • 0

    如果你想使用MVP,那么第一个步骤是为每个视图创建一个演示者,我的意思是,如果你有3个片段,那么将有3个演示者 . 我认为为4个视图(活动和3个片段)创建一个演示者是个坏主意 .

相关问题