Search code examples
androidfragmentfragmentmanager

FragmentManager findFragmentByTag different behavior on Android 4.0.4 and Android 4.4.2


I have a problem concerning this issue: https://code.google.com/p/android/issues/detail?id=13252

The issue is when changing the language of the Android device, some components such as RadioButton and CheckBox are not updated to the new language. I have two Fragments, FragmentA and FragmentB. In my FragmentActivity, I added FragmentA. And from Fragment A, I added FragmentB. I applied a workaround where I call a method either FragmentA or FragmentB to explicitly set the language to the correct one.

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    FragmentManager fm = getSupportFragmentManager();
    if (fm != null) {
	Fragment f = null;
			
	if ((f = fm.findFragmentByTag(FragmentB.TAG)) != null) {
		Log.e(TAG, FragmentB.TAG+ " is visible");
		((FragmentB)f).refreshLocale();
	} else {
		Log.e(TAG, FragmentB.TAG+ " is NOT visible");
	}

	if ((f = fm.findFragmentByTag(FragmentA.TAG)) != null) {
		Log.e(TAG, FragmentA.TAG+ " is visible");
		((FragmentA)f).refreshLocale();
        } else {
                Log.e(TAG, FragmentA.TAG+ " is NOT visible");
	}
    }
}

What I'm doing above is finding the Fragments by their TAG when the Activity is restored, then calling the refreshLocale() method in each Fragment, so that the correct language is applied. The fix works, but there is a situation where the behavior is inconsistent in my two test devices.

In my Galaxy S5(4.4.2) both FragmentA and FragmentB's language is updated using the workaround. But for my Xperia Mini Pro (4.0.4) only FragmentB, the currently visible Fragment, is updated. I put Logs in my code and I found that both FragmentA and FragmentB are actually visible, my code reaching FragmentA's refreshLocale() method, but somehow the text is STILL not updated to the new language.

A sample of the refreshLocale() method:

public void refreshLocale() {
    if (m_recallValues != null) {
        m_recallValues.setText(R.string.recall_values);
    }

    if (m_recallValuesRun != null) {
        m_recallValuesRun.setText(R.string.recall_run);
    }
}

Any idea about this issue? Thank you.


Solution

  • That's because the FragmentManager you are trying to find Fragment B with is not able to locate the said fragment. Fragment B was started from Fragment A, and therefore, was using the child FragmentManager. You should use getChildFragmentManager() from Fragment A instead.

    this might help: Child FragmentManager