JochemQuery
JochemQuery

Reputation: 1567

Android Fragment (Weird) behaviour on rotation change

Backstory: I'm building an app as a school project. It works with an API to get some JSON and convert that and show it to the user.

Note: (Players are people in World of Tanks, i'm using their api)

My current structure: Home -> Navigation drawer -> Players -> Select Player -> Details of a Player

Start Searching player Player detail This happens after turning the screen to horizontal

My problem: When in the detail view of a player it opens perfectly. When I change the orientation to horizontal the screen it goes "back" to the search view.

When I go from the nav drawer to a detail of a player (using hardcoded player) and I change the screen to horizontal nothing happens.

I'm totally clueless what causes this.

Finally some code: (Please not this is for school project and i'm new with android)

I chose to only dev for api 21+

XML Search

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:id="@+id/someId">


    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/search_query"
        android:hint="@string/search_hint"
        android:layout_alignBottom="@+id/search_button"
        android:layout_alignParentStart="true"
        android:maxLines="1"
        android:layout_toStartOf="@+id/search_button" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/search_button"
        android:onClick="getPlayers"
        android:id="@+id/search_button"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true" />

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
          android:id="@id/android:list"
        android:layout_below="@+id/search_query"
        android:layout_alignParentStart="true" />



</RelativeLayout>

XML Detail

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/player_detail_fragment"
    tools:context="com.jdkmedia.vh8.fragment.PlayerDetailFragment">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:id="@+id/playerName"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="24dp"/>


    <android.support.v7.widget.RecyclerView
        android:id="@+id/tank_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        android:layout_below="@+id/playerName"
        android:layout_alignParentStart="true"
        android:layout_marginTop="40dp" />

</RelativeLayout>

MainActivity Navigation Drawer

 @Override
    public void onNavigationDrawerItemSelected(int position) {
        // update the main content by replacing fragments
        Fragment fragment = null;

        switch (position) {
            case 0:
                fragment = MainActivityFragment.newInstance(accessToken);
                Log.i(APP + " Class: " + TAG, "Main activity fragment selected");
                break;
            case 1:
                fragment = PlayerSearchMainFragment.newInstance();
                Log.i(APP + " Class: " + TAG, "Player search activity fragment selected");
                break;
            case 2:
//                fragment = new TankCompareTopFragment();
                Player player = new Player(314134134,"stack overflow");
                onPlayerSelected(player);
                break;
            default:
                fragment = MainActivityFragment.newInstance(accessToken);
                Log.i(APP + " Class: " + TAG, " default fragment selected");
                break;
        }

        if(fragment != null){
            Log.i(APP + " Class: " + TAG, "Fragment is not null - transaction");
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction(   )
                    .replace(R.id.container, fragment, fragment.getClass().getName()).addToBackStack(fragment.getClass().getName()).commit();
        }
    }

Any other code files can be posted when needed.

Upvotes: 1

Views: 633

Answers (3)

tyz
tyz

Reputation: 11

From the Android Docs - http://developer.android.com/guide/topics/resources/runtime-changes.html

If OnDestroy is called (as it is on runtime changes) your activity will be restarted with onCreate.

You can use onSaveInstanceState() to capture the state in onPause() and restore it during onCreate() with onRestoreInstanceState().

For a fragment you should use setRetainInstance(boolean) in the Fragment's onCreate().

Similar questions have been asked previously. You may find more detailed information with a stackoverflow search.

Upvotes: 1

EE66
EE66

Reputation: 4661

  1. Device was rotated. FragmentManager saves state for all fragments, then frees them.
  2. New activity. New fragments get instantiated, with states restored.
  3. Fragments get moved into onCreate.
  4. onCreate of NavigationDrawerFragment triggers a replace transaction.
  5. The replace transaction removes the restored PlaceholderFragment with a new one, which has no saved state. credit to Chiu-Ki Chan taken from here

Upvotes: 3

Chris Stillwell
Chris Stillwell

Reputation: 10547

You need to save your fragments state. Modify your onCreate to resemble this.

onCreate(Bundle save){
   super.onCreate(save);
   setRetainInstance(true);
}

Upvotes: 1

Related Questions