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

标签 android android-fragments fragmentpageradapter tabview

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

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

最佳答案

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

从服务器获取数据,将其存储在您需要的位置,并从您的 Activity 更新 UI。此时,您可以显示 MyFragment1 或您的 TabLayout/ViewPager。如果它是 TabLayoutViewPager,您所做的就是创建 fragment 并将其添加到布局或相应的分页器适配器中。就是这样。您此时不设置数据。

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

因此在 fragment 的 onResume 中,您将拥有如下内容:

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

尽管将其存储在某个状态类中会更好。但这将是一个单独的问题。

祝你好运!

关于android - 当 fragment 在 FragmentPagerAdapter 中完全初始化时等待事件以使用数据设置它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49922747/

相关文章:

android - Android 中的多列文本显示

java - 使用 ant 引用 jar(不是/libs)的外部文件夹

android - 当 Activity 在其进程被杀死后重新创建时, fragment 后台是否也恢复了?

java - "Could not find class ' android.support.v4.app.FragmentActivity '"错误

android - 查看寻呼机 fragment 和选项卡不同步android

java - 解析jsoup中元素内的元素?

android-3.0-honeycomb - 非法参数异常 : No view found for id for fragment when fast switching ActionBar Tabs

android - FragmentPagerAdapter 已弃用

android - fragment 在 viewpager 中对用户可见之前初始化

java - Gmapsfx 集成在使用 Gluon-mobile 构建的 Android 应用程序中无法正常工作