でAndroidに注入できないこんにちは私は、MVVMとダガー2で私のアプリのリファクタリングを行っています。この例の[Countries App] [1] [1]: https://github.com/patloew/countries/tree/master/appRecaglerView ViewHolderをダガー2とMVVM
私はLoginActivity、RestAPiなどを正常に挿入しましたが、私の次のアクティビティにはリサイクルビューがあり、ビューホルダーはコンパイル時にエラーを出します。 は、これは私のコードです:
コンポーネント
@PerApplication
@Component(modules = {AppModule.class, NetworkApiModule.class, ViewModelModule.class})
public interface DiComponent {
@AppContext
Context context();
Resources resources();
APIService apiService();
}
@PerActivity
@Component(dependencies = {DiComponent.class},modules ={ActivityModules.class, ViewModelModule.class})
public interface DiActivitiesComponent {
void inject(LoginActivity activity);
void inject(MainActivity activity);
}
@PerViewHolder
@Component(dependencies = DiComponent.class, modules ={ViewHolderModule.class, ViewModelModule.class})
public interface DiViewHolderComponent {
void inject(MenuViewHolder viewHolder);
}
モジュール
@Module
public class AppModule {
private final Application mApp;
public AppModule(Application app) {
mApp = app;
}
@Provides
@PerApplication
@AppContext
Context provideAppContext() {
return mApp;
}
@Provides
@PerApplication
Resources provideResources(){return mApp.getResources();}
}
@Module
public class ActivityModules {
private final BaseActivity baseActivity;
public ActivityModules(BaseActivity baseActivity) {
this.baseActivity = baseActivity;
}
@Provides
@PerActivity
@ActivityContext
Context provideActivityContext() { return baseActivity; }
@Provides
@PerActivity
ProgressDialog provideProgressDialog() {
ProgressDialog progress;
progress = new ProgressDialog(baseActivity);
progress.setMessage("Loading...");
progress.setCancelable(false);
return progress;
}
@Provides
@PerActivity
Validator validator(){
return new Validator(baseActivity);
}
@Provides
@PerActivity
Navigator provideNavigator() { return new ActivityNavigator(baseActivity); }
}
@Module
public class ViewHolderModule {
private final AppCompatActivity activity;
public ViewHolderModule(View itemView) {
activity = (AppCompatActivity) itemView.getContext();
}
@Provides
@PerViewHolder
@ActivityContext
Context provideActivityContext() { return activity; }
@Provides
@PerViewHolder
FragmentManager provideFragmentManager() { return activity.getSupportFragmentManager(); }
@Provides
@PerViewHolder
Navigator provideNavigator() { return new ActivityNavigator(activity); }
}
@Module
public abstract class ViewModelModule {
@Binds
abstract Observable bindLoginViewModel(LoginViewModel loginViewModel);
@Binds
abstract Observable bindMainViewModel(MainViewModel mainViewModel);
@Binds
abstract MenuModelView bindCMenuViewModel(MenuModelView menuModelView);
}
Aplication
public class MyApplication extends Application {
private static MyApplication instance=null;
private static DiComponent component=null;
@Override
public void onCreate() {
super.onCreate();
instance=this;
component = DaggerDiComponent.builder()
.appModule(new AppModule(this))
.build();
}
public static MyApplication getInstance(){
return instance;
}
public static DiComponent getComponent() {
return component;
}
public static Resources getRes() { return instance.getResources(); }
}
BaseActivity
public abstract class BaseActivity<B extends ViewDataBinding,V extends MvvmViewModel> extends AppCompatActivity{
public static final String TAG = "BaseActivity";
protected B binding;
@Inject protected V viewModel;
@Inject protected Validator validator;
@Inject protected ProgressDialog progress;
private DiActivitiesComponent component;
protected final void setAndBindContentView(@LayoutRes int layoutResId, @Nullable Bundle savedInstanceState) {
if(viewModel == null) { throw new IllegalStateException("viewModel must not be null and should be injected via activityComponent().inject(this)"); }
binding = DataBindingUtil.setContentView(this, layoutResId);
binding.setVariable(BR.vm, viewModel);
viewModel.attachView((MvvmView) this, savedInstanceState);
}
protected final DiActivitiesComponent activityComponent() {
if(component == null) {
component = DaggerDiActivitiesComponent.builder()
.diComponent(MyApplication.getComponent())
.activityModules(new ActivityModules(this))
.build();
}
return component;
}
@Override
@CallSuper
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if(viewModel != null) { viewModel.saveInstanceState(outState); }
}
@Override
@CallSuper
protected void onDestroy() {
super.onDestroy();
if(viewModel != null) { viewModel.detachView(); }
viewModel = null;
binding = null;
component = null;
}
}
MainActivity
public class MainActivity extends BaseBarActivity<ActivityMainBinding, MainViewModel> implements MvvmView {
@Inject MenuListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityComponent().inject(this);
setAndBindContentView(R.layout.activity_main, savedInstanceState);
loadToolbar(R.string.empty_title);
ButterKnife.bind(this);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
binding.lstMenuItems.setHasFixedSize(true);
binding.lstMenuItems.setLayoutManager(new LinearLayoutManager(this));
binding.lstMenuItems.setAdapter(adapter);
adapter.setMenuItems(menuItems);
adapter.notifyDataSetChanged();
}
}
のviewmodels BaseViewModel
public abstract class BaseViewModel<V extends MvvmView> extends BaseObservable implements MvvmViewModel<V> {
@Inject protected Provider<Navigator> navigator;
private V mView;
public V getView() {
return mView;
}
@Override
@CallSuper
public void attachView(@NonNull V view, @Nullable Bundle savedInstanceState) {
mView = view;
if(savedInstanceState != null) { restoreInstanceState(savedInstanceState); }
}
@Override
@CallSuper
public void detachView() {
mView = null;
}
@Override
public void saveInstanceState(@NonNull Bundle outState) { }
@Override
public void restoreInstanceState(@NonNull Bundle savedInstanceState) { }
}
MainViewModel
@PerActivity
public class MainViewModel extends BaseViewModel<MvvmView> {
private Context context;
@Inject
public MainViewModel(@AppContext Context context) {
this.context=context;
}
}
ItemViewModel
@PerViewHolder
public class MenuModelView extends BaseViewModel<MvvmView> {
private PegasusMenuItem item;
private final Context context;
@Inject
public MenuModelView(@AppContext Context context){
this.context=context.getApplicationContext();
}
@Bindable
public Drawable getImage() {
return AppCompatDrawableManager.get().getDrawable(context,item.getResId());
}
public String getTextData() {
return item.getText();
}
public void update(PegasusMenuItem item) {
this.item = item;
notifyChange();
}
}
BaseViewHolder
public abstract class BaseViewHolder<B extends ViewDataBinding, V extends MvvmViewModel> extends RecyclerView.ViewHolder {
protected B binding;
@Inject protected V viewModel;
private DiViewHolderComponent viewHolderComponent;
private View itemView = null;
public BaseViewHolder(View itemView) {
super(itemView);
this.itemView = itemView;
}
protected final DiViewHolderComponent viewHolderComponent() {
if(viewHolderComponent == null) {
viewHolderComponent = DaggerDiViewHolderComponent.builder()
.diComponent(MyApplication.getComponent())
.viewHolderModule(new ViewHolderModule(itemView))
.build();
itemView = null;
}
return viewHolderComponent;
}
protected final void bindContentView(@NonNull View view) {
if(viewModel == null) { throw new IllegalStateException("viewModel must not be null and should be injected via viewHolderComponent().inject(this)"); }
binding = DataBindingUtil.bind(view);
binding.setVariable(BR.vm, viewModel);
viewModel.attachView((MvvmView) this, null);
}
public final V viewModel() { return viewModel; }
}
MenuViewHolder
public class MenuViewHolder extends BaseViewHolder<MenuItemBinding, MenuModelView> implements MvvmView {
public MenuViewHolder(View v) {
super(v);
viewHolderComponent().inject(this);
bindContentView(v);
}
}
レイアウト
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable name="vm" type="com.package.name.ViewModels.MainViewModel" />
</data>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:layout_width="@dimen/menu_item_size"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/gray_color"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/lst_menu_items"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:dividerHeight="0dp"
android:divider="@null" />
</LinearLayout>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
</layout>
MENU_ITEM
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="vm" type="com.package.name.ViewModels.ViewHolders.MenuModelView" />
</data>
<RelativeLayout
android:layout_width="@dimen/menu_item_size"
android:layout_height="@dimen/menu_item_size"
android:paddingTop="@dimen/margin_fields"
android:paddingBottom="@dimen/margin_fields"
android:background="@color/gray_color">
<ImageView
android:layout_width="@dimen/menu_item_icon_size"
android:layout_height="@dimen/menu_item_icon_size"
android:id="@+id/img_menu_icon"
android:src="@{vm.image}"
android:scaleType="centerInside"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{vm.textData}"
android:id="@+id/txt_menu_title"
android:textSize="@dimen/text_xsmall_size"
android:gravity="center"
android:layout_below="@+id/img_menu_icon"
android:textColor="@color/white_color" />
</RelativeLayout>
</layout>
私は麟蹄コメント場合
activity_main ctメソッドをDiViewHolderComponentに追加し、ビューホルダーでコードをコンパイルして起動すると、何度もコードをチェックしましたが、どこに問題があるのか分かりません!!!エラーログ
/Users/.../Views/Activities/BaseActivity.java
Error:(20, 42) error: cannot find symbol class BR
Error:(21, 63) error: cannot find symbol class DaggerDiActivitiesComponent
/Users/.../Views/Activities/LoginActivity.java
Error:(16, 54) error: package com.mifinity.app2soft.mifinitymvvm.databinding does not exist
Error:(25, 49) error: cannot find symbol class LoginActivityBinding
/Users/.../Views/Activities/MainActivity.java
Error:(23, 54) error: package com.package.name.databinding does not exist
Error:(30, 51) error: cannot find symbol class ActivityMainBinding
/Users/.../Views/ViewHolders/BaseViewHolder.java
Error:(9, 42) error: cannot find symbol class BR
Error:(10, 63) error: cannot find symbol class DaggerDiViewHolderComponent
/Users/.../Views/ViewHolders/MenuViewHolder.java
Error:(7, 54) error: package com.package.name.databinding does not exist
Error:(12, 53) error: cannot find symbol class MenuItemBinding
/Users/.../Views/ViewHolders/LastTransactionsViewHolder.java
Error:(7, 54) error: package com.mifinity.app2soft.mifinitymvvm.databinding does not exist
Error:(12, 64) error: cannot find symbol class AccountItemBinding
/Users/.../Views/ViewHolders/AmountViewHolder.java
Error:(7, 54) error: package com.package.name.databinding does not exist
Error:(13, 54) error: cannot find symbol class BalanceItemBinding
/Users/.../Views/Fragments/BaseFragment.java
Error:(18, 42) error: cannot find symbol class BR
Error:(19, 63) error: cannot find symbol class DaggerFragmentComponent
/Users/developer/22Technology/Android Projects/.../Views/Fragments/OverviewFragment.java
Error:(22, 54) error: package com.package.name.databinding does not exist
Error:(33, 52) error: cannot find symbol class OverviewFragmentBinding
/Users/.../MyApplication.java
Error:(6, 63) error: cannot find symbol class DaggerDiComponent
Note: Generating a MembersInjector for com.package.name.Views.Activities.MainActivity. Prefer to run the dagger processor over that class instead.
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
> java.lang.StackOverflowError
を投影し、公式の例を見てください –
エラーログが追加実際のエラーメッセージを記載してください –