【问题标题】:Android: How do I get string from resources using its name?Android:如何使用名称从资源中获取字符串?
【发布时间】:2011-11-21 12:56:12
【问题描述】:

我想在我的资源文件res\values\strings.xml 中为 UI 提供 2 种语言并为它们单独的字符串值:

<string name="tab_Books_en">Books</string>
<string name="tab_Quotes_en">Quotes</string>
<string name="tab_Questions_en">Questions</string>
<string name="tab_Notes_en">Notes</string>
<string name="tab_Bookmarks_en">Bookmarks</string>

<string name="tab_Books_ru">Книги</string>
<string name="tab_Quotes_ru">Цитаты</string>
<string name="tab_Questions_ru">Вопросы</string>
<string name="tab_Notes_ru">Заметки</string>
<string name="tab_Bookmarks_ru">Закладки</string>

现在我需要在我的应用中动态检索这些值:

spec.setContent(R.id.tabPage1);
String pack = getPackageName();
String id = "tab_Books_" + Central.lang;
int i = Central.Res.getIdentifier(id, "string", pack);
String str = Central.Res.getString(i);

我的问题是i = 0

为什么它在我的情况下不起作用?

【问题讨论】:

  • 您确定 Central.lang 是 en 还是 ru
  • 需要更多信息来检查您的代码。在得到 i 之前每个 var 的状态是什么?无论如何,您应该使用 Android 中的默认本地化支持来保持简单。

标签: android string resources


【解决方案1】:

您所指的链接似乎适用于运行时生成的字符串。 strings.xml 中的字符串不是在运行时创建的。 你可以通过

String mystring = getResources().getString(R.string.mystring);

getResources()Context 类的方法。如果您在 ActivityService(扩展 Context)内,您可以像在这个 sn-p 中一样使用它。

另外请注意,整个语言依赖都可以由 android 框架处理。 只需为每种语言创建不同的文件夹。如果英语是您的默认语言,只需将英语字符串放入res/values/strings.xml。然后新建文件夹values-ru,将同名的俄语字符串放入res/values-ru/strings.xml。从这一点开始,android 会根据您的设备区域设置选择正确的一个,无论是当您调用 getString() 还是通过 @string/mystring 引用 XML 中的字符串时。 res/values/strings.xml 中的那些是备用的,如果您没有覆盖用户区域设置的文件夹,则该文件夹将用作默认值。

请参阅LocalizationProviding Resources 了解更多信息。

【讨论】:

  • 如果你在android.support.v4.app.Fragment,你可以直接打电话给getString(R.string.mystring)
  • 我只是在徘徊。为什么(由谷歌)以如此复杂的方式完成?首先获取 mystring 的数字 ID(来自 R 对象),然后通过该 ID 获取字符串?以及“ID-of-mystring => actualValue”这对实际驻留在哪里?据我所知 mystring=>ID-of-mystring 在 R.java 中,但就是这样 :)
  • 确保“R”是您项目的 R 而不是默认的 android R。
  • 这可能是所需要的答案,但不是所要求的答案!要按名称动态访问字符串资源,请参阅@leonvian 的答案 ... 这应该是 IMO 接受的一个
【解决方案2】:

验证您的 packageName 是否正确。您必须参考您的 Android 应用程序的根包。

private String getStringResourceByName(String aString) {
      String packageName = getPackageName();
      int resId = getResources().getIdentifier(aString, "string", packageName);
      return getString(resId);
    }

【讨论】:

  • 如果有人有充分的理由这样做(例如,数据文件包含一个自定义字符串,该字符串决定应该显示哪个资源字符串,或者该字符串是从 Internet 获取的)——那么我想指出,这个解决方案是正确的。尤其要更正资源类型为string 而不是strings 的部分。因为这是合乎逻辑的(就像 Android 的其他部分一样)。所以,谢谢你(以及更多),@leonvian。 :-)
  • @Sameer 通过字符串获取数组只需使用: res.getStringArray(R.array.planets_array);看看这个官方链接:developer.android.com/guide/topics/resources/…
  • 酷。为了摆脱单独的方法声明,可以通过以下方式“简化”:String someStringFromXML = getString(getResources().getIdentifier("some_string_name", "string", getPackageName()));.
  • 谢谢!当从 Internet 获取字符串时,这是一个很好的解决方案。我正在实现一个聊天,它可以在设备之间传递系统消息。设备可能有不同的语言,我必须以接收设备的语言显示消息。
  • 不要忘记处理“Resources.NotFoundException”,否则您以后可能会遇到问题。
【解决方案3】:

不仅来自活动:

public static String getStringByIdName(Context context, String idName) {
    Resources res = context.getResources();
    return res.getString(res.getIdentifier(idName, "string", context.getPackageName()));
}

【讨论】:

    【解决方案4】:
    getResources().getString(getResources().getIdentifier("propertyName", "string", getPackageName()))
    

    【讨论】:

      【解决方案5】:

      我会在 leonvian 的解决方案中添加一些内容,因此如果在资源中找不到字符串(返回值 0,这不是有效的资源代码),该函数可能会返回一些内容:

      private String getStringResourceByName(String aString) {
          String packageName = getPackageName();
          int resId = getResources()
                  .getIdentifier(aString, "string", packageName);
          if (resId == 0) {
              return aString;
          } else {
              return getString(resId);
          }
      }
      

      【讨论】:

        【解决方案6】:

        最佳方法

        App.getRes().getString(R.string.some_id)

        在任何地方都可以使用(Utils,Models 也一样)。

        我已经阅读了所有的答案,所有的答案都可以让你的工作完成。

        • 您可以在 ActivityFragment 中使用 getString(R.string.some_string_id)
        • 您可以在无法直接访问getString() 方法的情况下使用Context.getString(R.string.some_string_id)。喜欢Dialog

        问题

        您没有Context 访问权限时,例如您的Util 类中的方法。

        假设下面的方法没有上下文。

        public void someMethod(){
            ...
            // can't use getResource() or getString() without Context.
        }
        

        现在您将在此方法中将Context 作为参数传递并使用getString().

        public void someMethod(Context context){
            ...
            context.getString(R.string.some_id);
        }
        

        我所做的是

        public void someMethod(){
            ...
            App.getAppResources().getString(R.string.some_id)
        }
        

        什么?在您的应用中的任何位置使用都非常简单!

        所以这里有一个解决方案,您可以通过它从任何地方访问资源,例如Util class

        import android.app.Application;
        import android.content.res.Resources;
        
        public class App extends Application {
            private static Resources resources;
        
            @Override
            public void onCreate() {
                super.onCreate();
        
                resources = getResources();
            }
        
            public static Resources getAppResources() {
                return resources;
            }
        
        }
        

        将名称字段添加到您的 manifest.xml &lt;application 标记。

        <application
                android:name=".App"
                ...
                >
                ...
            </application>
        

        现在你可以走了。在应用中的任何位置使用App.getAppResources().getString(R.string.some_id)

        【讨论】:

        • +1 简单干净的解决方案。注意拼写错误getResoursesgetResources 会导致覆盖。此外,单例模式似乎没有必要,可能可以跳过。此解决方案是否存在内存泄漏问题?
        • @Xarvalus 这会导致内存泄漏吗?
        • 在我的应用程序中一切正常 :) 只是想知道是否有人对此有任何问题。如果我遇到任何陷阱,我会告诉你。
        • @Xarvalus 内存泄漏通常发生在使用变量的地方,即使父类被破坏。就像在活动,片段中一样。我认为这种情况不会发生。
        【解决方案7】:

        更简单的方法是在活动中使用getString() 函数。

        String myString = getString(R.string.mystring);
        

        参考:http://developer.android.com/guide/topics/resources/string-resource.html

        我认为这个功能是在最近的Android版本中添加的,任何知道历史的人都可以对此发表评论。

        【讨论】:

          【解决方案8】:

          从字符串中获取资源字符串到 TextView 的简单方法。这里resourceName是资源的名称

          int resID = getResources().getIdentifier(resourceName, "string", getPackageName());
          textview.setText(resID);
          

          【讨论】:

            【解决方案9】:

            getResources() 仅在您在 ActivityFragment 班级时有效。

            • 随时随地访问字符串资源,

            使用:

            Resources.getSystem().getString(android.R.string.somecommonstuff)
            

            【讨论】:

              【解决方案10】:

              如果你没有 Activity 引用,你可以这样使用你的上下文:

              getContext().getString(R.string.your_string_name);
              

              【讨论】:

                【解决方案11】:

                如果你使用的是Kotlin,你可以定义一个扩展函数如下:

                fun Context.getStringResourceByName(stringName: String): String? {
                    val resId = resources.getIdentifier(stringName, "string", packageName)
                    return getString(resId)
                }
                

                然后简单地使用它。例如,在 Puzzles 应用中,我根据图像文件名设置 Activity 标题:

                val stringName = "${folderName}_${assetName.substringBefore(".")}"
                title = getStringResourceByName(stringName)
                

                在这个例子中,我正在读取基于动态名称的字符串资源。

                【讨论】:

                  【解决方案12】:

                  还有一组预定义的 Android 字符串,例如“Ok”、“Cancel”和许多其他字符串 - 因此您不必全部声明。只需通过以下方式获得它们:

                  getString(android.R.string.ok)
                  

                  (在这种情况下,“Ok”字符串)。顺便说一句,还有其他可用的 Android 资源,例如图标图像等。

                  【讨论】:

                    【解决方案13】:

                    在 Kotlin 中,利用扩展函数?

                    fun Context.getStringByName(name: String): String {
                        return getString(resources.getIdentifier(name, "string", packageName))
                    }
                    

                    【讨论】:

                      【解决方案14】:

                      String myString = getString(R.string.mystring);

                      简单的方法

                      【讨论】:

                        【解决方案15】:

                        如果您不想在活动或片段网络中获取它,那么:

                        getContext().getResources().getString(R.string.string_name);
                        

                        如果您想从没有活动上下文的活动或片段之外的类中获取它,请使用应用程序上下文:

                        getApplicationContext().getResources().getString(R.string.string_name);
                        

                        【讨论】:

                          【解决方案16】:

                          您可以在 Activity 中尝试:

                          getResources().getString(R.string.your string name);
                          

                          在片段等其他情况下,...使用

                          getContext().getResources().getString(R.string.your string name);
                          

                          【讨论】:

                            【解决方案17】:

                            为了安全起见,您应该添加: mContext.getResources().getString(R.string.your_string);

                            mContext 可以是:Fragment 的 onAttach() 或 Activity 的 this 中的上下文。

                            【讨论】:

                              【解决方案18】:
                              R.string.<string_name>
                              

                              直接在您的 java 文件中使用该行。保持简单。

                              【讨论】:

                              • 这不会一直有效。该字符串最终可能会显示为地址编号。
                              猜你喜欢
                              • 2017-02-22
                              • 1970-01-01
                              • 2011-05-24
                              • 1970-01-01
                              • 2023-03-07
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              相关资源
                              最近更新 更多