我发现R.string非常棒,可以将硬编码的字符串排除在代码之外,我希望在与应用程序中的模型一起工作的实用程序类中继续使用它来生成输出。例如,在本例中,我从活动外部的模型生成了一封电子邮件。

是否可以在上下文或活动之外使用getString ?我想我可以通过目前的活动,但似乎没有必要。如果我说错了,请指正!

编辑:我们可以在不使用上下文的情况下访问资源吗?


当前回答

如果你正在使用Hilt,你实际上可以注入上下文:

@Module
@InstallIn(SingletonComponent::class)
interface ResourceProvider {

    companion object {
    
    @Provides
    @Singleton
    @MyQualifier
    fun providesBaseUrl(@ApplicationContext context: Context): String = with(context) {
      getString(R.string.my_value)
    }
  }
}

其他回答

不知何故,我不喜欢存储静态值的俗气解决方案,所以提出了一个更长的,但干净的版本,可以测试以及。

找到了两种可能的方法

通过上下文。Resources作为类的参数,在其中您需要字符串资源。相当简单。如果不能作为参数传递,则使用setter。

e.g.

data class MyModel(val resources: Resources) {
    fun getNameString(): String {
        resources.getString(R.string.someString)
    }
}

使用数据绑定(尽管需要片段/活动)

阅读之前:本版本使用数据绑定

XML-

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>
    <variable
        name="someStringFetchedFromRes"
        type="String" />
</data>

<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@{someStringFetchedFromRes}" />
</layout>

活动/片段-

val binding = NameOfYourBinding.inflate(inflater)
binding.someStringFetchedFromRes = resources.getString(R.string.someStringFetchedFromRes)

有时,您需要根据模型中的字段更改文本。所以你也会数据绑定那个模型,因为你的activity/fragment知道这个模型,你可以很好地获取值,然后基于它数据绑定字符串。

不幸的是,你能访问任何字符串资源的唯一方法是一个上下文(即一个活动或服务)。在这种情况下,我通常做的是简单地要求调用者传递上下文。

是的,我们可以不使用“上下文”来访问资源

你可以使用:

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

... 在应用程序的任何地方,甚至在静态常量声明中。 不幸的是,它只支持系统资源。

对于本地资源,请使用此解决方案。这不是小事,但很有效。

以下是基于Khemraj Sharma的回答,这是Kotlin版本,有一个额外的扩展作为奖励:

class App: Application() {

    override fun onCreate() {
        super.onCreate()
        mInstance = this
        res = resources
    }
    companion object{

        private var mInstance: App? = null
        private var res: Resources? = null

        fun getInstance(): App? {
            return mInstance
        }

        fun getRes(): Resources? {
            return res
        }
    }
}

然后我们可以创建一个扩展:

fun Int.resourceToString(): String {
    return App.getRes()?.getString(this) ?: "Not Found"
}

并直接在任何资源id上使用扩展:

var asString = R.string.my_string.resourceToString()

我使用 getContext () .getApplicationContext () .getString (R.string.nameOfString); 这对我很管用。