2

我正在尝试在RecyclerView使用 airbnb.epoxy 的项目上实现 Click 功能。问题是我需要上下文才能在单击时导航到另一个活动。

我做了什么: 在 Epoxy 的示例应用程序之后,我在 EpoxyController 内实现了一个接口,其中包含在单击回收器视图中的项目时要调用的函数。然后我让我的主活动实现这个接口和方法,并在主活动中使用它的构造函数实例化控制器,并将一个对活动的引用传递给它:

    public class MortgageController extends TypedEpoxyController<List<Mortgage>> {

    private final MortgageCallBacks callBacks;

    public MortgageController(MortgageCallBacks callBacks) {
        this.callBacks = callBacks;
    }

    @Override
    protected void buildModels(List<Mortgage> mortgages) {
        Observable.from(mortgages)
                .subscribe(mortgage -> new MortgageModel_().id(mortgage.id())
                        .mortgage(mortgage)
                        .clicks(callBacks::onMortgageClicked)
                        .addTo(this));
    }


    public interface MortgageCallBacks {
        void onMortgageClicked(Mortgage mortgage);
    }
}

主要活动的 onCreate 和onMortgageClick

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

     controller = new MortgageController(this);
     initRecycler();
     controller.setData(mortgages);}
 
 @Override
 public void onMortgageClicked(Mortgage mortgage) {
     DetailActivity.start(this, mortgage);
 }

在上述工作时我想做什么Dagger2,我在我的项目中使用并想将控制器注入到MainActivity,注入它不是问题,而是提供活动上下文,经过一些研究,我发现环氧树脂允许活动注入,所以我想我可以将主要活动注入控制器,但我不确定这是最好的方法,也找不到实现这个的示例项目。

请告诉我最好的方法是什么

4

2 回答 2

1

它与这个主题并不真正相关,但我刚刚弄清楚如何从一个 Epoxy Controller 导航到另一个活动。

假设我们需要实现onSelected().

要在活动之间移动,我们需要一个intent. 但它需要一个Context构造函数。不幸的是,我们无法在 Epoxy Controller 中实现这一点。因此,我们需要在 an或 a上实现onSelected监听器,然后将其传递回 Epoxy Controller。ActivityFragment

下面是我的环氧树脂控制器:

class TaskController(private val listener: TaskSelectListener) : TypedEpoxyController<List<Task>>() {
    override fun buildModels(tasks: List<Task>?) {
        tasks?.forEach { task ->
            TaskBindingModel_()
                .id(task.id)
                .taskToShow(task)
                .listener { model, _, _, _ ->
                    listener.onSelected(model.taskToShow())
                }.addTo(this)
        }

    }

    interface TaskSelectListener {
        fun onSelected(suggestion: Task)
    }

}

它只是一个简单的控制器,这里只有两件事需要通知。首先是interface. 另一个类context将继承这个接口类并实现onSelected我们想要的方法。

另一件事是将该接口类作为回调传递给控制器​​。

在我的 MainActivity 文件中,我这样实现:

class MainActivity : AppCompatActivity(), TaskController.TaskSelectListener {
    // pass `this` MainActivity because it is a TaskSelectListener
    private val taskController : TaskController by lazy { TaskController(this) }

     override fun onSelected(task: Task) {
        val intent = Intent(this, TomatoActivity::class.java)
        startActivity(intent)
    }
}
于 2019-08-09T08:16:32.110 回答
0

经过大量研究,我找到了答案。它可能会帮助其他人,所以就在这里。

*我假设您已经具备 Dagger2 的基本功能(如果不查看Google 的用户指南)最新的 dagger 版本(2.10 以上)引入了 dagger.android 并允许您通过几个简单的步骤直接注入活动:1 .创建一个带有@ContributesAndroidInjector注解的方法的模块 2.将模块添加到应用程序组件 3.使应用程序实现HasActivityInjector

1.您可以创建一个 ActivityBindingModule,它有一个由@ContributesAndroidInjector 注释的方法,它会自动生成一个子组件,否则我们必须自己编写。您可以指定此子组件将具有的模块。

@Module 公共抽象类 ActivityBindingModule {

@PerActivity
@ContributesAndroidInjector(modules = MainActivityModule.class)
abstract MainActivity mainActivityInjector();

}

2.将模块添加到您的 AppComponent:

@Component(modules = {AppModule.class, ActivityBindingModule.class})
@Singleton
public interface AppComponent{
...
} 

3.让app实现HasActivityInjector并覆盖AndroidInjector activityInjector():

public class App implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> activityInjector;

@Override
public void onCreate() {
    super.onCreate();
     ...
}

@Override
public AndroidInjector<Activity> activityInjector() {
    return dispatchingActivityInjector;
}

}

另一种方法是扩展实现上述所有功能的DaggerApplication

现在我可以将 MainActivity 注入 Mortgage Controller

   private final MainActivity mainActivity;


@Inject
public MortgageController(MainActivity mainActivity) {
    this.mainActivity = mainActivity;
}

有关更多信息,请参阅这篇令人惊叹的文章,它帮助我更好地理解这个不那么简单的主题,以及Google 的 Android 架构示例应用程序示例项目,其中展示了如何正确实现 Dagger2。

于 2018-03-13T22:47:12.973 回答