等效onActivityResult的砂浆和流量? [英] Equivalent of onActivityResult for Mortar and Flow?

查看:120
本文介绍了等效onActivityResult的砂浆和流量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在寻找一种方式来利用从屏幕返回结果流程,而不会失去什么了建立在previous屏幕,类似于我做onActivityResult。例如这里的地方我创建一个新的文件的屏幕:

  @Layout(R.layout.new_document_view)
类NewDocumentScreen实现蓝图{

  //这里想象一下,有些蓝图锅炉板

  静态类presenter实现查看presenter< NewDocumentView> {
    私人最终流流;

    私人文档新建文档=新的文件();

    @注入presenter(流量流){this.flow =流动; }

    @覆盖保护无效的onLoad(包savedInstanceState){
        super.onLoad(savedInstanceState);

        NewDocumentView视图= getView();
        如果(查看== NULL)回报;

        view.bindTo(新建文档); //立即反映文档视图更改
    }

    //试想一下,这就是所谓的由pressing在NewDocumentView按钮
    公共无效chooseDocumentAuthor(){
      //我想这里是导航到选择屏幕,使我的选择
      //然后返回此屏幕已经设置文档的作者。
      flow.goTo(新ChooseDocumentAuthorScreen());
    }
  }
}
 

我怎样才能做到这一点?我一直在尝试与弹出弹出presenter 但不是很多对这些信息,我不相信这是正确的方式去,因为选择器是在自己的权利的屏幕。

更新&ndash的;可能的解决方案

根据从 @rjrjr 下面的答案我做这似乎工作好吗以下

TakesResult.java

 公共接口TakesResult< T> {
  //调用接收结果时,
  无效onResult(T结果);
}
 

NewDocumentScreen.java

  @Layout(R.layout.new_document_view)
类NewDocumentScreen实现蓝图,TakesResult<作者> {

  私人文档新建文档=新的文件();

  @覆盖公共无效onResult(作者结果){
    newDocument.setAuthor(结果);
  }

  //这里想象一下,有些蓝图锅炉板

  @ dagger.Module(=其注入NewDocumentView.class,addsTo = MainScreen.Module.class)
  类模块{
    @Provides文件provideDocument(){返回新建文档; }
    @Provides NewDocumentScreen provideScreen(){返回这一点; }
  }

  静态类presenter实现查看presenter< NewDocumentView> {
    私人最终流流;
    私人最终NewDocumentScreen屏幕
    私人最终文档新建文档;

    @注入presenter(流量流,NewDocumentScreen屏幕,文档新建文档){
      this.flow =流动;
      this.screen =屏幕;
      this.newDocument =新建文档;
    }

    @覆盖
    保护无效的onLoad(包savedInstanceState){
      //东西更新视图
    }

    //想象这就是所谓的观点
    公共无效chooseDocumentAuthor(){
      //由于屏幕TakesResult我们将它发送给ChooseAuthorScreen
      flow.goTo(新ChooseDocumentAuthorScreen(屏幕));
    }
  }
}
 

ChooseAuthorScreen.java

  @Layout(R.layout.choose_author_view)
类ChooseAuthorScreen实现蓝图{
  私人最终TakesResult<作者> resultReceiver;

  ChooseAuthorScreen(TakesResult<作者> resultReceiver){
    this.resultReceiver = resultReceiver;
  }

  //这里想象一下,有些蓝图锅炉板

  @ dagger.Module(=其注入ChooseAuthorView.class,addsTo = MainScreen.Module.class)
  类模块{
    @Provides TakesResult<作者> provideResultReceiver(){返回resultReceiver; }
  }

  静态类presenter实现查看presenter< ChooseAuthorView> {
    私人最终流流;
    私人最终TakesResult<作者> resultReceiver;

    @注入presenter(流量流,TakesResult<作者> resultReceiver){
      this.flow =流动;
      this.resultReceiver = resultReceiver;
    }

    //想象这就是所谓的观点
    公共无效chooseAuthor(作者作者){
      resultReceiver.onResult(作者);
      flow.goBack();
    }
  }
}
 

解决方案

弹出和弹出式presenter很可能是个错误。更好的方法,我看到的是有对话屏幕写入其结果一个众所周知的瞬态场的流动backstack的previous屏幕上的对象。一方面,这似乎是pretty的哈克。在另一方面,这是很简单,很可读。

I'm looking for a way to return a result from a Screen using Flow without losing what's been built up in the previous Screen, similar to what I'd do with onActivityResult. For example here's a screen where I'm creating a new document:

@Layout(R.layout.new_document_view)
class NewDocumentScreen implements Blueprint {

  // Imagine some Blueprint boiler plate here

  static class Presenter implements ViewPresenter<NewDocumentView> {
    private final Flow flow;

    private Document newDocument = new Document();

    @Inject Presenter(Flow flow) { this.flow = flow; }

    @Override protected void onLoad(Bundle savedInstanceState) {
        super.onLoad(savedInstanceState);

        NewDocumentView view = getView();
        if (view == null) return;

        view.bindTo(newDocument);  // immediately reflect view changes in document
    }   

    // Imagine this is called by pressing a button in NewDocumentView
    public void chooseDocumentAuthor() {
      // What I want here is to navigate to the chooser screen, make my choice and
      // then return to this screen having set the author on the document.
      flow.goTo(new ChooseDocumentAuthorScreen());
    }
  }
}

How can I do this? I've been experimenting with Popup and PopupPresenter but there's not a lot of info on these and I'm not convinced this is the right way to go since the chooser is a screen in its own right.

Update – Potential Solution

Based on an answer below from @rjrjr I've done the following which seems to work okay:

TakesResult.java

public interface TakesResult<T> {
  // Called when receiving a result
  void onResult(T result);
}

NewDocumentScreen.java

@Layout(R.layout.new_document_view)
class NewDocumentScreen implements Blueprint, TakesResult<Author> {

  private Document newDocument = new Document();      

  @Override public void onResult(Author result) {
    newDocument.setAuthor(result);
  }

  // Imagine some Blueprint boiler plate here

  @dagger.Module(injects = NewDocumentView.class, addsTo = MainScreen.Module.class)
  class Module {
    @Provides Document provideDocument() { return newDocument; }  
    @Provides NewDocumentScreen provideScreen() { return this; }
  }

  static class Presenter implements ViewPresenter<NewDocumentView> {
    private final Flow flow;
    private final NewDocumentScreen screen
    private final Document newDocument;

    @Inject Presenter(Flow flow, NewDocumentScreen screen, Document newDocument) { 
      this.flow = flow; 
      this.screen = screen;
      this.newDocument = newDocument;
    }

    @Override
    protected void onLoad(Bundle savedInstanceState) {
      // Stuff to update view
    }

    // Imagine this is called by the view
    public void chooseDocumentAuthor() {
      // Since screen TakesResult we send it to the ChooseAuthorScreen
      flow.goTo(new ChooseDocumentAuthorScreen(screen));
    }
  }
}

ChooseAuthorScreen.java

@Layout(R.layout.choose_author_view)
class ChooseAuthorScreen implements Blueprint {
  private final TakesResult<Author> resultReceiver;

  ChooseAuthorScreen(TakesResult<Author> resultReceiver) {
    this.resultReceiver = resultReceiver;
  }

  // Imagine some Blueprint boiler plate here

  @dagger.Module(injects = ChooseAuthorView.class, addsTo = MainScreen.Module.class)
  class Module {
    @Provides TakesResult<Author> provideResultReceiver() { return resultReceiver; }  
  }

  static class Presenter implements ViewPresenter<ChooseAuthorView> {
    private final Flow flow;
    private final TakesResult<Author> resultReceiver;

    @Inject Presenter(Flow flow, TakesResult<Author> resultReceiver) { 
      this.flow = flow; 
      this.resultReceiver = resultReceiver;
    }

    // Imagine this is called by the view
    public void chooseAuthor(Author author) {
      resultReceiver.onResult(author);
      flow.goBack();
    }
  }
}

解决方案

Popup and PopupPresenter were probably a mistake. A better technique I've seen is to have the "dialog" screen write its result to a well known transient field on the previous screen object in the Flow backstack. On the one hand this seems pretty hacky. On the other hand, it's very simple and very readable.

这篇关于等效onActivityResult的砂浆和流量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆