回答編集履歴
5
API17以降でクラッシュする問題への対策でコード修正
test
CHANGED
@@ -70,7 +70,11 @@
|
|
70
70
|
|
71
71
|
}
|
72
72
|
|
73
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
74
|
+
|
73
|
-
applyOverrideConfiguration(configuration);
|
75
|
+
applyOverrideConfiguration(configuration);
|
76
|
+
|
77
|
+
}
|
74
78
|
|
75
79
|
|
76
80
|
|
4
ソースコードの改善
test
CHANGED
@@ -30,47 +30,39 @@
|
|
30
30
|
|
31
31
|
public CustomLocaleTimePicker(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
32
32
|
|
33
|
-
super(
|
33
|
+
super(new ContextLocaleWrapper(context, Locale.US), attrs, defStyleAttr);
|
34
34
|
|
35
35
|
|
36
36
|
|
37
|
-
// N未満で書き換えたLocaleのデフォルト値を元に戻す
|
38
|
-
|
39
|
-
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && defaultLocale != null) {
|
40
|
-
|
41
|
-
|
37
|
+
((ContextLocaleWrapper) getContext()).resetDefaultLocale();
|
42
|
-
|
43
|
-
}
|
44
38
|
|
45
39
|
}
|
46
40
|
|
47
41
|
|
48
42
|
|
49
|
-
private static Locale de
|
43
|
+
private static class ContextLocaleWrapper extends ContextThemeWrapper {
|
50
44
|
|
51
45
|
|
52
46
|
|
53
|
-
|
47
|
+
@Nullable
|
54
48
|
|
55
|
-
// N未満ではLocaleのデフォルト値を参照してしまうので対策
|
56
|
-
|
57
|
-
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
58
|
-
|
59
|
-
|
49
|
+
private Locale defaultLocale = null;
|
60
|
-
|
61
|
-
Locale.setDefault(locale);
|
62
|
-
|
63
|
-
}
|
64
50
|
|
65
51
|
|
66
52
|
|
67
|
-
|
53
|
+
private ContextLocaleWrapper(Context context, Locale locale) {
|
68
54
|
|
55
|
+
super(context, context.getTheme());
|
56
|
+
|
57
|
+
|
58
|
+
|
69
|
-
if
|
59
|
+
Configuration configuration = new Configuration(context.getResources().getConfiguration());
|
70
60
|
|
71
61
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
72
62
|
|
73
63
|
configuration.setLocale(locale);
|
64
|
+
|
65
|
+
configuration.setLayoutDirection(locale);
|
74
66
|
|
75
67
|
} else {
|
76
68
|
|
@@ -78,24 +70,38 @@
|
|
78
70
|
|
79
71
|
}
|
80
72
|
|
81
|
-
|
73
|
+
applyOverrideConfiguration(configuration);
|
82
74
|
|
83
|
-
} else {
|
84
75
|
|
85
|
-
Resources res = context.getResources();
|
86
76
|
|
87
|
-
|
77
|
+
// N未満ではLocaleのデフォルト値を参照してしまうので対策
|
88
78
|
|
89
|
-
|
79
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && !Locale.getDefault().equals(defaultLocale)) {
|
90
80
|
|
81
|
+
defaultLocale = Locale.getDefault();
|
82
|
+
|
83
|
+
Locale.setDefault(locale);
|
84
|
+
|
85
|
+
}
|
86
|
+
|
87
|
+
}
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
-
|
91
|
+
public void resetDefaultLocale() {
|
92
|
+
|
93
|
+
// N未満で書き換えたLocaleのデフォルト値を元に戻す
|
94
|
+
|
95
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && defaultLocale != null) {
|
96
|
+
|
97
|
+
Locale.setDefault(defaultLocale);
|
98
|
+
|
99
|
+
}
|
92
100
|
|
93
101
|
}
|
94
102
|
|
95
103
|
}
|
96
104
|
|
97
|
-
|
98
|
-
|
99
105
|
}
|
100
106
|
|
101
107
|
```
|
3
styleやthemeを正しく引き継げるようコード修正
test
CHANGED
@@ -22,7 +22,7 @@
|
|
22
22
|
|
23
23
|
public CustomLocaleTimePicker(Context context, @Nullable AttributeSet attrs) {
|
24
24
|
|
25
|
-
this(context, attrs,
|
25
|
+
this(context, attrs, Resources.getSystem().getIdentifier("timePickerStyle", "attr", "android"));
|
26
26
|
|
27
27
|
}
|
28
28
|
|
@@ -32,9 +32,11 @@
|
|
32
32
|
|
33
33
|
super(getContextForLocale(context, Locale.US), attrs, defStyleAttr);
|
34
34
|
|
35
|
+
|
36
|
+
|
37
|
+
// N未満で書き換えたLocaleのデフォルト値を元に戻す
|
38
|
+
|
35
39
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && defaultLocale != null) {
|
36
|
-
|
37
|
-
// N未満で書き換えたLocaleのデフォルト値を元に戻す
|
38
40
|
|
39
41
|
Locale.setDefault(defaultLocale);
|
40
42
|
|
@@ -50,9 +52,9 @@
|
|
50
52
|
|
51
53
|
private static Context getContextForLocale(@NonNull Context context, @NonNull Locale locale) {
|
52
54
|
|
55
|
+
// N未満ではLocaleのデフォルト値を参照してしまうので対策
|
56
|
+
|
53
57
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
54
|
-
|
55
|
-
// N未満ではLocaleのデフォルト値を参照してしまうので対策
|
56
58
|
|
57
59
|
defaultLocale = Locale.getDefault();
|
58
60
|
|
@@ -76,7 +78,7 @@
|
|
76
78
|
|
77
79
|
}
|
78
80
|
|
79
|
-
return new ContextWrapper(context.createConfigurationContext(configuration));
|
81
|
+
return new ContextThemeWrapper(context.createConfigurationContext(configuration), context.getTheme());
|
80
82
|
|
81
83
|
} else {
|
82
84
|
|
2
説明の修正
test
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
|
4
4
|
|
5
|
-
**追記**: Android N
|
5
|
+
**追記**: Android N未満ではLocale.getDefault()の値を書き換える必要があったので、それに対する対策コードも追記しました。TimePickerの代わりにCustomLocaleTimePickerをxml内に埋め込む等して利用してください。
|
6
6
|
|
7
7
|
|
8
8
|
|
@@ -30,7 +30,7 @@
|
|
30
30
|
|
31
31
|
public CustomLocaleTimePicker(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
32
32
|
|
33
|
-
super(getContextForLocale(context, Locale.
|
33
|
+
super(getContextForLocale(context, Locale.US), attrs, defStyleAttr);
|
34
34
|
|
35
35
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && defaultLocale != null) {
|
36
36
|
|
1
N未満でのコードの問題修正、カスタムViewの実装例追加
test
CHANGED
@@ -1,39 +1,99 @@
|
|
1
1
|
AndroidのViewはContextが保持している [Configuration](https://developer.android.com/reference/android/content/res/Configuration) というクラスからLocaleの設定を読み込んでいます。このLocaleを変更した状態のContextを生成し、TimePickerの生成時に渡すようにすればOKです。
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
**追記**: Android N以前ではLocale.getDefault()の値を書き換える必要があったので、それに対する対策コードも追記しました。TimePickerの代わりにCustomLocaleTimePickerをxml内に埋め込む等して利用してください。
|
2
6
|
|
3
7
|
|
4
8
|
|
5
9
|
```java
|
6
10
|
|
7
|
-
|
11
|
+
public class CustomLocaleTimePicker extends TimePicker {
|
8
12
|
|
9
|
-
public Context getContextForLocale(Context context, Locale locale) {
|
10
13
|
|
11
|
-
Configuration configuration = context.getResources().getConfiguration();
|
12
14
|
|
13
|
-
i
|
15
|
+
public CustomLocaleTimePicker(Context context) {
|
14
16
|
|
15
|
-
configuration.setLocale(locale);
|
16
|
-
|
17
|
-
return new ContextWrapper(context.createConfigurationContext(configuration));
|
18
|
-
|
19
|
-
} else {
|
20
|
-
|
21
|
-
Resources res = context.getResources();
|
22
|
-
|
23
|
-
configuration.locale = locale;
|
24
|
-
|
25
|
-
res.updateConfiguration(configuration, res.getDisplayMetrics());
|
26
|
-
|
27
|
-
|
17
|
+
this(context, null);
|
28
18
|
|
29
19
|
}
|
30
20
|
|
21
|
+
|
22
|
+
|
23
|
+
public CustomLocaleTimePicker(Context context, @Nullable AttributeSet attrs) {
|
24
|
+
|
25
|
+
this(context, attrs, 0);
|
26
|
+
|
31
|
-
}
|
27
|
+
}
|
32
28
|
|
33
29
|
|
34
30
|
|
35
|
-
|
31
|
+
public CustomLocaleTimePicker(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
36
32
|
|
37
|
-
|
33
|
+
super(getContextForLocale(context, Locale.JAPAN), attrs, defStyleAttr);
|
34
|
+
|
35
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && defaultLocale != null) {
|
36
|
+
|
37
|
+
// N未満で書き換えたLocaleのデフォルト値を元に戻す
|
38
|
+
|
39
|
+
Locale.setDefault(defaultLocale);
|
40
|
+
|
41
|
+
}
|
42
|
+
|
43
|
+
}
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
private static Locale defaultLocale;
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
private static Context getContextForLocale(@NonNull Context context, @NonNull Locale locale) {
|
52
|
+
|
53
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
54
|
+
|
55
|
+
// N未満ではLocaleのデフォルト値を参照してしまうので対策
|
56
|
+
|
57
|
+
defaultLocale = Locale.getDefault();
|
58
|
+
|
59
|
+
Locale.setDefault(locale);
|
60
|
+
|
61
|
+
}
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
Configuration configuration = new Configuration(context.getResources().getConfiguration());
|
66
|
+
|
67
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
68
|
+
|
69
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
70
|
+
|
71
|
+
configuration.setLocale(locale);
|
72
|
+
|
73
|
+
} else {
|
74
|
+
|
75
|
+
configuration.locale = locale;
|
76
|
+
|
77
|
+
}
|
78
|
+
|
79
|
+
return new ContextWrapper(context.createConfigurationContext(configuration));
|
80
|
+
|
81
|
+
} else {
|
82
|
+
|
83
|
+
Resources res = context.getResources();
|
84
|
+
|
85
|
+
configuration.locale = locale;
|
86
|
+
|
87
|
+
res.updateConfiguration(configuration, res.getDisplayMetrics());
|
88
|
+
|
89
|
+
return new ContextWrapper(context);
|
90
|
+
|
91
|
+
}
|
92
|
+
|
93
|
+
}
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
}
|
38
98
|
|
39
99
|
```
|