[英]What is the best way to implement onClick inside an Epoxy Controller when using Dagger
我正在嘗試使用 airbnb.epoxy 在RecyclerView
內的項目上實現 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
,注入它不是問題,而是提供活動上下文,經過一些研究,我發現環氧樹脂允許活動注入,所以我想我可以將主要活動注入控制器,但我不確定這是最好的方法,也找不到實現這一點的示例項目。
請教我什么是最好的方法
它與本主題並不真正相關,但我剛剛弄清楚如何從一個活動從 Epoxy Controller 導航到另一個活動。
假設我們需要實現onSelected()
。
為了在活動之間移動,我們需要一個intent
。但它需要一個構造函數的Context
。 不幸的是,我們無法在 Epoxy Controller 中實現這一點。 因此,我們需要在Activity
或Fragment
上實現onSelected
偵聽器,然后將其傳遞回 Epoxy Controller。
下面是我的環氧樹脂控制器:
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)
}
}
經過大量研究,我找到了答案。 它可能會幫助其他人,所以就在這里。
*我假設您已經具備 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.使應用程序實現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-Architecture 示例應用程序一個示例項目,其中展示了如何正確實施 Dagger2。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.