Reputation: 103
I am using Navigation drawer layout and have 2 items in side menu. I used fragment for each item to show while navigate.
Let's consider Fragment1
& Fragment2
. When i auto-rotate the screen from Fragment2
, it destroy the fragment and showing Fragment1
's content.
With few youTube tutorials, I tried using onSaveInstanceState
. But i was not able to find the correct solution.
JavaHomeActivity.java //Fragment1
public class JavaHomeActivity extends Fragment{
// created for save state in orientation change
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState==null)
{
}
else{
savedInstanceState.getString("home_text");
}
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("Home");
}
// created for save state in orientation change
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("home_text", String.valueOf(R.id.nav_home));
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.java_home_layout,container,false);
}
}
JavaBasicActivity //Fragment2
public class JavaBasicActivity extends Fragment{
TextView text;
String data;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("Java Basics");
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("basic_text", String.valueOf(R.id.nav_basics));
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.java_basic_layout,container,false);
if(savedInstanceState==null)
{
}
else{
data=savedInstanceState.getString("basic_text");
TextView myText= (TextView) view.findViewById(R.id.basicText);
myText.setText(data);
}
return view;
}
}
Fragment1's XML
<TextView
android:id="@+id/homeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="start"
android:padding="15dp"
android:text="@string/java_home_content"
android:textAlignment="textStart"
android:textColor="@color/text_color" />
Fragment2's XML
<TextView
android:id="@+id/basicText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="start"
android:drawableBottom="@drawable/jvm_arc"
android:padding="15dp"
android:text="@string/java_basic_content"
android:textAlignment="textStart"
android:textColor="@color/text_color" />
JavaMainPageActivity.java //navigation Drawer Activity
public class JavaMainPageActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_java_main_page);
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);
displaySelectedScreen(R.id.nav_home);
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.java_main_page, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void displaySelectedScreen(int id){
Fragment fragment= null;
switch(id)
{
case R.id.nav_home:
fragment= new JavaHomeActivity();
break;
case R.id.nav_basics:
fragment= new JavaBasicActivity();
break;
}
if(fragment!=null)
{
FragmentTransaction ft= getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_main, fragment);
ft.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
displaySelectedScreen(id);
return true;
}
}
Can anyone please help me? Where i am doing error and which i have to change to get the solution.?
Upvotes: 1
Views: 136
Reputation: 2188
Here is your solution.
Your Fragment would look something like this:
public class Fragment1 extends Fragment {
private View mView;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
// created for save state in orientation change
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("Fragment1", "My First Fragment");
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_1, container, false);
return mView;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
TextView mText = (TextView) mView.findViewById(R.id.text);
if (savedInstanceState == null) {
} else {
String saved = savedInstanceState.getString("Fragment1");
mText.setText(saved);
}
}
}
And your activity should be like this :
public class MainActivity extends AppCompatActivity {
private Fragment mCurrentFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
//Restore the fragment's instance
mCurrentFragment = getSupportFragmentManager().getFragment(savedInstanceState, "Fragment1");
} else {
mCurrentFragment = new Fragment1();
addFragment(mCurrentFragment);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "Fragment1", mCurrentFragment);
}
public void addFragment(Fragment fragment) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
if (mCurrentFragment != null) {
Fragment f = getSupportFragmentManager().findFragmentByTag(mCurrentFragment.getClass().getName());
if (f != null) {
fragmentTransaction.remove(f);
}
}
fragmentTransaction.add(R.id.fragment, fragment, fragment.getClass().getName());
fragmentTransaction.commit();
mCurrentFragment = fragment;
}
}
As it is already said that activity will recreate, you need to save your fragment's state too in your activity as in above code. Hope it will help you and more clear to you.
Upvotes: 0
Reputation: 13865
You are adding the Fragment in your onCreate
through displaySelectedScreen(R.id.nav_home);
and this gets executed even after orientation change.
So this overrides the actual system recreated Fragment.
Change the code like this in onCreate
:
if (savedInstanceState == null) {
displaySelectedScreen(R.id.nav_home);
}
Upvotes: 1