Mortar 和 Flow 库与 ViewPager

Mortar and Flow libraries vs. ViewPager

我正在尝试在我的应用程序中调整 Mortar&Flow,但遇到了一个问题,我无法让 PageAdapter 与 Screens 一起工作,而不是 Fragments。

有人成功了吗?

我没有成功,但是,也许有人可以从这一点指导我:

初始匕首注册:

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

MainScreen,其 View 托管 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() {}
    }
}

主视图:

...........
@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);
}
.....

现在,主要部分,子屏幕(3 个相似的屏幕,不同之处仅在于我们传递给它们的参数=> 它们应该根据这些参数调整视图)

@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);
        }
    }
}

这是风景 public class 子视图扩展了 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() {....}
......
}

自定义寻呼机适配器:

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();
    }
}

问题陈述:它正在崩溃,因为 SubView class 尚未在适配器的 "Layouts.createView(childContext, screen);" 时刻添加到注入列表中,我不能默认添加它,因为我想要一个从 SubScreen 到 SubScreen.Presenter 的数据的@provider。 (我正在使用局部变量。

如果 我将 SubView.class 添加到注入列表中并将本地 Screen 的变量转换为静态变量,那么我将在 ViewPager 中有 3 个相同的页面(这是合乎逻辑的,因为构造函数的每次下一次调用 - 都会覆盖旧的静态变量)。

有help/ideas吗? 谢谢你的帮助, 康斯坦丁

好的,我明白了。

首先,将 SubView 添加到全局注入的列表中 classes 然后修改 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);
        }
    }
}

然后在自定义适配器中进行以下更改:

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;
    }
    ....
}

即如果要重复使用同一屏幕,解决方案是在屏幕中保留局部 AND 静态变量。当我们膨胀视图时 - 只需将正确的值设置为静态值(将在 Presenter 中使用)。

我不确定这是最好的解决方案,但它确实有效。很高兴听到,如果可以改进。