ナビゲーションアーキテクチャコンポーネントを使用してスプラッシュスクリーンを実装する方法を知りたいです。
今まで私はこのようなものを持っています
ユーザーは、初めてProfileFragment
にプロファイルを設定する必要があり、ChatFragment
からプロファイルを編集できます。
私の問題は、ナビゲーション後にSplashFragment
をスタックから削除する方法がわからないことです。 条件付きナビゲーション を見ましたが、よく理解していませんでした。
スプラッシュスクリーンは、ユーザーに数秒間表示されると一般的に誤用され、ユーザーは既にスプラッシュスクリーンを見て時間を無駄にしている一方で、既にアプリと対話することができます。その代わりに、できるだけ早くアプリとやり取りできる画面に移動する必要があります。そのため、スプラッシュスクリーンはAndroidのアンチパターンと見なされていました。しかし、Googleは、ユーザーがアイコンをクリックしてから最初のアプリ画面を操作する準備ができており、その間にブランド情報を表示できる短いウィンドウがまだあることを認識しました。これは、スプラッシュスクリーンを実装する正しい方法です。
スプラッシュスクリーンを適切な方法で実装するために、個別のスプラッシュフラグメントは必要ありません。アプリのロードに不必要な遅延が発生するためです。それを行うには、特別なthemeのみが必要です。理論上、アプリのテーマはUIに適用でき、アプリのUIが初期化されて表示されるよりもずっと早く表示されます。簡単に言えば、次のようなSplashTheme
が必要です。
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="Android:windowBackground">@drawable/splash_background</item>
</style>
splash_background
drawableは次のようになります。
<?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>
とにかく、フラグメントは何らかのアクティビティでホストされます。MainActivty
と呼びましょう。 Manifest
で、アクティビティにSplashTheme
を追加するだけです(ユーザーがアプリアイコンをクリックしたときのスプラッシュスクリーンテーマが表示されます)。
<activity Android:name=".ui.MainActivity"
Android:theme="@style/SplashTheme">
次に、MainActivity
で通常のAppTheme
に戻り、onCreate
を呼び出す前にsuper
でこれを行います。
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
.....
スプラッシュスクリーンは、Androidでは常に奇妙です。アプリのアイコンをクリックしてから最初のActivity
を作成するまでの間にスプラッシュスクリーンを表示したいだけです。スプラッシュ画面がFragment
である場合、最初のActivity
が作成されるまでユーザーには白い背景が表示され、スプラッシュFragment
があるためアプリの起動時間が長くなります作成および削除されます。ベストプラクティスは、Ian LakeのようなスプラッシュAppTheme
を使用することです(Android Framework Engineer)は この投稿 で説明しています)。
ナビゲーションについては、アプリは ナビゲーションの原理 で説明されているように、アプリの開始および終了時にユーザーに表示される最初と最後の画面である固定の目的地を持っている必要があります。あなたの場合、ChatFragment
を固定の宛先にすることは理にかなっています。 onCreate
のChatFragment
で、ユーザーが既にプロファイルを持っているかどうかを確認し、 条件付きナビゲーション を使用してProfileFragment
にリダイレクトする必要があります。 't。
あなたはこれを試すことができます、それは現在私のために働いています:
_ <action
Android:id="@+id/action_splashFragment_to_profileFragment"
app:destination="@id/signInFragment"
app:launchSingleTop="true"
app:popUpTo="@id/splashFragment"
app:popUpToInclusive="true" />
_
popUpTo(the current destination)
とpopUpToInclusive(true)
を設定するだけで、指定された宛先に到達するまで他のすべての画面がポップされます。popUpToInclusive()
がtrue
-新しい宛先にナビゲートする前。
上記の状況を解決する2つの方法を次に示します。
One:NavHostFragment's Activity
で、現在のNavDestination
がMainFragment
の場合はonBackPress()
メソッド、adnはfinish()
だけActivity
をオーバーライドします。
@Override
public void onBackPressed() {
NavDestination navDestination = mNavController.getCurrentDestination();
if (navDestination != null
&& navDestination.getId() == R.id.mainFragment) {
finish();
return;
}
super.onBackPressed();
}
Two:Navigation_graph app:popUpTo="@id/nav_graph"
およびapp:popUpToInclusive="true"
でMainFragmentアクションに設定します
<?xml version="1.0" encoding="utf-8"?>
<navigation
Android:id="@+id/nav_graph"
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"
app:startDestination="@id/splashFragment">
<fragment
Android:id="@+id/splashFragment"
Android:name="xxx.fragment.splash.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:popUpTo="@id/nav_graph"
app:popUpToInclusive="true"/>
<action
Android:id="@+id/action_splashFragment_to_guideFragment"
app:destination="@id/guideFragment"
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:popUpTo="@id/nav_graph"
app:popUpToInclusive="true"/>
</fragment>
<fragment
Android:id="@+id/guideFragment"
Android:name="xxx.fragment.guide.GuideFragment"
Android:label="GuideFragment"
tools:layout="@layout/fragment_guide">
<action
Android:id="@+id/action_guideFragment_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:popUpTo="@id/nav_graph"
app:popUpToInclusive="true"/>
</fragment>
<fragment
Android:id="@+id/mainFragment"
Android:name="xxx.fragment.main.MainFragment"
Android:label="fragment_main"
tools:layout="@layout/fragment_main">
</fragment>
</navigation>
助けてください!
警告:これは非推奨です。ナビゲーションalpha08では、clearTaskタグが削除されました。 非推奨のclearTaskおよびlaunchDocumentフラグをNavOptionsから削除
私のプロジェクトでは、アクションで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>
あなたのJavaファイル
new Handler().postDelayed(new Runnable(){
@Override
public void run() {
/* Create an Intent that will start the Navigation Host activity . */
Intent mainIntent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(mainIntent);
finish();
}
}, 5000);
ホストアクティビティの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>