【问题标题】:Retain data in Fragment switching在 Fragment 切换中保留数据
【发布时间】:2018-11-08 13:27:37
【问题描述】:

正在开发一个包含 3 个片段的应用。当用户决定通过 BottomNavigationView 从 FragmentB 或 FragmentC 切换回 FragmentA 时,我想在 FragmentA 中保留数据。 我的代码在更改屏幕方向时效果很好,但由于某种原因,它不会保留片段更改的数据。

为了测试,我只使用了一个应该保留字符串数据的 EditText。

MainActivity

public class MainActivity extends AppCompatActivity implements 
BottomNavigationView.OnNavigationItemSelectedListener {

Fragment Frag = new Fragment();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    BottomNavigationView navigation = findViewById(R.id.navigation);
    navigation.setOnNavigationItemSelectedListener(this); // mOnNavigationItemSelectedListener


    if (savedInstanceState != null)
    {
        Frag = getSupportFragmentManager().getFragment(savedInstanceState, "Frag");
    }
    else
    loadFragment(new FragmentA());
}

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
    Fragment fragment = null;
    int i = menuItem.getItemId();
    if (i == R.id.fragmentA) {
        fragment = new FragmentA();
    } else if (i == R.id.fragmentB) {
        fragment = new FragmentB();
    } else if (i == R.id.fragmentC) {
        fragment = new FragmentC();           
    }

    return loadFragment(fragment);
}

private boolean loadFragment(Fragment fragment)
{
    if (fragment != null)
    {
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commit();
        Frag = fragment;
        return true;
    }
    return false;
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState, "Frag", Frag);
}
}

片段A

public class FragmentA extends Fragment {

EditText editText;
String string;

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

    if (savedInstanceState != null)
    {
        string = savedInstanceState.getString("Text", "");
    }
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    // return super.onCreateView(inflater, container, savedInstanceState);
    LayoutInflater layoutInflater = getActivity().getLayoutInflater();
    View view = layoutInflater.inflate(R.layout.fragmentA, container, false);

    editText = view.findViewById(R.id.centerText);
    editText.setText(string);
    return view;
}

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    string = editText.getText().toString();
    outState.putString("Text", string);
}
}

当用户从 FragmentB 或 FragmentC 切换回 FragmentA 时,我希望 editText 保留数据。 我已经为这个问题苦苦挣扎了一段时间,尝试了不同的方法,但没有成功。

【问题讨论】:

  • 您的问题可以解决,阅读 Fragment 生命周期和 FragmentTransaction 类中的方法。 add 方法的一些重载允许您添加标签来检索您的片段。目前您正在使用替换,它本质上是一种先删除后添加的形式。可以找到一个很好的讨论here。

标签: java android fragment retain onsaveinstancestate


【解决方案1】:

您可以保留对片段的引用,而不是像在此处那样每次都创建新片段:

if (i == R.id.fragmentA) {
    fragment = new FragmentA();
} else if (i == R.id.fragmentB) {
    fragment = new FragmentB();
} else if (i == R.id.fragmentC) {
    fragment = new FragmentC();           
}

您还可以使用ViewPager,它不仅可以让您在屏幕之间滑动,还可以设置viewPager.setOffscreenPageLimit(i);,这意味着除非片段离屏幕太远,否则不会重新创建片段。

【讨论】:

    【解决方案2】:

    这是你的错误

    if (i == R.id.fragmentA) {
        fragment = new FragmentA();
    } else if (i == R.id.fragmentB) {
        fragment = new FragmentB();
    } else if (i == R.id.fragmentC) {
        fragment = new FragmentC();           
    }
    

    点击后创建新的片段实例

    【讨论】:

      【解决方案3】:

      感谢您的回复。 这就是我改变的。它现在正在工作,虽然我不确定这是否是解决这个问题的优雅方法。导航回 FragmentA 时,数据现在保留在 EditText 中。

      MainActivity

      public class MainActivity extends AppCompatActivity implements 
      BottomNavigationView.OnNavigationItemSelectedListener {
      
      Fragment Frag = new Fragment();
      Fragment FragmentA;
      Fragment FragmentB;
      Fragment FragmentC;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
      
          BottomNavigationView navigation = findViewById(R.id.navigation);
          navigation.setOnNavigationItemSelectedListener(this); // mOnNavigationItemSelectedListener
      
          FragmentA = new FragmentA();
          FragmentB = new FragmentB();
          FragmentC = new FragmentC();
      
          if (savedInstanceState != null)
          {
              Frag = getSupportFragmentManager().getFragment(savedInstanceState, "Frag");
          }
          else
          loadFragment(FragmentA);
      }
      
      @Override
      public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
          Fragment fragment = null;
          int i = menuItem.getItemId();
          if (i == R.id.fragmentA) {
              fragment = FragmentA;
          } else if (i == R.id.fragmentB) {
              fragment = FragmentB;
          } else if (i == R.id.fragmentC) {
              fragment = FragmentC;
          }
          return loadFragment(fragment);
      }
      
      private boolean loadFragment(Fragment fragment)
      {
          if (fragment != null)
          {
              getSupportFragmentManager().beginTransaction().hide(FragmentA).commit();
              getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commit();
              getSupportFragmentManager().beginTransaction().show(fragment).commit();
      
              Frag = fragment;
              return true;
          }
          return false;
      }
      
      @Override
      protected void onSaveInstanceState(Bundle outState) {
          super.onSaveInstanceState(outState);
          getSupportFragmentManager().putFragment(outState, "Frag", Frag);
      }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-13
        • 1970-01-01
        • 2017-11-04
        • 1970-01-01
        相关资源
        最近更新 更多