Android Studio 3.0 Canary 8Cách đưa Hoạt động vào Bộ điều hợp bằng dagger2
Tôi đang cố gắng đưa MainActivity vào Bộ điều hợp của mình. Tuy nhiên, giải pháp của tôi hoạt động tốt, nhưng tôi nghĩ rằng đó là một mùi mã và không đúng cách để làm điều đó.
đoạn chuyển đổi của tôi trông như thế này, nhưng tôi không thích về việc này là tôi phải cast Activity
-MainActivity
:
public class RecipeAdapter extends RecyclerView.Adapter<RecipeListViewHolder> {
private List<Recipe> recipeList = Collections.emptyList();
private Map<Integer, RecipeListViewHolderFactory> viewHolderFactories;
private MainActivity mainActivity;
public RecipeAdapter(Activity activity, Map<Integer, RecipeListViewHolderFactory> viewHolderFactories) {
this.recipeList = new ArrayList<>();
this.viewHolderFactories = viewHolderFactories;
this.mainActivity = (MainActivity)activity;
}
@Override
public RecipeListViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
/* Inject the viewholder */
final RecipeListViewHolder recipeListViewHolder = viewHolderFactories.get(Constants.RECIPE_LIST).createViewHolder(viewGroup);
recipeListViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/* Using the MainActivity to call a callback listener */
mainActivity.onRecipeItemClick(getRecipe(recipeListViewHolder.getAdapterPosition()));
}
});
return recipeListViewHolder;
}
}
Trong mô-đun của tôi, tôi vượt qua Hoạt động trong constructor của mô-đun và chuyển nó vào Adapter.
@Module
public class RecipeListModule {
private Activity activity;
public RecipeListModule() {}
public RecipeListModule(Activity activity) {
this.activity = activity;
}
@RecipeListScope
@Provides
RecipeAdapter providesRecipeAdapter(Map<Integer, RecipeListViewHolderFactory> viewHolderFactories) {
return new RecipeAdapter(activity, viewHolderFactories);
}
}
Trong lớp Ứng dụng của tôi, tôi tạo thành phần và tôi đang sử dụng SubComponent cho bộ điều hợp. Ở đây tôi phải vượt qua Hoạt động mà tôi không chắc chắn là một ý tưởng hay.
@Override
public void onCreate() {
super.onCreate();
applicationComponent = createApplicationComponent();
recipeListComponent = createRecipeListComponent();
}
public BusbyBakingComponent createApplicationComponent() {
return DaggerBusbyBakingComponent.builder()
.networkModule(new NetworkModule())
.androidModule(new AndroidModule(BusbyBakingApplication.this))
.exoPlayerModule(new ExoPlayerModule())
.build();
}
public RecipeListComponent createRecipeListComponent(Activity activity) {
return recipeListComponent = applicationComponent.add(new RecipeListModule(activity));
}
Fragment Mỹ I tiêm như thế này:
@Inject RecipeAdapter recipeAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((BusbyBakingApplication)getActivity().getApplication())
.createRecipeListComponent(getActivity())
.inject(this);
}
Mặc dù các tác phẩm thiết kế trên, tôi nghĩ rằng đó là một mùi mã như tôi phải cast Hoạt động với MainActivity. Lý do tôi sử dụng Hoạt động vì tôi muốn làm cho mô-đun này trở nên chung chung hơn.
Chỉ cần tự hỏi nếu có một cách tốt hơn
=============== CẬP NHẬT sử dụng giao diện
Interface
public interface RecipeItemClickListener {
void onRecipeItemClick(Recipe recipe);
}
Thực hiện
public class RecipeItemClickListenerImp implements RecipeItemClickListener {
@Override
public void onRecipeItemClick(Recipe recipe, Context context) {
final Intent intent = Henson.with(context)
.gotoRecipeDetailActivity()
.recipe(recipe)
.build();
context.startActivity(intent);
}
}
Trong mô-đun của mình, tôi có các nhà cung cấp sau đây
@Module
public class RecipeListModule {
@RecipeListScope
@Provides
RecipeItemClickListener providesRecipeItemClickListenerImp() {
return new RecipeItemClickListenerImp();
}
@RecipeListScope
@Provides
RecipeAdapter providesRecipeAdapter(RecipeItemClickListener recipeItemClickListener, Map<Integer, RecipeListViewHolderFactory> viewHolderFactories) {
return new RecipeAdapter(recipeItemClickListener, viewHolderFactories);
}
}
Sau đó, tôi sử dụng nó thông qua constructor injection trong RecipeAdapter
public class RecipeAdapter extends RecyclerView.Adapter<RecipeListViewHolder> {
private List<Recipe> recipeList = Collections.emptyList();
private Map<Integer, RecipeListViewHolderFactory> viewHolderFactories;
private RecipeItemClickListener recipeItemClickListener;
@Inject /* IS THIS NESSESSARY - AS IT WORKS WITH AND WITHOUT THE @Inject annotation */
public RecipeAdapter(RecipeItemClickListener recipeItemClickListener, Map<Integer, RecipeListViewHolderFactory> viewHolderFactories) {
this.recipeList = new ArrayList<>();
this.viewHolderFactories = viewHolderFactories;
this.recipeItemClickListener = recipeItemClickListener;
}
@Override
public RecipeListViewHolder onCreateViewHolder(final ViewGroup viewGroup, int i) {
/* Inject the viewholder */
final RecipeListViewHolder recipeListViewHolder = viewHolderFactories.get(Constants.RECIPE_LIST).createViewHolder(viewGroup);
recipeListViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
recipeItemClickListener.onRecipeItemClick(getRecipe(recipeListViewHolder.getAdapterPosition()), viewGroup.getContext());
}
});
return recipeListViewHolder;
}
}
Chỉ cần một câu hỏi, là chú thích cần @Inject cho các nhà xây dựng trong RecipeAdapter. Vì nó hoạt động có hoặc không có @Inject.
Hãy có một cái nhìn tại Constructor Injection và làm thế nào để sử dụng nó. Việc tạo các phương thức 'cung cấp *' chỉ gọi một hàm tạo là không có gì ngoài tiếng ồn và mã để duy trì. –