Skip to content

Commit 70c9e68

Browse files
committed
Correct ActionBar subtitle on locale change
1 parent a26a62e commit 70c9e68

File tree

3 files changed

+102
-8
lines changed

3 files changed

+102
-8
lines changed

app/src/main/java/com/zegoggles/smssync/activity/MainActivity.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import android.provider.Telephony.Sms;
2424
import android.support.annotation.NonNull;
2525
import android.support.annotation.Nullable;
26+
import android.support.annotation.StringRes;
2627
import android.support.v4.app.ActivityCompat;
2728
import android.support.v4.app.Fragment;
2829
import android.support.v4.app.FragmentManager;
@@ -116,13 +117,14 @@ public class MainActivity extends ThemeActivity implements
116117
private static final int REQUEST_PERMISSIONS_BACKUP_SERVICE = 6;
117118

118119
public static final String EXTRA_PERMISSIONS = "permissions";
119-
private static final String SCREEN_TITLE = "title";
120+
private static final String SCREEN_TITLE_RES = "titleRes";
120121

121122
private Preferences preferences;
122123
private AuthPreferences authPreferences;
123124
private OAuth2Client oauth2Client;
124125
private Intent fallbackAuthIntent;
125126
private Intent changeDefaultPackageIntent;
127+
private PreferenceTitles preferenceTitles;
126128

127129
@Override
128130
public void onCreate(Bundle bundle) {
@@ -136,7 +138,7 @@ public void onCreate(Bundle bundle) {
136138
oauth2Client = new OAuth2Client(authPreferences.getOAuth2ClientId());
137139
fallbackAuthIntent = new Intent(this, OAuth2WebAuthActivity.class).setData(oauth2Client.requestUrl());
138140
changeDefaultPackageIntent = new Intent(ACTION_CHANGE_DEFAULT).putExtra(EXTRA_PACKAGE_NAME, getPackageName());
139-
141+
preferenceTitles = new PreferenceTitles(getResources(), R.xml.preferences);
140142
preferences = new Preferences(this);
141143
if (bundle == null) {
142144
showFragment(new MainSettings(), null);
@@ -237,8 +239,11 @@ public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Prefer
237239
if (LOCAL_LOGV) {
238240
Log.v(TAG, "onPreferenceStartFragment(" + preference + ")");
239241
}
240-
final Fragment fragment = Fragment.instantiate(this, preference.getFragment(),
241-
new BundleBuilder().putString(SCREEN_TITLE, String.valueOf(preference.getTitle())).build());
242+
final Fragment fragment = Fragment.instantiate(
243+
this,
244+
preference.getFragment(),
245+
new BundleBuilder().putInt(SCREEN_TITLE_RES, preferenceTitles.getTitleRes(preference.getKey())).build());
246+
242247
showFragment(fragment, preference.getKey());
243248
return true;
244249
}
@@ -318,13 +323,13 @@ public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, Preferen
318323
onBackStackChanged();
319324
}
320325

321-
private @Nullable CharSequence getCurrentTitle() {
326+
private @StringRes int getCurrentTitle() {
322327
final int entryCount = getSupportFragmentManager().getBackStackEntryCount();
323328
if (entryCount == 0) {
324-
return null;
329+
return 0;
325330
} else {
326331
final BackStackEntry entry = getSupportFragmentManager().getBackStackEntryAt(entryCount - 1);
327-
return entry.getBreadCrumbTitle();
332+
return entry.getBreadCrumbTitleRes();
328333
}
329334
}
330335

@@ -409,7 +414,7 @@ private void showFragment(@NonNull Fragment fragment, @Nullable String rootKey)
409414
.replace(R.id.preferences_container, fragment, rootKey);
410415
if (rootKey != null) {
411416
tx.addToBackStack(null);
412-
tx.setBreadCrumbTitle(args.getString(SCREEN_TITLE));
417+
tx.setBreadCrumbTitle(args.getInt(SCREEN_TITLE_RES));
413418
}
414419
tx.commit();
415420
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.zegoggles.smssync.activity;
2+
3+
import android.content.res.Resources;
4+
import android.content.res.XmlResourceParser;
5+
import android.support.annotation.NonNull;
6+
import android.support.annotation.StringRes;
7+
import android.support.annotation.XmlRes;
8+
import org.xmlpull.v1.XmlPullParser;
9+
import org.xmlpull.v1.XmlPullParserException;
10+
11+
import java.io.IOException;
12+
import java.util.HashMap;
13+
import java.util.Map;
14+
15+
/**
16+
* Standard Android preferences don't expose the title resource id. Reparse preferences XML,
17+
* key title resources by preference key.
18+
*/
19+
class PreferenceTitles {
20+
private static final String NS = "http://schemas.android.com/apk/res/android";
21+
private static final String PREFERENCE_SCREEN = "PreferenceScreen";
22+
private Map<String, Integer> titleResources = new HashMap<String, Integer>();
23+
24+
PreferenceTitles(@NonNull Resources resources, @XmlRes int preferenceRes) {
25+
final XmlResourceParser parser = resources.getXml(preferenceRes);
26+
try {
27+
while (true) {
28+
int type;
29+
do {
30+
type = parser.next();
31+
} while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT);
32+
33+
if (type == XmlPullParser.END_DOCUMENT) {
34+
break;
35+
} else if (PREFERENCE_SCREEN.equals(parser.getName()) && parser.getAttributeCount() > 0) {
36+
final @StringRes int titleRes = parser.getAttributeResourceValue(NS, "title", 0);
37+
final String key = parser.getAttributeValue(NS, "key");
38+
if (titleRes > 0 && key != null) {
39+
titleResources.put(key, titleRes);
40+
}
41+
}
42+
}
43+
} catch (IOException e) {
44+
throw new RuntimeException(e);
45+
} catch (XmlPullParserException e) {
46+
throw new RuntimeException(e);
47+
}
48+
}
49+
50+
/**
51+
* @return the string resource id or 0 if not found
52+
*/
53+
@StringRes int getTitleRes(String preferenceKey) {
54+
final Integer res = titleResources.get(preferenceKey);
55+
return res == null ? 0 : res;
56+
}
57+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.zegoggles.smssync.activity;
2+
3+
import com.zegoggles.smssync.R;
4+
import org.junit.Before;
5+
import org.junit.Test;
6+
import org.junit.runner.RunWith;
7+
import org.robolectric.RobolectricTestRunner;
8+
import org.robolectric.RuntimeEnvironment;
9+
10+
import static com.google.common.truth.Truth.assertThat;
11+
12+
@RunWith(RobolectricTestRunner.class)
13+
public class PreferenceTitlesTest {
14+
private PreferenceTitles subject;
15+
16+
@Before
17+
public void setUp() throws Exception {
18+
subject = new PreferenceTitles(RuntimeEnvironment.application.getResources(), R.xml.preferences);
19+
}
20+
21+
@Test public void testParseValidKey() {
22+
final int res = subject.getTitleRes("com.zegoggles.smssync.activity.fragments.AutoBackupSettings");
23+
assertThat(res).isGreaterThan(0);
24+
String resolved = RuntimeEnvironment.application.getString(res);
25+
assertThat(resolved).isEqualTo("Auto backup settings");
26+
}
27+
28+
@Test public void testInvalidKeyReturnsZero() {
29+
final int res = subject.getTitleRes("foo.bar.not.found");
30+
assertThat(res).isEqualTo(0);
31+
}
32+
}

0 commit comments

Comments
 (0)