TextViewインスタンスにアクセスしてリソースIDを取得し、リソース名をgetResources().getResourceEntryName()
で取得できますが、関連する文字列のIDを取得する方法が見つからないようです。TextViewに関連付けられた文字列リソースのIDを取得する方法は?
TextViewに関連付けられた文字列リソースのIDを動的に取得するにはどうすればよいですか?
TextViewインスタンスにアクセスしてリソースIDを取得し、リソース名をgetResources().getResourceEntryName()
で取得できますが、関連する文字列のIDを取得する方法が見つからないようです。TextViewに関連付けられた文字列リソースのIDを取得する方法は?
TextViewに関連付けられた文字列リソースのIDを動的に取得するにはどうすればよいですか?
私は2つのペアを取得するためのリソースを使用し、その後、文字列のname
とレイアウトXMLでのTextViewインスタンスの+id
に一致するようにした可能性が唯一の回避策:
/**
* finds a string id matching a text view id name and returns the value
* @param textView - text view
* @param context - the context
* @param locale - the locale string
* @return String - resource string if found, empty string otherwise
*/
public static String getTextViewStringFromResources(TextView textView,Context context,String locale){
String result = "";
final int textViewID = textView.getId();
if(textViewID <= 0){
Log.e(TAG,"invalid id for textView " + textView + " text = " + textView.getText());
result = textView.getText().toString();
return result;
}
//get resources (re-usable)
final Resources resources = getLocalizedResources(context,locale);
// get textViews id
final String entryName = resources.getResourceEntryName(textView.getId());
// get the string id !! must match the textview id !!
final int stringID = resources.getIdentifier(entryName,"string",context.getPackageName());
//return string value for string id found by textview id
try{
result = resources.getString(stringID);
}catch (Resources.NotFoundException e){
Log.e(TAG,"couldn't find a string id for " + entryName);
Log.e(TAG,e.getMessage());
}
return result;
}
//!! requires minSDK 17
@NonNull
public static Resources getLocalizedResources(Context context, String locale) {
Locale desiredLocale = new Locale(locale);
Configuration conf = context.getResources().getConfiguration();
conf.setLocale(desiredLocale);
Context localizedContext = context.createConfigurationContext(conf);
return localizedContext.getResources();
}
スワップが部分的に基づいていますスワッピングテキストフィールドのGunhan Sancar's methodにあります。
これは動作しますが、かなりハックです。
最終的にはGoogleの手書き入力言語をプログラムで変更する必要があり、そのためJuuso's ADB Change Languageアプリが手軽に利用できるようになりました。
final String TAG = "ChangeLanguage"
//change language utils "kindly borrowed" from net.sanapeli.adbchangelanguage: brilliant little app!
/**
* updates a Configuration with a list of Locales
* @param configuration - a configuration to updated
* @param arrayList - an ArrayList of Locale instances
* @return the updated configuration
*/
@TargetApi(24)
public static Configuration addLocalesToConfiguration(Configuration configuration, ArrayList<Locale> arrayList) {
configuration.setLocales(new LocaleList((Locale[]) arrayList.toArray(new Locale[arrayList.size()])));
return configuration;
}
/**
* Change the system language
* @param lanaguageList - a list of Locale instances to change to
*/
public static void changeLanguages(ArrayList<Locale> lanaguageList){
try {
Class cls = Class.forName("android.app.ActivityManagerNative");
Method method = cls.getMethod("getDefault", new Class[0]);
method.setAccessible(true);
Object invoke = method.invoke(cls, new Object[0]);
method = cls.getMethod("getConfiguration", new Class[0]);
method.setAccessible(true);
Configuration configuration = (Configuration) method.invoke(invoke, new Object[0]);
configuration.getClass().getField("userSetLocale").setBoolean(configuration, true);
if (VERSION.SDK_INT >= 24) {
configuration = addLocalesToConfiguration(configuration, lanaguageList);
} else {
configuration.locale = (Locale) lanaguageList.get(0);
}
Method method2 = cls.getMethod("updateConfiguration", new Class[]{Configuration.class});
method2.setAccessible(true);
method2.invoke(invoke, new Object[]{configuration});
Log.d(TAG,"locale updated to" + lanaguageList.get(0).toString());
} catch (Exception e) {
Log.e(TAG,"error changing locale (double check you're granted permissions to the app first: pm grant com.hirschandmann.googlearts android.permission.CHANGE_CONFIGURATION)");
e.printStackTrace();
}
}
アプリにCHANGE_CONFIGURATION
を付与することを忘れないでください:
は参考のため、ここではJuusoのアプローチを使用して機能です。
これはAndroid 7.1.1でテストされていますが、特定のビルド条件ではgetConfiguration
が見つからないため、Android 8.0(および潜在的に上向き)で失敗する可能性があることに注意してください。
このメソッドは、変更したい言語のLocaleオブジェクトのArrayListが、上に と期待しています。
ArrayList<Locale> fr = new ArrayList<Locale>();
fr.add(new Locale("fr"));
fr.add(new Locale("en"));
ArrayList<Locale> en = new ArrayList<Locale>();
en.add(new Locale("en"));
en.add(new Locale("fr"));
デバイスにも言語がインストールされていることを確認してください。
改善提案が他にもある場合は、回答を更新して幸いです。
できません。 A TextView
は、setText(int resid)
を呼び出すと、StringリソースのIDを格納しません。このオーバーロードされたメソッドはすべて、リソースからStringを取得し、setText(CharSequence text)
メソッドを呼び出します。
うん、それは楽しいことではありません。欲しいものはありますか? –
あなたのユースケースは何か分かりませんが、自分のコードでTextViewに最後に設定したStringリソースを追跡することができます。 – Sander
私はアプリケーションの内部だけで、完全なOS設定を変更せずにロケール文字列を交換しています。 'setContentView'がアクティビティに対して呼び出された後はありますか? –