最も正しいスプラッシュスクリーンの実装

一般的に、これはmedium.comからの私の記事の翻訳であり、元の記事はここにあり 、彼らが言うように購読します。

一般に、Androidでスプラッシュを正しくスプラッシュする方法に関する記事をかなり多く見ましたが、すべて1つの問題があります-開発者はネイティブアプリケーションに単一のエントリポイントがないことを忘れている-2009年にこれに遭遇しました開発パスを開始したばかりのとき。 ある種のソーシャルネットワーク用のある種のクライアントを開発していることを想像してくださいandroid.intent.action.MAIN他に、写真、テキスト、通知のアプリ共有を開始するために使用できるandroid.intent.action.MAINのアクティビティがマニフェストにある場合があります。 そして良い方法で、どこでもスプラッシュが必要です!

テーマ


まず、カスタムの「android:windowBackground」を使用して基本的なapaテーマを作成します。このテーマには、スプラッシュの画像が配置されます。 基本的なテーマは少なくともすべてのエントリポイントに適用する必要がありますが、通常はアプリのすべてのアクティビティを使用します。

 <resources> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> <style name="AppTheme.SplashScreen" parent="AppTheme"> <item name="android:windowBackground">@drawable/splash</item> <item name="android:windowTranslucentStatus">true</item> <item name="android:windowTranslucentNavigation">true</item> </style> ... </resources> 

また、 android:windowTranslucentStatusおよびandroid:windowTranslucentNavigationandroid:windowTranslucentNavigationして、スプラッシュをさらにクールに見せます! android:windowBackgroundにはandroid:windowBackground画像が含まれており、これは背景のままであり、承認画面ではunsplash.comから取得したため、著者kazuendについて言及します。

アクティビティ


デモプロジェクトには、3つのアクティベーションがあります。メイン画面、承認、および何かを調べることができる画面です。 承認を除くすべてのSplashedActivityは、承認のステータスを確認するためにSplashedActivityから継承されます。

 private const val ACTIVITY_AUTH = 1000 abstract class SplashedActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { if (!isAuthenticated()) { startActivityForResult(Intent(this, AuthActivity::class.java), ACTIVITY_AUTH) } setTheme(R.style.AppTheme_Base) super.onCreate(savedInstanceState) } private fun isAuthenticated(): Boolean { return getUser() != null } private fun onAuthenticatedCallback(resultCode: Int, data: Intent?) { when (resultCode) { Activity.RESULT_CANCELED -> finish() Activity.RESULT_OK -> recreate() } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { when (requestCode) { ACTIVITY_AUTH -> onAuthenticatedCallback(resultCode, data) } super.onActivityResult(requestCode, resultCode, data) } } 

承認を開始し、結果を待ち、承認が成功した場合は自分自身を再作成します。 一般的に、 recreate()はあまり好きではありませんが、多くの開発者はonCreate() UIを初期化し、 recreate()後にonCreate()を開始したIntentを失うことなく再び呼び出されます。

ログイン


通常はAccountManagerを使用しますが、接続する必要があるボイラープレートが多すぎるため、すべてがSharedPreferencesに保存されます。



 class AuthActivity : AppCompatActivity() { private val authCardView by lazy { findViewById<CardView>(R.id.authCardView) } private val okButton by lazy { findViewById<Button>(R.id.okButton) } private val cancelButton by lazy { findViewById<Button>(R.id.cancelButton) } private val loginEditText by lazy { findViewById<EditText>(R.id.loginEditText) } private val passwordEditText by lazy { findViewById<EditText>(R.id.passwordEditText) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_auth) authCardView.animate() .setDuration(500L) .setInterpolator(AccelerateDecelerateInterpolator()) .alpha(1F) .setListener(object : Animator.AnimatorListener { override fun onAnimationRepeat(p0: Animator?) { } override fun onAnimationCancel(p0: Animator?) { } override fun onAnimationStart(p0: Animator?) { authCardView.alpha = 0F authCardView.visibility = View.VISIBLE } override fun onAnimationEnd(p0: Animator?) { authCardView.visibility = View.VISIBLE } }) okButton.setOnClickListener { performInputChecksAndSaveUser { login, password -> saveUser(User(login, password)) setResult(Activity.RESULT_OK) finish() } } cancelButton.setOnClickListener { finish() } } private fun performInputChecksAndSaveUser(successCallback: (String, String) -> Unit) { if (loginEditText.text.isBlank()) { loginEditText.error = getText(R.string.errorEmptyLogin) } if (passwordEditText.text.isBlank()) { passwordEditText.error = getText(R.string.errorEmptyPassword) } if (loginEditText.text.isNotBlank() && passwordEditText.text.isNotBlank()) { successCallback.invoke(loginEditText.text.toString(), passwordEditText.text.toString()) } } } 

美しいアニメーションに加えて、actitvitはユーザーの入力をチェックし、エラーを表示し、実際にユーザー名とパスワードを保存します。 ただし、ユーザーが[キャンセル]または[戻る]ボタンをクリックすると、アクティビティはActivity.RESULT_CANCELLED結果コードで終了し、ActivityManagerはスタックを返し、認証の原因となったアクティベーションを完了します。 このアイデアは、誰が許可を引き起こしたかは関係ないということです-許可が必要なアクティビティが起動されるとすぐに、利用可能なユーザーデータがあるかどうかをチェックし、ない場合は、許可プロセスの成功結果の後に表示されます。

共有する


 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.nixan.splashscreenexample"> ... <activity android:name=".ShareActivity"> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> </activity> ... </manifest> 

 class ShareActivity : SplashedActivity() { private val helloText by lazy { findViewById<TextView>(R.id.helloText) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) getUser()?.let { helloText.text = "${it.login}\n${intent.getStringExtra(Intent.EXTRA_TEXT)}" } } } 

ご覧のとおり、 AndroidManifest.xmlでもアクティビティクラスでも、通常のIntent処理は特別なものではありません。 recreate()メリットrecreate() -そのため、すべてのアクティビティをいつものように記述します。

おわりに


そして今、何が起こったのでしょうか?

通常、 ActivityManagerは、ユーザーがアプリアイコンをクリックしてからターゲットのActivityonCreate()が呼び出されるまでに時間がかかります。 このようなタイムラグをマスクするために、システムはアクティビティからandroid:themeを取得し、コンテンツなしでレンダリングします。その後、制御が記述されたクラスに転送され、アプリケーションが動作を開始します。

すべてのアクティビティがスプラッシュ画面のようなテーマでレンダリングされ、それらすべてがSplashedActivityから継承されて承認チェックを実行し、追加の初期化画面を実行することを発表しました-この場合、これはユーザーが承認されたAuthActivityのみAuthActivity 。 別のSplashedActivityはこの承認の結果を処理し、ユーザーにアプリのコンテンツをさらに表示するか閉じるかを決定します。

したがって、ユーザーがGoogle Playにログインし、アプリケーションをインストールし、すぐにこのアプリを介してコンテンツを共有することを決定した場合、承認画面が表示されますが、共有したいコンテンツは失われません。 私は自分でアプリケーションをインストールすることを知っていますが、すぐにそれらにアクセスすることはありません。そのため、このようなユーザーの行動のパターンは非常に適切な場所です。

この記事の例を使用したプロジェクトへのリンクを次に示します。

Source: https://habr.com/ru/post/J348136/


All Articles