How to get a default string value from resources in SafeArgs?
Asked Answered
H

3

15

I'm just learning a Android NavigationUI, and try set a toolbar title using string default value from Safe Args. But have some problem about it.

'String resources' file:

    <string name="title_add_item">Add new items</string>

Navigation graph file. Set label as Title: {title} argument.

<navigation 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"
android:id="@+id/nav_graph"
app:startDestination="@id/mainFragment">

<fragment
    android:id="@+id/addNewItemFragment"
    android:name="com.myapplication.AddNewItemFragment"
    android:label="Title: {title}"
    tools:layout="@layout/fragment_add_new_item" >
    <argument
        android:name="title"
        app:argType="string"
        android:defaultValue="@string/title_add_item" />
</fragment>
<fragment
    android:id="@+id/mainFragment"
    android:name="com.myapplication.MainFragment"
    android:label="fragment_main"
    tools:layout="@layout/fragment_main" >
    <action
        android:id="@+id/action_to_add_items_fragment"
        app:destination="@id/addNewItemFragment" />
</fragment>

If {app:argType="string"} I got an error :

 Caused by: org.xmlpull.v1.XmlPullParserException: unsupported value 'Add new items' for string. You must use a "reference" type to reference other resources.

If {app:argType="reference"} app works, but i have a number in title (i think it's a resource id):

enter image description here

Of course I can assign the value of the toolbar title in the code by getting it from the arguments. But is it possible to change this code so that the title filled in correctly?

Heighten answered 30/7, 2019 at 15:17 Comment(1)
I found that it's a bugParliamentary
P
2

References to resources are supported only in reference types. Using a resource reference in any other type results in an exception.

Feel free to star the existing issue: https://issuetracker.google.com/issues/167959935. For the time being, u can hardcode the string value with app:argType="string" or try setting programmatically until it gets resolved.

enter image description here

Parliamentary answered 14/11, 2020 at 8:6 Comment(0)
J
0

Take a look over here.

You don't need to use arguments to set a static title. You can just set the title you want to appear in the toolbar to the fragment in the navigation graph with android:label.

<fragment
    android:id="@+id/addNewItemFragment"
    android:name="com.myapplication.AddNewItemFragment"
    android:label="@string/title_add_item"
    tools:layout="@layout/fragment_add_new_item" >

Then setup the toolbar using setupWithNavController

val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(navController.graph)
findViewById<Toolbar>(R.id.toolbar)
    .setupWithNavController(navController, appBarConfiguration)

This way you don't need to override onSupportNavigateUp and the title will automatically update once you navigate to another fragment.

If for some reason you really want to combine the argument with the value in android:label then there is no other way but using app:argType="reference" and combining the two in your code.

Jowers answered 5/8, 2020 at 17:32 Comment(1)
Yes, but idea was automatic set title from "defaultValue" saveArg variable if that variable doesn't set.Heighten
A
0

You can just make it as a reference type and set it and get as reference/resource with getString(args.title)

nav_graph.xml

<fragment
    android:id="@+id/choose_scanner"
    android:name="com.myapp.ChooseScannerFragment"
    tools:layout="@layout/fragment_choose_scanner">
    <action
        android:id="@+id/action_scan_with_camera"
        app:destination="@+id/qr_scanner" />
</fragment>

<fragment
    android:id="@+id/qr_scanner"
    android:name="com.myapp.ScanFragment"
    tools:layout="@layout/fragment_scan">
    <argument
        android:name="show_back_button"
        android:defaultValue="false"
        app:argType="boolean" />

    <argument
        android:name="title"
        android:defaultValue="@string/connect_printer_device"
        app:argType="reference" />

    <argument
        android:name="message"
        android:defaultValue="@string/scan_printer_message"
        app:argType="reference" />
</fragment>

ChooseScannerFragment

 findNavController().navigate(ChooseScannerFragmentDirections.actionScanWithCamera(
                    showBackButton = true,
                    title = R.string.step_1_scan_reference,
                    message = R.string.scan_reference_message
                ))

ScanFragment.kt

binding.message.text = getString(args.message)
        binding.title.text = getString(args.title)
        binding.back.visibility = if (args.showBackButton) View.VISIBLE else View.INVISIBLE
Adsorb answered 23/12, 2021 at 9:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.