UserA1195
UserA1195

Reputation: 103

How do i retain Fragment's content while changing orientation in android?

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

Answers (2)

AndiM
AndiM

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

Bob
Bob

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

Related Questions