-1

I have a main activity which has two configurations, one which will display a fragment which is locked to portrait orientation.

When a button is clicked on this fragment, a fragment replaces it, however this new fragment can be displayed landscape with a second fragment side-by-side.

This all works fine, however I am intercepting back-navigation in the second state so that I can replace the fragments with the original configuration. When changing orientation all of my class variables are being reset and my references to the fragments are lost.

Here is the main activity:

package mobileapp.group2.fragmenttest;

import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;

public class MainActivity extends FragmentActivity
    implements ListPeersFragment.ListPeersFragmentListener
{
    public static final String LIST_FRAGMENT_TAG = "ListPeersFragment";
    public static final String GAME_FRAGMENT_TAG = "GameFragment";
    public static final String OPP_FRAGMENT_TAG  = "ViewOpponentFragment";

    // FrameLayout references
    private FrameLayout mLeftFrame;
    private FrameLayout mRightFrame;

    // Fragment references
    private ListPeersFragment mListPeersFragment = null;
    private GameFragment      mGameFragment      = null;
    private ViewOppFragment   mViewOppFragment   = null;

    // Boolean denoting if currently in game mode.
    //private boolean mGameMode;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mLeftFrame  = (FrameLayout) findViewById(R.id.left_frame);
        mRightFrame = (FrameLayout) findViewById(R.id.right_frame);

        // However, if we're being restored from a previous state,
        // then we don't need to do anything and should return or else
        // we could end up with overlapping fragments.
        if (savedInstanceState != null) {
            return;
        }

        // Create fragments
        if (mListPeersFragment == null)
            mListPeersFragment = new ListPeersFragment();
        if (mGameFragment == null)
            mGameFragment    = new GameFragment();
        if (mViewOppFragment == null)
            mViewOppFragment = new ViewOppFragment();

        // In case this activity was started with special instructions from an
        // Intent, pass the Intent's extras to the fragment as arguments
        mListPeersFragment.setArguments(getIntent().getExtras());

        // Add the fragment to the 'fragment_container' FrameLayout
        FragmentManager fm = getSupportFragmentManager();
        fm.beginTransaction().add(R.id.left_frame, mListPeersFragment, LIST_FRAGMENT_TAG).commit();
        fm.beginTransaction().add(R.id.right_frame, mViewOppFragment, OPP_FRAGMENT_TAG).commit();

        //mGameMode = false;
    }

    // Used to intercept back navigation.
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            FragmentManager fm = getSupportFragmentManager();
            if (fm.findFragmentByTag(GAME_FRAGMENT_TAG) != null)
            {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                //FragmentTransaction ft = fm.beginTransaction();
                fm.beginTransaction().replace(R.id.left_frame, mListPeersFragment, LIST_FRAGMENT_TAG)
                        .commitAllowingStateLoss();
                //mGameMode = false;
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    public void startGame()
    {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.left_frame, mGameFragment, GAME_FRAGMENT_TAG).commit();

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
        //mGameMode = true;
    }

    // Implementation of the ListPeersFragmentListener function onPeerSelected
    public void onPeerSelected(int position)
    {

    }

}

The main activity layout file:

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="horizontal" >

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:id="@+id/left_frame"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"/>

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:id="@+id/right_frame"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"/>

</LinearLayout>

The landscape version just has weights on the framelayouts.

The other fragment classes are very simple they don't do anything at the moment.

The failing code is the onKeyDown method. Is there a way to prevent the class variables from being re-initialised on orientation change? I have looked at handling config changes but then the landscape layout file is not loaded.

If anyone can help would be very appreciated!!!

jl1992
  • 9
  • 2

2 Answers2

1

You should use the onSaveInstanceState() and the onRestoreInstanceState() methods of the Activity as mentioned in this link.

Also, you would need to call the setRetainInstance() methods in the Fragments you want to save.

Check out this link for more information about setRetainInstanceState().

Community
  • 1
  • 1
Evin1_
  • 12,292
  • 9
  • 45
  • 47
0

Actually whenever orientation gets changed, activities Oncreate () method is called. So to prevent clearing of variables, override OnConfigurationChange() method and in your manifest file do this at the activity:-

android:configChanges="orientation"
Ankesh kumar Jaisansaria
  • 1,563
  • 4
  • 26
  • 44