一般に、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:windowTranslucentNavigation
を
android: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
は、ユーザーがアプリアイコンをクリックしてからターゲットの
Activity
で
onCreate()
が呼び出されるまでに時間がかかります。 このようなタイムラグをマスクするために、システムはアクティビティから
android:theme
を取得し、コンテンツなしでレンダリングします。その後、制御が記述されたクラスに転送され、アプリケーションが動作を開始します。
すべてのアクティビティがスプラッシュ画面のようなテーマでレンダリングされ、それらすべてが
SplashedActivity
から継承されて承認チェックを実行し、追加の初期化画面を実行することを発表しました-この場合、これはユーザーが承認された
AuthActivity
のみ
AuthActivity
。 別の
SplashedActivity
はこの承認の結果を処理し、ユーザーにアプリのコンテンツをさらに表示するか閉じるかを決定します。
したがって、ユーザーがGoogle Playにログインし、アプリケーションをインストールし、すぐにこのアプリを介してコンテンツを共有することを決定した場合、承認画面が表示されますが、共有したいコンテンツは失われません。 私は自分でアプリケーションをインストールすることを知っていますが、すぐにそれらにアクセスすることはありません。そのため、このようなユーザーの行動のパターンは非常に適切な場所です。
この記事の例を使用したプロジェクトへのリンクを次に示します。