当片段在 FragmentPagerAdapter 中完全初始化时等待事件以使用数据设置它们

Wait for event when fragments fully initialized in FragmentPagerAdapter to setup them with data

我有一个 activity 正在折叠 AppBarLayout。在 onCreate() 方法中,我向服务器发送请求以获取一些数据。并根据我得到的数据 - 我需要在运行时动态选择要显示给用户的视图:1. MyFragment1;或 2. TabLayout/ViewPagerFragmentPagerAdapter,其中有两个片段。我需要为这些片段设置一些数据。但是接下来的问题是:我已经有数据并在我的适配器中将其设置为片段,但是片段方法 onCreate 尚未被调用,并且我的布局未初始化。这就是我在将数据填充到布局视图时崩溃的原因。那么,我怎样才能以某种方式制作 - 首先创建片段并初始化它的字段,然后才用数据设置它?谢谢。

    private MenuFragment1 menu1Fragment1;
    private MenuFragment3 menu1Fragment3;
    private TabMenuAdapter adapter;

private void setupViewPager(ViewPager viewPager) {
        menu1Fragment1 = new MenuFragment1();
        menu1Fragment3 = new MenuFragment3();

        adapter = new TabMenuAdapter(getSupportFragmentManager());
        adapter.addFragment(menu1Fragment1, "Menu 1");
        adapter.addFragment(menu1Fragment3, "Menu 2");
        viewPager.setAdapter(adapter);
    }

public onDataLoaded(String data)
{
//at this point, fragment is created, but it's View fields are NULL!!
menu1Fragment1.data = data;
}


@Layout(id = R.layout.content_shop_final)
public class ShopFinalTermsFragment extends BaseFragment {

    private static final String SANS_SERIF_FAMILY_NAME = "sans-serif";
    private static final String SANS_SERIF_MEDIUM_FAMILY_NAME = "sans-serif-medium";

    private InfoModel InfoModel;
    private RateModel RateModel;

    @BindView(R.id.shop_final_nested_scroll_view)
    NestedScrollView nestedScrollView;

    @BindView(R.id.shop_final_pending_txt)
    TextView pendingDurationTxt;

    @BindView(R.id.shop_final_rate_cond_rv)
    RecyclerView rateCondRv;

    @BindView(R.id.shop_final_description_txt)
    TextView descriptionTxt;

    @Inject
    ToolsManager toolsManager;

    RateConditionsAdapter adapter;


    private String getParams;

    public static ShopFinalTermsFragment newInstance(String getParams, InfoModel shopInfoModel, RateModel RateModel) {
        ShopFinalTermsFragment fragment = new ShopFinalTermsFragment();

        Bundle args = new Bundle();
        args.putString(SHOP_GET_PARAMS, shopGetParams);
        args.putSerializable(INFO_MODEL_KEY, shopInfoModel);
        args.putSerializable(MODEL_KEY, userCashbackRateModel);
        fragment.setArguments(args);

        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getArguments() != null) {
            this.GetParams = getArguments().getString(SHOP_GET_PARAMS);
            this.InfoModel = (InfoModel) getArguments().getSerializable(INFO_MODEL_KEY);
            this.RateModel = (RateModel) getArguments().getSerializable(RATE_MODEL_KEY);
        }
    }

    @Override
    protected void setupInOnCreateView() {
        nestedScrollView.setVisibility(View.VISIBLE);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            conditionsTxt.setTypeface(Typeface.create(SANS_SERIF_FAMILY_NAME, Typeface.BOLD));
        } else {
            conditionsTxt.setTypeface(Typeface.create(SANS_SERIF_MEDIUM_FAMILY_NAME, Typeface.NORMAL));
        }
    }

    @Override
    protected void inject() {
        ShopsComponent shopsComponent = DaggerShopsComponent.builder()
                .applicationComponent(((BaseActivity) getActivity()).getApplicationComponent())
                .build();
        shopsComponent.inject(this);
    }

    public void setupWithData(InfoModel InfoModel, RateModel RateModel) {
//THIS METHOD IS COLLED FROM ACTIVITY'S onDataLoaded(InfoModel InfoModel, RateModel RateModel) method
        setupShopInformation(shopInfoModel);
        setCashBackRateModel(userCashbackRateModel);
    }
}

您以错误的方式使用了依赖项。应该在片段上调用 ​​setupWithData 的不是 activity,而应该是从 activity(或其他存储)获取数据的片段。这样,您将打破对最终未初始化的片段生命周期的依赖。

从服务器获取数据,将其存储在您需要的地方,然后从您的 activity 更新 UI。此时你要么显示 MyFragment1,要么显示你的 TabLayout/ViewPager。如果它是 TabLayoutViewPager,您所做的就是创建片段并将其添加到布局或相应的寻呼机适配器中。而已。您此时不设置数据。

现在,当您的内部片段填充到寻呼机适配器中时,它们将经历 onAttachonCreateonStartonResume 生命周期方法。 onResume 是加载数据的好地方。您可以直接从片段访问它,也可以从出站 activity 获取它 - 取决于什么对您更有意义。如果您需要 activity 引用,您可以通过片段中的 getActivity() 方法访问它。

因此在该片段的 onResume 中,您将拥有类似的内容:

setupShopInformation((YourActivity) getActivity()).getShopInfoModel());
setCashBackRateModel((YourActivity) getActivity()).getUserCashbackRateModel());

尽管以某种状态存储它会更好 class。但这将是一个单独的问题。

祝你好运!