Fix double loading of navigation fragments

This commit is contained in:
Dominik Schürmann 2014-02-04 21:46:22 +01:00
parent e2bd3ae831
commit ecd376961f

View File

@ -80,6 +80,16 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
private Fragment mCurrentFragment; private Fragment mCurrentFragment;
private BootstrapButton mImportButton; private BootstrapButton mImportButton;
private static final Class[] NAVIGATION_CLASSES = new Class[]{
ImportKeysServerFragment.class,
ImportKeysFileFragment.class,
ImportKeysQrCodeFragment.class,
ImportKeysClipboardFragment.class,
ImportKeysNFCFragment.class
};
private int mCurrentNavPostition = -1;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -109,6 +119,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
handleActions(savedInstanceState, getIntent()); handleActions(savedInstanceState, getIntent());
} }
protected void handleActions(Bundle savedInstanceState, Intent intent) { protected void handleActions(Bundle savedInstanceState, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
Bundle extras = intent.getExtras(); Bundle extras = intent.getExtras();
@ -132,8 +143,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
/* Keychain's own Actions */ /* Keychain's own Actions */
// display file fragment // display file fragment
getSupportActionBar().setSelectedNavigationItem(1); loadNavFragment(1, null);
loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]);
if (dataUri != null) { if (dataUri != null) {
// action: directly load data // action: directly load data
@ -164,18 +174,16 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
} }
// display key server fragment with query // display key server fragment with query
getSupportActionBar().setSelectedNavigationItem(0);
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString(ImportKeysServerFragment.ARG_QUERY, query); args.putString(ImportKeysServerFragment.ARG_QUERY, query);
loadFragment(ImportKeysServerFragment.class, args, mNavigationStrings[0]); loadNavFragment(0, args);
// action: search immediately // action: search immediately
startListFragment(savedInstanceState, null, null, query); startListFragment(savedInstanceState, null, null, query);
} else if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) { } else if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) {
// NOTE: this only displays the appropriate fragment, no actions are taken // NOTE: this only displays the appropriate fragment, no actions are taken
getSupportActionBar().setSelectedNavigationItem(1); loadNavFragment(1, null);
loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]);
// no immediate actions! // no immediate actions!
startListFragment(savedInstanceState, null, null, null); startListFragment(savedInstanceState, null, null, null);
@ -183,27 +191,23 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
// also exposed in AndroidManifest // also exposed in AndroidManifest
// NOTE: this only displays the appropriate fragment, no actions are taken // NOTE: this only displays the appropriate fragment, no actions are taken
getSupportActionBar().setSelectedNavigationItem(2); loadNavFragment(2, null);
loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[2]);
// no immediate actions! // no immediate actions!
startListFragment(savedInstanceState, null, null, null); startListFragment(savedInstanceState, null, null, null);
} else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) { } else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) {
// NOTE: this only displays the appropriate fragment, no actions are taken // NOTE: this only displays the appropriate fragment, no actions are taken
getSupportActionBar().setSelectedNavigationItem(3); loadNavFragment(3, null);
loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[3]);
// no immediate actions! // no immediate actions!
startListFragment(savedInstanceState, null, null, null); startListFragment(savedInstanceState, null, null, null);
} else {
startListFragment(savedInstanceState, null, null, null);
} }
} }
private void startListFragment(Bundle savedInstanceState, byte[] bytes, Uri dataUri, String serverQuery) { private void startListFragment(Bundle savedInstanceState, byte[] bytes, Uri dataUri, String serverQuery) {
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.import_keys_list_container) != null) {
// However, if we're being restored from a previous state, // However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else // then we don't need to do anything and should return or else
// we could end up with overlapping fragments. // we could end up with overlapping fragments.
@ -222,34 +226,44 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
// do it immediately! // do it immediately!
getSupportFragmentManager().executePendingTransactions(); getSupportFragmentManager().executePendingTransactions();
} }
}
/**
* "Basically, when using a list navigation, onNavigationItemSelected() is automatically
* called when your activity is created/re-created, whether you like it or not. To prevent
* your Fragment's onCreateView() from being called twice, this initial automatic call to
* onNavigationItemSelected() should check whether the Fragment is already in existence
* inside your Activity."
* <p/>
* from http://stackoverflow.com/questions/10983396/fragment-oncreateview-and-onactivitycreated-called-twice/14295474#14295474
*
* In our case, if we start ImportKeysActivity with parameters to directly search using a fingerprint,
* the fragment would be loaded twice resulting in the query being empty after the second load.
*
* Our solution:
* To prevent that a fragment will be loaded again even if it was already loaded loadNavFragment
* checks against mCurrentNavPostition.
*
* @param itemPosition
* @param itemId
* @return
*/
@Override @Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) { public boolean onNavigationItemSelected(int itemPosition, long itemId) {
// Create new fragment from our own Fragment class Log.d(Constants.TAG, "onNavigationItemSelected");
switch (itemPosition) {
case 0: loadNavFragment(itemPosition, null);
loadFragment(ImportKeysServerFragment.class, null, mNavigationStrings[itemPosition]);
break;
case 1:
loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[itemPosition]);
break;
case 2:
loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[itemPosition]);
break;
case 3:
loadFragment(ImportKeysClipboardFragment.class, null, mNavigationStrings[itemPosition]);
break;
case 4:
loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[itemPosition]);
break;
default:
break;
}
return true; return true;
} }
private void loadNavFragment(int itemPosition, Bundle args) {
if (mCurrentNavPostition != itemPosition) {
getSupportActionBar().setSelectedNavigationItem(itemPosition);
loadFragment(NAVIGATION_CLASSES[itemPosition], args, mNavigationStrings[itemPosition]);
mCurrentNavPostition = itemPosition;
}
}
private void loadFragment(Class<?> clss, Bundle args, String tag) { private void loadFragment(Class<?> clss, Bundle args, String tag) {
mCurrentFragment = Fragment.instantiate(this, clss.getName(), args); mCurrentFragment = Fragment.instantiate(this, clss.getName(), args);
@ -275,10 +289,9 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
String query = "0x" + fingerprint; String query = "0x" + fingerprint;
// display key server fragment with query // display key server fragment with query
getSupportActionBar().setSelectedNavigationItem(0);
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString(ImportKeysServerFragment.ARG_QUERY, query); args.putString(ImportKeysServerFragment.ARG_QUERY, query);
loadFragment(ImportKeysServerFragment.class, args, mNavigationStrings[0]); loadNavFragment(0, args);
// action: search directly // action: search directly
startListFragment(savedInstanceState, null, null, query); startListFragment(savedInstanceState, null, null, query);