簡體   English   中英

使用 getPageTitle 在 kotlin android 中找不到字符串資源

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM