Menu
Who Do Is
  • Home
  • What
  • How
  • Is
  • Can
  • Are
  • Does
  • Do
  • Why
  • Who
  • Where
  • Which
  • Which
  • Should
  • Will
  • When
  • What’s
  • Did
Who Do Is

[ANSWERED] android – How can I find NavController if I use view binding?

Posted on November 14, 2022

Solution 1 :

The code B should still be working fine .

I made a look into findNavController() . This is an extension function for simpifying the code , the code for extension function is

fun Activity.findNavController(@IdRes viewId: Int): NavController =
    Navigation.findNavController(this, viewId)

Now looking in to the code of findNavController() inside Navigation we see below

 @NonNull
    public static NavController findNavController(@NonNull Activity activity, @IdRes int viewId) {
        View view = ActivityCompat.requireViewById(activity, viewId);
        NavController navController = findViewNavController(view);
        if (navController == null) {
            throw new IllegalStateException("Activity " + activity
                    + " does not have a NavController set on " + viewId);
        }
        return navController;
    }

The viewId we are passing in argument is used in the first line

View view = ActivityCompat.requireViewById(activity, viewId);

now looking into requireViewById() inside ActivityCompat we see

  @NonNull
    public static <T extends View> T requireViewById(@NonNull Activity activity, @IdRes int id) {
        if (Build.VERSION.SDK_INT >= 28) {
            return activity.requireViewById(id);
        }

        T view = activity.findViewById(id);
        if (view == null) {
            throw new IllegalArgumentException("ID does not reference a View inside this Activity");
        }
        return view;
    }

for api 28 and plus the method which gets called is

@NonNull
    public final <T extends View> T requireViewById(@IdRes int id) {
        T view = findViewById(id);
        if (view == null) {
            throw new IllegalArgumentException("ID does not reference a View inside this Activity");
        }
        return view;
    }

So as long as the view (inside which the nav_host_fragment is present) is attached to activity the code which you wrote for finding the nav controller should work completely fine .

class TasksActivity : AppCompatActivity() {
    
    private lateinit var binding: TasksActBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = TasksActBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)       //you are attaching view to activity here , make sure you always call this before the next line , else you will get IllegalStateException 
      
        val navController: NavController = findNavController(R.id.nav_host_fragment)       
    }

}

I have not tested the code personally but from what I see it should work perfectly fine.

READ  [ANSWERED] libs - How do I embed a native code library in an Android app (SDK 29+)?
Powered by Inline Related Posts

Solution 2 :

We are using ViewBinding to get a reference of view itself. If you are using viewbinding in TextView, you will get a reference of the View.

In the case of NavCotroller, If you use Viewbinding, you will get a reference to a fragment, while findNavController expect ViewId of type integer.

findNavController(@IdRes viewId: int)

Solution 3 :

The correct working way is as follows:

enter image description here

FragmentContainerView has to be accessed from the supportFragmentManager:

val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragment) as NavHostFragment

val navController = navHostFragment.navController

Problem :

Normally, I use val navController: NavController = findNavController(R.id.nav_host_fragment) in Code A to find NavController, it’s based R.id.nav_host_fragment.

Now I use view binding in the app just like Code B, how can I NavController if I use view binding ?

BTW, in my mind R.id.nav_host_fragment will not be available in view binding , right?

Code A

class TasksActivity : AppCompatActivity() { 

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.tasks_act)

        val navController: NavController = findNavController(R.id.nav_host_fragment)
     }
 
}

Code B

class TasksActivity : AppCompatActivity() {
    
    private lateinit var binding: TasksActBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = TasksActBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)       
      
        //val navController: NavController = findNavController(R.id.nav_host_fragment)       
    }

}

tasks_act.xml

<androidx.drawerlayout.widget.DrawerLayout
    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/drawer_layout"
    android_layout_width="match_parent"
    android_layout_height="match_parent"
    tools_context=".tasks.TasksActivity"
    tools_openDrawer="start">

    <LinearLayout
        android_layout_width="match_parent"
        android_layout_height="match_parent"
        android_orientation="vertical">

        <com.google.android.material.appbar.AppBarLayout
            android_layout_width="match_parent"
            android_layout_height="wrap_content">

            <androidx.appcompat.widget.Toolbar
                android_id="@+id/toolbar"
                android_layout_width="match_parent"
                android_layout_height="wrap_content"
                android_minHeight="?attr/actionBarSize"
                android_theme="@style/Toolbar"
                app_popupTheme="@style/ThemeOverlay.AppCompat.Light" />
        </com.google.android.material.appbar.AppBarLayout>

        <fragment
            android_id="@+id/nav_host_fragment"
            android_name="androidx.navigation.fragment.NavHostFragment"
            android_layout_width="match_parent"
            android_layout_height="match_parent"

            app_defaultNavHost="true"
            app_navGraph="@navigation/nav_graph" />

    </LinearLayout>

    ..

</androidx.drawerlayout.widget.DrawerLayout>

Comments

Comment posted by HelloCW

Thanks! but

Comment posted by stackoverflow.com/questions/60733289/…

I’m not sure, but you can check this answer:

Comment posted by Stachu

viewId

Recent Posts

  • How can I play with my cat without toys?
  • What is a bag pipe band called?
  • Are Honda Civics actually fast?
  • Are Yankee candles toxic?
  • How do I pair my Michael Kors smartwatch with my Android?

Recent Comments

No comments to show.

Archives

  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022

Categories

  • ¿Cómo
  • ¿Cuál
  • ¿Cuántas
  • ¿Cuánto
  • ¿Que
  • ¿Quién
  • 90” and 108” so you may have to round up to the nearest size.
  • and delete any Spotify folders from it. Once this is done
  • Android
  • Are
  • At
  • Bei
  • blink
  • C'est
  • Can
  • carbs
  • Comment
  • Did
  • Do
  • Does
  • During
  • For
  • Has
  • How
  • In
  • Is
  • Ist
  • Kann
  • Können
  • nouveau
  • On
  • or 108 inches.2020-08-03
  • Où
  • owning
  • Pourquoi
  • Puis-je
  • Quand
  • Quante
  • Quel
  • Quelle
  • Quelles
  • Quels
  • Qui
  • Should
  • Sind
  • Sollte
  • spiritual
  • tap the downward-facing arrow on the top left. A downward-facing arrow will appear underneath each song in the album; they'll turn green as the download completes.2020-07-28
  • Uncategorized
  • Wann
  • Warum
  • Was
  • Welche
  • Welcher
  • Welches
  • Welke
  • Wer
  • Were
  • What
  • What's
  • When
  • Where
  • Which
  • Who
  • Whose
  • Why
  • Wie
  • Will
  • Wo
  • Woher
  • you will receive two curtains each with the same measurements of width 66"" (168cm) x drop 54""(137cm).
  • you'll see a green downward-facing arrow next to each song.2021-02-26
©2023 Who Do Is | Powered by SuperbThemes & WordPress