英文:
how to get a value from resource file in the main Activity class when using fragments?
问题
以下是您要翻译的部分:
"我正在开发一个带有片段的应用程序,我想在MainActivity.kt中使用“strings.xml”中的一个值。这些是选项卡的名称。但是,如果我这样做:
private var title: String = getText(R.string.title).toString()
当我运行代码时,我会收到以下错误:
java.lang.NullPointerException: 尝试调用虚拟方法
'android.content.res.Resources android.content.Context.getResources()'
时出现空对象引用
如果我这样做:
private var title = getText(R.string.title)
我还会收到错误,如果我这样做:
private var title = R.string.title
我会得到一个整数。我该如何获取我在<string name="title">Start</string>
中实际的文本?"
英文:
I'm developing an app with fragments and I want to use a value from "strings.xml" in MainActivity.kt. These are the names of the tabs. But, if I do this:
private var title: String = getText(R.string.title).toString()
I get this error when I run the code:
> java.lang.NullPointerException: Attempt to invoke virtual method
> 'android.content.res.Resources android.content.Context.getResources()'
> on a null object reference
If I do:
private var title = getText(R.string.title)
I also get the error and if I do:
private var title = R.string.title
I get an integer.
How can I get the atual text I have in <string name="title">Start</string>
?
答案1
得分: 0
你应该使用getString(),而且函数getString(以及getText)要求你的活动被实例化。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var title = getString(R.string.title)
英文:
You should use getString(), and the function getString (as well as getText) requires your activity to be instantiated.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var title = getString(R.string.title)
答案2
得分: 0
在诸如“Activities”和“Fragments”之类的地方,小心使用在表达式中需要“Context”的顶级变量赋值。它们在构建时没有 *Context*,系统稍后提供 - 这就是你看到这种错误的方式(在你的情况下,它试图在应该是“Context”的东西上调用`getResources()`,但实际上它是 *null*)。
片段的`Context`在[进入`CREATED`状态时已经被附加][1],因此可以在`onCreate`或之后安全地访问它。因此,您可以使您的顶级变量`lateinit`(推迟赋值),并稍后设置其值:
// 定义没有值的变量 - 必须在读取之前设置值!
private lateinit var title: String
override fun onCreate(savedInstanceState: Bundle?) {
...
// 在可以时赋值
title = getText(R.string.title).toString()
}
或者,您可以使用`lazy`委托,它将在第一次访问变量时通过运行设置函数设置值:
private val title: String by lazy {
getText(R.string.title).toString()
}
如果在`Context`可用之前调用函数,这将失败,因此在这两种情况下,您必须能够保证没有任何东西尝试过早地从中读取。`lazy`可能更整洁(没有单独的赋值),但它确实使值只读,而不是`var` - 在这种情况下可能没关系!
此外,如果您明确想要`String`而不是`CharSequence`,只需调用`getString`而不是`getText`。
[1]: https://developer.android.com/guide/fragments/lifecycle#fragment_created
英文:
You need to be careful assigning top-level variables in things like Activities
and Fragments
with expressions that require a Context
. They don't have one at construction time, the system provides that later - that's how you end up seeing this kind of error (in your case, it's trying to call getResources()
on something that should be a Context
, but it's actually null).
A fragment's Context
has been attached by the time it enters the CREATED state, so it's safe to access it in onCreate
or later. So you can make your top-level variable lateinit
(deferring assignment) and set the value on it later:
// define the variable without a value - you need to set a value before this is read!
private lateinit var title: String
override fun onCreate(savedInstanceState: Bundle?) {
...
// assign the value when you can
title = getText(R.string.title).toString()
}
Or you could use a lazy
delegate, which will set the value the first time the variable is accessed, by running a setter function:
private val title: String by lazy {
getText(R.string.title).toString()
}
This will fail if the function is called before the Context
is available too, so in both situations you have to be able to guarantee nothing will try to read from it too early. The lazy
is arguably neater (no separate assignment) but it does make the value read-only, instead of a var
- that's probably fine in this situation!
Also if you specifically want a String
instead of a CharSequence
, just call getString
instead of getText
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论