问题
I have 3 Fragment (Fragment Home, Fragment A, Fragment B and Fragment C). First time app run will display Fragment Home (Set in Mainactivity). From Navigation Draw Item can choose every fragment. Every selected item will display detail Fragment.
I have problems to handle data and retain fragment :
(1). When I select a fragment (for example Fragment A) will show the page of Fragment A. But when I rotate the device, why my fragment back to Fragment Home and not stay at current Fragment ??How to handle it ?
(2). In Fragment B, I show image in GridView. But when I rotate the device, why my fragment back to Fragment Home and not stay at current Fragment ??How to handle it and still display this fragment with existing Data?
This is my code :
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private static final String LOG_TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
displaySelectedItem(R.id.nav_home);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
displaySelectedItem(item.getItemId());
return true;
}
private void displaySelectedItem (int itemId) {
Fragment fragment = null;
switch (itemId){
case R.id.nav_home:
fragment = new FragmentHome();
break;
case R.id.nav_a:
fragment = new FragmentA();
break;
case R.id.nav_b:
fragment = new FragmentB();
break;
case R.id.nav_c:
fragment = new FragmentC();
break;
case R.id.nav_d:
fragment = new FragmentD();
break;
}
FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
List<Fragment> fragments = fragmentManager.getFragments();
if (fragments != null) {
for(Fragment f : fragments){
fragmentManager.popBackStack();
}
}
//replace the fragment
if (fragment != null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment, "TAG_FRAGMENT");
fragmentTransaction.commit();
}
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerLayout.closeDrawer(GravityCompat.START);
}
Fragment A :
public class FragmentA extends Fragment {
public FragmentA() {
super();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_a, container, false);
return rootView;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("Fragment A");
}
}
Fragment B :
public class FragmentB extends Fragment {
private static final String LOG_TAG = FragmentB.class.getSimpleName();
private ImageAdapter imageAdapter;
private ArrayList<Movie> movieList;
public FragmentNowPlaying() {
super();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_b, container, false);
GridView gridView = (GridView) rootView.findViewById(R.id.gridviewNowPlaying);
imageAdapter = new ImageAdapter(getContext(), R.layout.fragment_b, movieList);
if (savedInstanceState == null) {
movieList = new ArrayList<Movie>();
}else{
movieList = (ArrayList<Movie>) savedInstanceState.get("MovieList");
}
gridView.setAdapter(imageAdapter);
return rootView;
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList("MovieList",movieList);
super.onSaveInstanceState(outState);
}
回答1:
Solved this issue. In MainActivity add this :
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION, 0);
Menu menu = navigationView.getMenu();
menu.getItem(mCurrentSelectedPosition).setChecked(true);
}
In every fragment add condition to check savedInstanceState null or not.
Thanks everybody
回答2:
You need to override onConfigurationChanged(Configuration newConfig)
method in your Fragments A and B to tell them to stay there when the app configuration change. For example:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// get current fragment
Fragment fragment = mAdapter.getItem(currentItem);
if(fragment!=null){
fragment.onResume();
}
}
回答3:
Because every time you rotate the screen the onCreate() method is called.
work around
in onCreate() method check whether the savedInstanceState() is null or not
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(null == savedInstanceState){
//set you initial fragment object
}
else
{
//Load the fragment by tag
}
}
and to save the instance state just before onPause() in all fragments
@Override
protected void onSaveInstanceState(Bundle bundle1)
{
super.onSaveInstanceState(bundle1); Log.i(tag,"inside onSaveInstanceState");
bundle1.putInt("tag",n);
}
来源:https://stackoverflow.com/questions/40232149/how-to-handle-rotate-screen-and-save-data-in-fragment