[英]String resource not found in kotlin android with getPageTitle
此处是 android 和 kotlin 的新手。 制作我的第一个应用程序,我正在尝试使用getPageTitle
function 为我的标签提供标题(其中是字符串资源)。 完整的实现如下:
class FAAMainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar as Toolbar)
val pagerAdapter = SectionsPagerAdapter(supportFragmentManager, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
pager.adapter = pagerAdapter
tabs.setupWithViewPager(pager)
}
private class SectionsPagerAdapter : FragmentPagerAdapter{
constructor(fm: FragmentManager, behavior: Int) : super(fm, behavior)
override fun getItem(position: Int): Fragment {
when (position) {
0 -> return HomeFragment()
1 -> return KittensFragment()
2 -> return CatsFragment()
3 -> return FosterersFragment()
4 -> return FAAUsersFragment()
else -> {
return HomeFragment()
}
}
}
override fun getCount(): Int {
return 5
}
override fun getPageTitle(position: Int): CharSequence? {
when(position) {
0 -> Resources.getSystem().getText(R.string.home_tab)
1 -> Resources.getSystem().getText(R.string.kitten_tab)
2 -> Resources.getSystem().getText(R.string.cat_tab)
3 -> Resources.getSystem().getText(R.string.fosterer_tab)
4 -> Resources.getSystem().getText(R.string.faa_user_tab)
else -> "Error"
}
return "Error"
}
}
}
尝试运行应用程序会出现以下错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{uk.ac.aber.dcs.cs31620.faa/uk.ac.aber.dcs.cs31620.faa.ui.FAAMainActivity}: android.content.res.Resources$NotFoundException: String resource ID #0x7f0d0027
我不明白为什么它找不到字符串资源。
我的字符串。xml;
<resources>
<string name="app_name">Feline Adoption Agency</string>
<string name="hello_blank_fragment">Hello blank fragment</string>
<string name="home_tab">Home</string>
<string name="kitten_tab">Kittens</string>
<string name="cat_tab">Cats</string>
<string name="fosterer_tab">Fosterers</string>
<string name="faa_user_tab">FAA Users</string>
</resources>
更多信息,因为我对此悬赏:
app/build/generated/not_namespaced_r_class_sources/debug/r/uk/ac/aber/dcs/cs31620/faa/R.java
文件中。app/build/generated/not_namespaced_r_class_sources/debug/r/androidx/appcompat/R.java
我不确定这是问题的原因。 我对FAAMainActivity
class 的进口是:
import android.content.res.Resources import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentPagerAdapter import kotlinx.android.synthetic.main.activity_main.* import uk.ac.aber.dcs.cs31620.faa.R import uk.ac.aber.dcs.cs31620.faa.ui.cats.CatsFragment import uk.ac.aber.dcs.cs31620.faa.ui.faa_users.FAAUsersFragment import uk.ac.aber.dcs.cs31620.faa.ui.fosterers.FosterersFragment import uk.ac.aber.dcs.cs31620.faa.ui.home.HomeFragment import uk.ac.aber.dcs.cs31620.faa.ui.kittens.KittensFragment
如果有人想尝试一下,我已经在这里上传了这个项目。
根据文档,调用Resources.getSystem()
提供系统级资源,而不是您的应用程序级资源:
返回一个全局共享资源 object,它只提供对系统资源(无应用程序资源)的访问,并且没有为当前屏幕配置(不能使用维度单位,不改变基于 n 方向等)。
您需要应用程序或活动级别上下文才能从您的 strings.xml 中检索字符串。 我已将您的SectionsPagerAdapter
更改为此以修复您的错误:
private class SectionsPagerAdapter(fm: FragmentManager, behavior: Int, private val context: Context) :
FragmentPagerAdapter(fm, behavior) {
override fun getItem(position: Int): Fragment {
return when (position) {
0 -> HomeFragment()
1 -> KittensFragment()
2 -> CatsFragment()
3 -> FosterersFragment()
4 -> FAAUsersFragment()
else -> {
HomeFragment()
}
}
}
override fun getCount(): Int {
return 5
}
override fun getPageTitle(position: Int): CharSequence? {
return when(position) {
0 -> context.getString(R.string.kitten_tab)
1 -> context.getString(R.string.kitten_tab)
2 -> context.getString(R.string.cat_tab)
3 -> context.getString(R.string.fosterer_tab)
4 -> context.getString(R.string.faa_user_tab)
else -> context.getString(R.string.home_tab)
}
}
}
FAAMainActivity
val pagerAdapter = SectionsPagerAdapter(supportFragmentManager, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT, this) // Passed "this" as context
在这里,我主要更改了您代码中的以下内容,
从
private class SectionsPagerAdapter : FragmentPagerAdapter{
constructor(fm: FragmentManager, behavior: Int) : super(fm, behavior)
...
}
至
private class SectionsPagerAdapter(fm: FragmentManager, behavior: Int, private val context: Context) :
FragmentPagerAdapter(fm, behavior) {
...
}
我已将您的 JAVA 样式构造函数更改为 kotlin 的主构造函数,并将Context
添加为第三个参数。 现在我们将使用该Context
而不是Resources.getSystem()
来获取字符串。
利用
Resources.getSystem().getString(R.string.faa_user_tab)
代替
Resources.getSystem().getText(R.string.faa_user_tab)
如Resources的文档中所述,方法getSystem() :
返回一个全局共享资源 object,它只提供对系统资源(没有应用程序资源)的访问,没有为当前屏幕配置(不能使用维度单位,不根据方向改变等),并且不受运行时资源的影响覆盖。
因此,您无法通过此方法访问您的应用程序资源。 但是看看你的代码,你可以简单地改变
private class SectionsPagerAdapter
至:
private inner class SectionsPagerAdapter
当你想获取字符串而不是
Resources.getSystem().getString(R.string.kitten_tab)
做这个:
getString(R.string.kitten_tab)
说明:当您将 class 标记为inner
时,您正在使外部 class 中的每个方法以及其他内容在内部 class中可见和可访问。 在每个Activity (任何Context )中都有访问资源的方法。 其中之一是getString
,您可以简单地使用它来通过它们的 id 获取字符串。
我知道我没有直接回答您的问题,但可以通过更改您创建/使用适配器的方式来解决问题。
主要的变化是,我们将“责任”交给用户,而不是让适配器决定如何填充视图。
我们通过请求页面列表来做到这一点,在此示例中,我使用了Pair<String, Fragment>
但您可以使用所需的所有必要信息创建实际数据 model。
class SectionsPagerAdapter(
fragmentManager: FragmentManager,
behavior: Int,
val pages: List<Pair<String, Fragment>>
) : FragmentPagerAdapter(fragmentManager, behavior) {
override fun getItem(position: Int): Fragment = pages[position].second
override fun getCount(): Int = pages.size
override fun getPageTitle(position: Int): CharSequence = pages[position].first
}
当您创建适配器时,您可以像这样在Activity/Fragment
中创建它
val pages = listOf( /* Change the list to fit your exact needs*/
context.getString(R.string.kitten_tab) to HomeFragment(),
context.getString(R.string.kitten_tab) to KittensFragment(),
context.getString(R.string.cat_tab) to CatsFragment(),
context.getString(R.string.fosterer_tab) to FosterersFragment(),
context.getString(R.string.faa_user_tab) to FAAUsersFragment()
)
val adapter = SectionsPagerAdapter(
supportFragmentManager,
FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT,
pages
)
这样,您不仅可以解决问题,还可以获得一个可扩展的解决方案,该解决方案不仅支持此用例,还支持任何其他用例
适用于您的方法的代码是:
Resources.getSystem().getText(android.R.string.cancel) // returns Cancel
Resources.getSystem().getString(android.R.string.cancel) // returns Cancel
Resources.getSystem().getResourceName(android.R.string.cancel)) //returns android:string/cancel
Resources.getSystem().getResourceEntryName(android.R.string.cancel)) returns cancel
但在所有情况下,使用的字符串都以android.R开头,这意味着您只能使用这些方法访问内置资源的 android。
我不知道您为什么要尝试使用上述方法访问您的字符串资源。
下面我列出了访问您的应用相关资源的某些方法:
getResources().getText(R.string.app_name)); // returns Test App
getResources().getString(R.string.app_name)); // returns Test App
getResources().getResourceEntryName(R.string.app_name)); // returns app_name
getResources().getResourceName(R.string.app_name)); //returns com.example.testapp:string/app_name
context.getText(R.string.app_name)); // returns Test App
context.getString(R.string.app_name)); // returns Test App
您也可以使用上下文来访问以getResources()开头的方法。
我认为您以错误的方式调用字符串资源。 它应该是这样的: -
override fun getPageTitle(position: Int): CharSequence? {
when(position) {
0 -> getString(R.string.home_tab) // just call getString() bcz, calling from AppCompatActivity
1 -> getString(R.string.kitten_tab) // if you use fragment and try to call
2 -> getString(R.string.cat_tab) // getString(), use resources.getString(...)
3 -> getString(R.string.fosterer_tab)
4 -> getString(R.string.faa_user_tab)
else -> "Error"
}
return "Error"
}
试试这个,希望你的问题能得到解决。 如果有任何问题进一步出现,请告诉我。 快乐编码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.