在片段交换中保留数据

时间:2018-11-08 13:27:37

标签: java android fragment retain onsaveinstancestate

正在开发一个包含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);
}
}

FragmentA

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保留数据。 我已经在这个问题上苦苦挣扎了一段时间,尝试其他方法没有运气。

3 个答案:

答案 0 :(得分: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();           
}

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

答案 1 :(得分: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();           
}

点击后创建新的片段实例

答案 2 :(得分:0)

感谢您的答复。 这就是我所改变的。尽管我不确定这是否是解决此问题的理想方法,但现在可以正常工作。现在,导航回FragmentA时,数据将保留在EditText中。

MainActivity

#include <iostream>
#include <string>
#include <algorithm>

//function to output string without spaces, numbers, or punctuations        
std::string alphabetOnly (std::string input)
{
    auto not_alpha = [](char c) { return !std::isalpha(c); };
    input.erase(std::remove_if(begin(input), 
                               end(input), 
                               not_alpha), 
                std::end(input));
    return input;
}

int main() {
    std::string input;

    std::cout << "Enter a string to test: ";
    getline(std::cin, input);

    std::cout << "alphabetOnly: " << alphabetOnly(input) << std::endl;
}