Java Android导航组件-如果用户未登录,则导航到其他活动

Java Android导航组件-如果用户未登录,则导航到其他活动,java,android,android-navigation,Java,Android,Android Navigation,我目前有一个使用单一活动的Android项目。此活动(MainActivity)包括工具栏、底部导航和导航主机片段 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.

我目前有一个使用单一活动的Android项目。此活动(MainActivity)包括工具栏、底部导航和导航主机片段

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

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

<androidx.fragment.app.FragmentContainerView
    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"
    android:layout_above="@id/bottom_nav"
    android:layout_below="@id/toolbar"/>

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottom_nav"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    app:menu="@menu/bottom_nav"
    />
但是,我想检查一下用户是否已登录。如果用户未登录,我不希望加载主片段,而是希望导航到带有欢迎屏幕的单独活动

我已尝试在主片段上添加以下内容:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.fragment_home, container, false);


    SharedPreferences getSharedData = this.getActivity().getSharedPreferences("MyApp", Context.MODE_PRIVATE);
    Boolean loggedIn = getSharedData.getBoolean("isUserLoggedIn", false);

    if (!loggedIn) {
        Navigation.findNavController(v).navigate(R.id.welcomeActivity);
    }

    // .. load the data for the home screen ..

}
但是,这会导致一个错误:

java.lang.IllegalStateException: View android.widget.LinearLayout{a81e94f V.E...... ......I. 0,0-0,0} does not have a NavController set
如果用户未登录,如何导航到单独的欢迎屏幕

更新:

这是当前导航图:

<?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/homeFragment">

<fragment
    android:id="@+id/homeFragment"
    android:name="com.myapp.app.HomeFragment"
    android:label="Home"
    tools:layout="@layout/fragment_home">
     // .. actions to sub fragments ..
</fragment>
<fragment
    android:id="@+id/secondFragment"
    android:name="com.myapp.app.SecondFragment"
    android:label="Second"
    tools:layout="@layout/fragment_second" />
    // .. actions to sub fragments ..
<fragment
    android:id="@+id/thirdFragment"
    android:name="com.myapp.app.ThirdFragment"
    android:label="Third"
    tools:layout="@layout/fragment_third">
    // .. actions to sub fragments ..
</fragment>
<fragment
    android:id="@+id/fourthFragment"
    android:name="com.myapp.app.FourthFragment"
    android:label="Fourth"
    tools:layout="@layout/fragment_fourth" >
    // .. actions to sub fragments ..
</fragment>

// .. More subfragments linked from the first four ..

<activity
    android:id="@+id/welcomeActivity"
    android:name="com.myapp.app.WelcomeActivity"
    android:label="activity_welcome"
    tools:layout="@layout/activity_welcome" />
</navigation>

// .. 对子片段执行的操作。。
// .. 对子片段执行的操作。。
// .. 对子片段执行的操作。。
// .. 对子片段执行的操作。。
// .. 从前四个链接的更多子片段。。

主页、第二、第三和第四是底部的四个选项卡。我需要的是检查用户是否已登录,并显示带有底部导航的主页片段。如果用户未登录,我需要显示一个没有底部导航的单独片段或活动,该片段或活动将链接到登录和注册选项,并最终返回带有底部导航的主片段。

您正在调用活动,正如您所说的单独活动,而不是片段。所以你必须这样称呼意图

Intent intent = new Intent(this, welcomeActivity.class);
startActivity(intent);

希望它能起作用。

这不是在加载
HomeFragment
时启动
WelcomeActivity
的好方法, 如果用户未登录或第一次打开用户,您可以在
SplashScreen
中进行检查,您可以显示
WelcomeActivity
,否则您可以创建具有与
WelcomeActivity
相同功能的
WelcomeFragement
,显示
WelcomeFragment
而不是显示
HomeFragment

这只是一个可以修改和改进的示例或想法

更新 您可以从活动中使用导航控制器,而非空条件有助于防止崩溃

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 
{

View v = inflater.inflate(R.layout.fragment_home, container, false);


SharedPreferences getSharedData = this.getActivity().getSharedPreferences("MyApp", Context.MODE_PRIVATE);
Boolean loggedIn = getSharedData.getBoolean("isUserLoggedIn", false);

if (!loggedIn) {

    NavHostFragment navHostFragment = (NavHostFragment) (getActivity() AppCompactActivity).getSupportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    navcontroller.navigate(actionForNavigatingHomeFragmentToMainActivity);
 }

}
在欢迎活动中添加操作使用弹出窗口。
popUpTo和PopuptInclusive仍然从后堆栈中删除目的地,就像您使用ID导航一样。

在home片段中,尝试更改下面的行

Navigation.findNavController(v).navigate(R.id.welcomeActivity);

根据源代码文档

Navigation.findNavController(视图)

根据这一点,它获取
fragment
并从其父级查找
NavHostFragment
,然后获取
NavController


有了这个,我相信您可以决定使用哪种方法进行导航。同样,我建议您将所有逻辑代码从
onCreateView

中移出。根据错误,您的片段
LinearLayout
没有任何
NavController
链接。你能分享片段XML和导航图吗?@Anand我已经添加了导航图,并解释了我试图完成的更多内容。活动转换也可以使用导航组件完成。看,我刚刚添加了当前导航图,并解释了更多我想要的。我最关心的是我将条件放在哪里(在哪个活动/片段中),以及在登录后如何返回主片段。请检查新的更新,可能会帮助您。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 
{

View v = inflater.inflate(R.layout.fragment_home, container, false);


SharedPreferences getSharedData = this.getActivity().getSharedPreferences("MyApp", Context.MODE_PRIVATE);
Boolean loggedIn = getSharedData.getBoolean("isUserLoggedIn", false);

if (!loggedIn) {

    NavHostFragment navHostFragment = (NavHostFragment) (getActivity() AppCompactActivity).getSupportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    navcontroller.navigate(actionForNavigatingHomeFragmentToMainActivity);
 }

}
Navigation.findNavController(v).navigate(R.id.welcomeActivity);
NavHostFragment.findNavController(this).navigate(R.id.welcomeActivity);
 /**
 * Find a {@link NavController} given a local {@link View}.
 *
 * <p>This method will locate the {@link NavController} associated with this view.
 * This is automatically populated for views that are managed by a {@link NavHost}
 * and is intended for use by various {@link android.view.View.OnClickListener listener}
 * interfaces.</p>
 *
 * @param view the view to search from
 * @return the locally scoped {@link NavController} to the given view
 * @throws IllegalStateException if the given view does not correspond with a
 * {@link NavHost} or is not within a NavHost.
 */
@NonNull
public static NavController findNavController(@NonNull View view) {
    NavController navController = findViewNavController(view);
    if (navController == null) {
        throw new IllegalStateException("View " + view + " does not have a NavController set");
    }
    return navController;
}
/**
 * Find a {@link NavController} given a local {@link Fragment}.
 *
 * <p>This method will locate the {@link NavController} associated with this Fragment,
 * looking first for a {@link NavHostFragment} along the given Fragment's parent chain.
 * If a {@link NavController} is not found, this method will look for one along this
 * Fragment's {@link Fragment#getView() view hierarchy} as specified by
 * {@link Navigation#findNavController(View)}.</p>
 *
 * @param fragment the locally scoped Fragment for navigation
 * @return the locally scoped {@link NavController} for navigating from this {@link Fragment}
 * @throws IllegalStateException if the given Fragment does not correspond with a
 * {@link NavHost} or is not within a NavHost.
 */
@NonNull
public static NavController findNavController(@NonNull Fragment fragment) {
    // some code here
}