我有一个折叠 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
。如果它是 TabLayout
或 ViewPager
,您所做的就是创建 fragment 并将其添加到布局或相应的分页器适配器中。就是这样。您此时不设置数据。
现在,当您的内部 fragment 填充到寻呼机适配器中时,它们将经过 onAttach
、onCreate
、onStart
和 onResume
生命周期方法。 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/