MainActivity中导航主机片段的调用方法 [英] Calling method on navigation host fragment inside MainActivity

查看:65
本文介绍了MainActivity中导航主机片段的调用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发我的第一个Android应用程序,并且我知道架构可能有点混乱. 我在android中使用新的Jetpack导航.我有一个导航抽屉,在其中添加了一个回收站视图,用户可以从中选择回收站视图中的项目,并基于该主导航主机片段应滚动到特定位置.

I am developing my first Android app and I know that architecture could be a bit messy. I am using new Jetpack navigation in android. I have a navigation drawer where I added a recycler view from where the user can select the item in the recycler view and based on that main navigation host fragment should scroll to a specific location.

我想知道如何在与导航主机片段关联的片段下面调用方法.我可以获取导航主机片段的句柄,但我想在该特定片段中调用自定义方法,该特定方法不会通过导航主机片段公开,因此它给了我编译时错误.

I wanted to know how I can call a method in the underneath fragment associated with the navigation host fragment. I can get a handle to the navigation host fragment but I wanted to call a custom method in that particular fragment which is not exposed via navigation host fragment and because of that it gives me the compile-time error.

我正在使用的方法如下.

The approach I am using is the following.

val readerFragment: ReaderFragment = supportFragmentManager.findFragmentById(R.id.reader_fragment) as ReaderFragment

readerFragment.scrollToChapter(5)

readerFragment.scrollToChapter(5)

此处的Reader片段是导航主机片段下面使用的实际片段,这会导致以下异常

Here Reader fragment is the actual fragment used underneath navigation host fragment, this results in the following exception

com.example.quran E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.quran, PID: 7640
    kotlin.TypeCastException: null cannot be cast to non-null type com.example.quran.ReaderFragment

或尝试像这样直接从nav_host_fragment获取

or if try to get it directly from nav_host_fragment like this

val readerFragment: ReaderFragment = nav_host_fragment as ReaderFragment

然后我得到以下异常

java.lang.ClassCastException: androidx.navigation.fragment.NavHostFragment cannot be cast to com.example.quran.ReaderFragment

有人可以帮助我如何从MainActivity内部的nav_host _fragment获取实际片段.

Can somebody help me that how I can get the actual fragment from the nav_host _fragment inside the MainActivity.

下面是nav_graph的代码

Below is the code for the nav_graph

<?xml version="1.0" encoding="utf-8"?>
<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/reader_fragment">
    <fragment
        android:id="@+id/reader_fragment"
        android:name="com.example.quran.ReaderFragment"
        android:label="Reader"
        tools:layout="@layout/reader_fragment">
    </fragment>
    <fragment
        android:id="@+id/chapterDetailsFragment"
        android:name="com.example.quran.ChapterDetailsFragment"
        android:label="fragment_chapter_details"
        tools:layout="@layout/fragment_chapter_details" />
</navigation>

这是MainActivity的布局

and here is the layout for MainActivity

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity"
    tools:openDrawer="start">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorTopNavigation">

            <TextView
                android:id="@+id/toolbar_textView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fontFamily="@font/montserratbold"
                android:textColor="@color/toolbarItemColor"
                android:layout_marginRight="?android:attr/actionBarSize"
                android:gravity="center"
                android:textSize="30dp"
                android:textStyle="bold" />

        </androidx.appcompat.widget.Toolbar>

        <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>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true">


        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/chapters_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </com.google.android.material.navigation.NavigationView>


</androidx.drawerlayout.widget.DrawerLayout>

推荐答案

对问题的解释

您的代码中的第一个错误:

Your first error from the code:

 val readerFragment: ReaderFragment = nav_host_fragment as ReaderFragment

因为NavHostFragment是一个主机(即您的片段在其中),所以您无法将NavHostFragment转换为其他任何内容.

Is because, the NavHostFragment is a host (i.e. your fragment is inside of it), so you cannot cast the NavHostFragment to anything else.

 supportFragmentManager.findFragmentById(R.id.reader_fragment) as ReaderFragment

TypeCastException:不能将null强制转换为非null类型

TypeCastException: null cannot be cast to non-null type

findFragmentById返回null,因为它找不到您的片段.这是第二个错误.

The findFragmentById is returning null as it does not find your fragment. that's the second error.

解决方案

您可以对其稍加修改,以获取屏幕上的片段:

You can hack it a bit to get the on screen fragment:

NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host);
navHostFragment.getChildFragmentManager().getFragments().get(0);

您还可以检查子片段管理器,因为您的片段是导航主机的子片段:

You could also check the child fragment manager since your fragment is a child of the nav host:

NavHostFragment fragment = supportFragmentManager.findFragmentById(R.id.nav_host);
MyFragment frag = (MyFragment) fragment.getChildFragmentManager().findFragmentByTag(tag);

参考:

Android导航体系结构组件-获取当前可见的片段

这篇关于MainActivity中导航主机片段的调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆