Android 导航架构组件-启动屏幕
我想知道如何使用导航架构组件实现初始屏幕 到现在为止,我有这样的东西 用户必须第一次在Android 导航架构组件-启动屏幕,android,kotlin,splash-screen,android-architecture-navigation,Android,Kotlin,Splash Screen,Android Architecture Navigation,我想知道如何使用导航架构组件实现初始屏幕 到现在为止,我有这样的东西 用户必须第一次在ProfileFragment中设置其配置文件,并可以从ChatFragment编辑其配置文件 我的问题是我不知道如何在导航后从堆栈中删除SplashFragment。我见过,但不太明白 Android上的闪屏一直都很奇怪。您只想在单击应用程序图标和创建第一个活动之间显示启动屏幕。如果您的启动屏幕是一个片段,用户仍将看到白色背景,直到创建第一个活动,并且由于必须创建和删除启动片段,应用程序的启动时间将增加。最
ProfileFragment
中设置其配置文件,并可以从ChatFragment
编辑其配置文件
我的问题是我不知道如何在导航后从堆栈中删除
SplashFragment
。我见过,但不太明白 Android上的闪屏一直都很奇怪。您只想在单击应用程序图标和创建第一个活动之间显示启动屏幕。如果您的启动屏幕是一个片段
,用户仍将看到白色背景,直到创建第一个活动
,并且由于必须创建和删除启动片段
,应用程序的启动时间将增加。最佳实践是使用splashAppTheme
,就像Ian Lake(安卓框架工程师)在中解释的那样
至于导航,您的应用程序应该有一个固定的目的地,这是用户在进入和退出应用程序时看到的第一个和最后一个屏幕,如中所述。在您的情况下,将ChatFragment
作为固定目的地是有意义的。在ChatFragment
的onCreate
中,您应该检查用户是否已经有一个配置文件,如果没有,则使用将其重定向到ProfileFragment
。您可以尝试一下,它目前对我有效:
<action
android:id="@+id/action_splashFragment_to_profileFragment"
app:destination="@id/signInFragment"
app:launchSingleTop="true"
app:popUpTo="@id/splashFragment"
app:popUpToInclusive="true" />
只需设置popUpTo(当前目标)
和popuptinclusive(true)
,这将弹出所有其他屏幕,直到它到达指定目标-如果popuptinclusive()也会弹出目标
设置为true
——然后导航到新的目的地。以下是解决上述情况的两种方法
一个:
在NavHostFragment的活动中
重写onBackPress()
方法,如果当前NavDestination
是MainFragment
,则只需finish()
活动
@Override
public void onBackPressed() {
NavDestination navDestination = mNavController.getCurrentDestination();
if (navDestination != null
&& navDestination.getId() == R.id.mainFragment) {
finish();
return;
}
super.onBackPressed();
}
两个:
在导航图app:popUpTo=“@id/nav\u graph”
和app:popuptinclusive=“true”
在我的项目中,我在action中测试app:clearTask=“true”,它运行良好~~~
<fragment
android:id="@+id/splashFragment"
android:name="xxx.SplashFragment"
android:label="fragment_splash"
tools:layout="@layout/fragment_splash">
<action
android:id="@+id/action_splashFragment_to_mainFragment"
app:destination="@id/mainFragment"
app:enterAnim="@anim/anim_right_in"
app:exitAnim="@anim/anim_left_out"
app:popEnterAnim="@anim/anim_left_in"
app:popExitAnim="@anim/anim_right_out"
app:clearTask="true"/>
</fragment>
你可以试试这个把戏,对我来说绝对不错。
从清单文件中将初始屏幕设置为启动程序屏幕,并从初始屏幕启动主机活动
清单文件代码
<activity android:name=".SplashScreen"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
主机活动的Xml代码
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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">
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/navigation_graph" />
</android.support.constraint.ConstraintLayout>
你会是这样的
<?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/navigation_graph"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="com.devgenesis.breaker.ice.navigationmproject.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" />
</navigation>
当闪屏显示给用户几秒钟时,通常会出现误用闪屏的情况,用户在已经可以与应用程序交互的情况下浪费时间看闪屏。相反,你应该让他们尽快进入屏幕,在那里他们可以与应用程序交互。因为之前的闪屏在android上被认为是反模式的。但后来谷歌意识到,在用户点击图标和您的第一个应用程序屏幕准备好进行交互之间仍然存在一个短窗口,在此期间,您可以显示一些品牌信息。这是实现启动屏幕的正确方法
因此,要以正确的方式实现启动屏幕,您不需要单独的启动片段,因为它会在应用程序加载中引入不必要的延迟。要做到这一点,您只需要特别的主题。从理论上讲,应用程序主题可以应用到用户界面上,并且比您的应用程序用户界面初始化和可见的时间要快得多。简而言之,您只需要像这样SplashTheme
:
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/splash_background</item>
</style>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque"> <!-- android:opacity="opaque" should be here -->
<item>
<!--this is your background, you can use color, gradient etc.-->
<color android:color="@color/colorPrimary"/>
<!--<shape>
<gradient
android:angle="315"
android:endColor="#1a82ff"
android:startColor="#2100d3"
android:type="linear"/>
</shape> -->
</item>
<item>
<bitmap android:src="@drawable/ic_logo"
android:gravity="center"/>
</item>
</layer-list>
您的片段将被托管在某个活动中,我们称之为mainacactivty
。在Manifest
中,只需将SplashTheme
添加到您的活动中(这将显示用户单击应用程序图标时的启动屏幕主题):
我认为Nav AAC的想法是能够使用单活动架构。你确定你不需要一个图表和popTo吗?@EpicPandaForce首先,AAC不是关于单个活动,单个活动最适合AAC,你也可以将它用于多个活动。最重要的是,使用SplashFragment无法实现正确的启动屏幕。最重要的是,使用SplashFragment无法实现正确的启动屏幕。
为什么不?另外,请参阅和“”“我们将导航组件作为构建应用程序内UI的框架引入,重点是使单个活动应用程序成为首选架构。”“阅读@Sander也指出的这篇文章,这里解释了什么是合适的启动屏幕。简单地说,使用SplashFragment
启动应用程序时会有不必要的延迟,通过应用程序主题实现的启动屏幕只会在应用程序初始化所需的时间内显示。好的,这完全取决于您的业务需求。这是一种常见的模式,使用显式启动屏幕来确定是否登录。添加一个点击监听器或让用户更快地超越启动屏幕的方式,并用这种方法挽回一些尊严,否则这是一种UX反模式:你阻止应用程序使用(可能)营销团队需要达到一些不一致的KPI。
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/splash_background</item>
</style>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque"> <!-- android:opacity="opaque" should be here -->
<item>
<!--this is your background, you can use color, gradient etc.-->
<color android:color="@color/colorPrimary"/>
<!--<shape>
<gradient
android:angle="315"
android:endColor="#1a82ff"
android:startColor="#2100d3"
android:type="linear"/>
</shape> -->
</item>
<item>
<bitmap android:src="@drawable/ic_logo"
android:gravity="center"/>
</item>
</layer-list>
<activity android:name=".ui.MainActivity"
android:theme="@style/SplashTheme">
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
.....