Bibliotecas de Mortero y Flujo vs. ViewPager

Estoy tratando de adaptar Mortar & Flow en mi aplicación y frente a un problema, que no puedo hacer PageAdapter funciona con pantallas, en lugar de fragmentos.

¿Alguien logró hacerlo bien?

No lo logré, pero probablemente alguien me puede guiar desde este punto:

El registro inicial de Dagger:

@Module( injects = { MainActivity.class, }, library = true, complete = false ) public class DaggerConfig { @SuppressWarnings("unused") @Provides @Singleton Gson provideGson() { return new GsonBuilder().create(); } } 

MainScreen, cuyo View está alojando ViewPager:

 @Layout(R.layout.screen_main) @WithModule(MainScreen.Module.class) public class MainScreen extends Path { @dagger.Module(injects = MainView.class, addsTo = DaggerConfig.class) public static class Module {} @Singleton public static class Presenter extends ViewPresenter<MainView> { @Inject public Presenter() {} } } 

Vista principal:

 ........... @Inject MainScreen.Presenter presenter; ........... @Override protected void onFinishInflate() { super.onFinishInflate(); ButterKnife.inject(this); final Path[] screens = { new SubScreen("1"), new SubScreen("2"), new SubScreen("3"), }; CustomPagerAdapter customPagerAdapter = new CustomPagerAdapter(getContext(), screens ); customPagerAdapter .setAdapter(firstRunPagerAdapter); } ..... 

Ahora, la parte principal , SubScreen (3 pantallas similares, que difiere sólo por los parámetros que estamos pasando en ellos => deben ajustar las vistas de acuerdo a estos parámetros)

 @Layout(R.layout.screen_subscreen) @WithModule(SubScreen.Module.class) public class SubScreen extends Path { private final String title; public SubScreen(String titleParam) { title = titleParam; } @dagger.Module(injects = SubView.class, addsTo = DaggerConfig.class) public class Module { @Provides SubViewMetadata provideSubViewMetadata() { return new SubViewMetadata(backgroundColor, title); } } @Singleton public static class Presenter extends ViewPresenter<SubView> { private String title; @Inject public Presenter(String title) { this.title= title; } @Override protected void onLoad(Bundle savedInstanceState) { super.onLoad(savedInstanceState); if (!hasView()) { return; } getView().setTitle(subViewMetadata.title); } } } 

Y su clase pública de vista SubView extends FrameLayout {

  @InjectView(R.id.subViewTitleTextView) TextView subViewTitleTextView; @Inject SubScreen.Presenter presenter; public SubView(Context context, AttributeSet attrs) { super(context, attrs); ObjectGraphService.inject(context, this); } public void setTitle(String title) { subViewTitleTextView.setText(title); } @Override protected void onAttachedToWindow() {....} @Override protected void onDetachedFromWindow() {....} ...... } 

Adaptador personalizado del buscapersonas:

 public class CustomPagerAdapter extends PagerAdapter { private final Context context; private final Path[] screens; public CustomPagerAdapter(Context context, Path[] screens) { this.context = context; this.screens = screens; } @Override public int getCount() { return (screens == null)? 0 : screens.length; } @Override public boolean isViewFromObject(View view, Object o) { return view.equals(o); } @Override public Object instantiateItem(ViewGroup container, int position) { Path screen = screens[position]; MortarScope originalScope = MortarScope.getScope(context); MortarScope newChildScope = originalScope.buildChild().build("tutorialpage" + position); Context childContext = newChildScope.createContext(context); View newChild = Layouts.createView(childContext, screen); container.addView(newChild); return newChild; } @Override public void destroyItem(ViewGroup container, int position, Object object) { View view = ((View) object); container.removeView(view); MortarScope.getScope(view.getContext()).destroy(); } } 

La instrucción del problema : se está estrellando, ya que la clase SubView no se ha agregado a la lista de Inyecciones en la sección "Layouts.createView (childContext, pantalla)"; Momento en el adaptador, y no puedo agregarlo de forma predeterminada, porque quiero tener un @provider de datos de SubScreen a SubScreen.Presenter. (Estoy usando la variable local.

Si agrego SubView.class a la lista de inyecciones y convierto las variables locales de Screen en static, entonces tendré 3 páginas idénticas dentro de ViewPager (lo cual es lógico, ya que cada llamada siguiente del constructor – anula las viejas variables estáticas).

Cualquier ayuda / ideas? Gracias por su ayuda, Konstantin

Ok, me di cuenta.

Primero de todo, agregando SubView en la lista de clases inyectadas globalmente Luego modificando la clase SubScreen:

 @Layout(R.layout.screen_subscreen) public class SubScreen extends Path { private static String titleStatic; // Introducing static variable private final String title; public SubScreen(String titleParam) { title = titleParam; } public void refreshPresenter() { titleStatic = title; } @Singleton public static class Presenter extends ViewPresenter<SubView> { private String title; @Inject public Presenter() { } @Override protected void onLoad(Bundle savedInstanceState) { super.onLoad(savedInstanceState); if (!hasView()) { return; } getView().setTitle(titleStatic); } } } 

Y luego en Custom adapter hacer esto cambia:

 public class CustomPagerAdapter extends PagerAdapter { private final Context context; private final SubScreen[] screens; public CustomPagerAdapter(Context context, SubScreen[] screens) { this.context = context; this.screens = screens; } ...... @Override public Object instantiateItem(ViewGroup container, int position) { SubScreen screen = screens[position]; MortarScope originalScope = MortarScope.getScope(context); MortarScope newChildScope = originalScope.buildChild().build("tutorialpage" + position); Context childContext = newChildScope.createContext(context); screen.refreshPresenter(); // updating the static var with local one! View newChild = Layouts.createView(childContext, screen); container.addView(newChild); return newChild; } .... } 

Es decir, la solución es mantener las variables locales y estáticas en la pantalla, si la misma pantalla va a ser reutilizada. Y cuando inflemos la vista, simplemente establecemos el valor correcto para el estático (que se usaría en el presentador).

No estoy seguro, que es la mejor solución posible, pero funciona. Sería bueno escuchar, si puede ser mejorado.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.