如何获取与 TextView 关联的字符串资源的 id?

问题描述 投票:0回答:2

我可以访问 TextView 实例,获取它的资源 ID 并通过

getResources().getResourceEntryName()
获取它的资源名称,但我似乎无法找到一种方法来获取与其关联的字符串的 ID。

如何动态获取与 TextView 关联的字符串资源的 ID?

android textview android-resources
2个回答
1
投票

你不能。如果您调用

TextView
setText(int resid)
不会存储字符串资源的 ID。这个重载方法所做的就是从资源中获取字符串并调用
setText(CharSequence text)
方法。


1
投票

我唯一的解决方法是将布局 xml 中 TextView 实例的

+id
与字符串的
name
匹配,然后使用 Resources 将两者配对:

/**
     * 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 的交换文本字段的方法

这行得通,但它几乎是一个 hack.

最终我还需要以编程方式更改 Google 手写输入语言,为此 Juuso 的 ADB 更改语言 应用程序非常方便。

作为参考,这里有一个使用 Juuso 方法的函数:

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 your.app.package.here android.permission.CHANGE_CONFIGURATION )");
            e.printStackTrace();
        }
    }

记得将

CHANGE_CONFIGURATION
授予您的应用程序。

这是在 Android 7.1.1 上测试的,但请记住,它会在 Android 8.0(和可能向上)上失败,因为在某些构建条件下找不到

getConfiguration
(API 不同)。

该方法需要一个 ArrayList 的 Locale 对象,其中包含您要更改为顶部的语言: 例如

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"));

确保语言也安装在设备上。

如果您有其他改进建议,我很乐意更新答案

© www.soinside.com 2019 - 2024. All rights reserved.