防止ViewPager始终初始化下一个片段(位置n + 1)

问题描述 投票:3回答:3

我正在使用ViewPager进行注册,其中包含5个片段:FragmentA-> FragmentB-> FragmentC-> FragmentD-> FragmentE。 FragmentD需要来自FragmentC的数据,以便在显示其视图时向用户显示一些信息。问题是在向用户显示FragmentC时会初始化FragmentD,这意味着FragmentD所需的数据尚未准备好。因此,FragmentD无法正确显示数据,因为已经调用了其生命周期初始化方法(我用来从FragmentC获取数据)。

我已经尝试设置pager.setOffscreenPageLimit(0)来强制ViewPager始终重建片段,但是由于1是接受的最小值,所以这是不可能的。

这是我的FragmentC代码的履历:

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

    radio0 = (RadioButton) getView().findViewById(R.id.radio_0);
    radio0.setOnCheckedChangeListener(this);
    text0 = (TextView) getView().findViewById(R.id.description_0);
    setOnClickListener(text0, radio0);

    radio1 = (RadioButton) getView().findViewById(R.id.radio_1);
    radio1.setOnCheckedChangeListener(this);
    text1 = (TextView) getView().findViewById(R.id.description_1);
    setOnClickListener(text1, radio1);

    radio2 = (RadioButton) getView().findViewById(R.id.radio_2);
    radio2.setOnCheckedChangeListener(this);
    text2 = (TextView) getView().findViewById(R.id.description_2);
    setOnClickListener(text2, radio2);
}

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    if (isChecked) {
        switch (buttonView.getId()) {
                    case R.id.radio_0:
            radio1.setChecked(false);
            radio2.setChecked(false);

            choice = 0;
            break;
        case R.id.radio_1:
            radio0.setChecked(false);
            radio2.setChecked(false);

            choice = 1;
            break;
        case R.id.radio_2:
            radio0.setChecked(false);
            radio1.setChecked(false);

            choice = 2;
            break;
        }
    }
}

这是我的FragmentD代码的履历:

private OnOptionSelectedListener callback;
private EditText edit0, edit1, edit2, edit3;

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    // This makes sure that the container activity has implemented
    // the callback interface. If not, it throws an exception
    try {
        callback = (OnOptionSelectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement OnOptionSelectedListener");
    }
}

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

    edit0 = ((EditText) getView().findViewById(R.id.edit_0));
    edit1 = ((EditText) getView().findViewById(R.id.edit_1));
    edit2 = ((EditText) getView().findViewById(R.id.edit_2));
    edit3 = ((EditText) getView().findViewById(R.id.edit_3));
}

@Override
public void onStart() {
    super.onStart();

    choice = callback.getChoice();

    edit0.setText(text0);
    edit1.setText(text1);
    edit2.setText(text2);
    edit3.setText(text3);
}

public interface OnOptionSelectedListener {
    public int getOption();
}

每个editText内部的值(text0,text1,text2,text3)取决于FragmentC之前所做的选择。但是,就像我之前说的,在初始化FragmentC时会调用onActivityCreatedonStart,因此用户尚未选择任何选项,即choice始终带有默认值,而不是用户选择哪个选项无关。

我真的不知道该怎么办...有人有什么想法吗?

android android-fragments android-viewpager
3个回答
7
投票

忘记setOffscreenPageLimit()并覆盖setUserVisibleHint(boolean)方法。

检查该方法的参数以使其变为true,并在那里使用给定的数据更新UI。

请注意,不建议使用上述方法,因此应改用setUserVisibleHint(boolean)。有关更多信息,请访问:

FragmentTransaction.setMaxLifecycle(Fragment, Lifecycle.State)


0
投票

只需在onCreate()中调用setOffscreenPageLimit()(在初始化ViewPager之后)。 OffscreenPageLimit设置应保留到当前页面任一侧的页面数(在您的情况下为2)。这样,您所有的片段都将被实例化。

来源:https://developer.android.com/reference/androidx/fragment/app/FragmentTransaction#setMaxLifecycle(androidx.fragment.app.Fragment,%20androidx.lifecycle.Lifecycle.State)


0
投票

Preload fragment's view in ViewPager on first run增大为2,因此您知道仍在实例化当前所选片段前后的片段。之后,由于您使用的是setOffscreenPageLimit(),因此应考虑设置ViewPageronPageChangeListener()上,并以这种方式与活动交互-而不是使用生命周期方法。

ViewPager

© www.soinside.com 2019 - 2024. All rights reserved.