Salut, je fais un refactor de mon application avec MVVM et poignard 2, et je suis cet exemple [Countries App] [1] [1]: J'ai réussi à injecter LoginActivity, RestAPi et d'autres, mais dans ma prochaine activité, j'ai une vue recycleur et les détenteurs de vue donnent une erreur lors de la compilation. Ceci est mon code:Impossible d'injecter RecyclerView ViewHolder dans android avec dagger 2 et MVVM
Composants
@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);
}
Modules
@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);
}
}
Layouts activity_main
<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>
Si je commente le Inje ct méthodes dans DiViewHolderComponent et dans le titulaire de la vue le code compiler et lancer l'application, j'ai vérifié le code de nombreuses fois, mais je ne sais pas où est le problème s'il vous plaît aider !!!
Error Log
/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
S'il vous plaît inclure le message d'erreur réelle –
journal d'erreur ajouté –