-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ViewPager's PagerAdapter & Mortar's Screens #162
Comments
Ok, I didn't succeed but, probably someone can guide me from this point: The initial Dagger Registration: @Module(
injects = {
MainActivity.class,
},
library = true,
complete = false
)
public class DaggerConfig {
@SuppressWarnings("unused")
@Provides @Singleton Gson provideGson() {
return new GsonBuilder().create();
}
} MainScreen, whose View is hosting 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() {}
}
} MainView: ...........
@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);
}
..... Now, the main part, SubScreen (3 similar screens, that differs only by the parameters we are passing into them => they should adjust views according these parameters) @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);
}
}
} and it's view public class 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() {....}
......
} Custom Pager adapter: 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" + (new Random()).nextInt(999999));
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();
}
} The problem statement: it's crashing, as SubView class hasn't been added into list of Injections at the "Layouts.createView(childContext, screen);" moment in the Adapter, and I can't add it by default, because I want to have a @Provider of data from SubScreen to SubScreen.Presenter. (I'm using local variable. If I add SubView.class into list of injections and convert local Screen's variables into static, then I'll have 3 identical pages inside the ViewPager (which is logical, as every next call of the constructor - overrides old static variables). Any help/ideas? Thanks |
Ok, apparently I did something. First of all, adding SubView into list of globally injected classes. Then modifying SubScreen class: @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);
}
}
} and then in Custom adapter do this changes: 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;
}
....
} I.e. the idea is to keep the local AND static variables in the Screen, if the same screen is going to be reused. And when we inflate the view it - just setting the right value to the static one (that would be used in the Presenter). It works, though I'm not sure if it's a right way to do it, so would be very happy, if someone can approve this approach or propose a better solution. |
In my opinion, your logic of static variable and And in the future, you should use stack overflow for such topic. |
At this gist, you can find above solution but with save state functionality. |
Hi,
This topic has been discussed a while ago and even nice snippet has been posted (https://gist.github.com/kboyarshinov/d30c354541f95ecaeaac), but since then, the Flow and Mortar have changed and I'm a bit confused.
It used to be something like this:
But now, Layouts is no longer part of Flow and requireChild is no longer part of MortarScope.
Does anyone succeed in adapting it for the latest libs versions?
Thanks a lot(all square libraries are so awesome!) & best wishes!
The text was updated successfully, but these errors were encountered: