ラベル Activity の投稿を表示しています。 すべての投稿を表示
ラベル Activity の投稿を表示しています。 すべての投稿を表示

2023年10月10日火曜日

Android Activityを透明にするための設定を解説

どうも。どっことです。今回はActivityを透明にするための設定について解説します。

Activityを透明にする

完全に透明なActivityでなにかしら処理する(つまりAPI通信する、DBの更新処理するなどを完全に透明なActivityで実行する)のはユーザ観点ではよくないですが、例えばダイアログを表示するためだけのActivityなどであれば、背景が見えて別画面に見えてしまうのは不自然であるため、確かに透明である必要があります。そういった、不自然なことを回避する目的でActivityを透明にする設定を紹介していきたいと思います。

設定方法

AndroidManifest.xmlで透明にしたいActivitythemeに以下を設定します。

<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>

例えば、上記の設定を適用したthemeTransparentActivityThemeとして用意しました。

<style name="TransparentActivityTheme" parent="AppTheme.NoActionBar">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:colorBackgroundCacheHint">@null</item>
    <item name="android:windowIsTranslucent">true</item>
</style>

上記をAndroidManifest.xmlの透明にしたいActivitythemeに適用します。以下はTransparentActivityというActivityに設定したときの例です。

<activity
    android:name="com.sample.application.TransparentActivity"
    android:theme="@style/TransparentActivityTheme"/>

orientation指定をするとクラッシュするので注意

ただし実際にアプリ内に組み込む場合、注意が必要です。透明なActivityには危険が含まれているのです。 透明なActivityに対してorientationの指定をするとクラッシュします。実装でorientationを指定したり、AndroidManifestでのActivityscreenOrientationを指定するとアプリがクラッシュするようです。呼び出し元のActivityと同じorientationで制御されるようなので、透明なActivityを呼び出す時は気をつけてください。

参考

2023年10月9日月曜日

Android Activityをダイアログぽく表示する方法を紹介

どうも。どっことです。今回はActivityをダイアログっぽく表示する方法を紹介します。

Activityをダイアログのように表示する

色々カスタマイズできるのは嬉しいDialogFragmentですが、実装が面倒で「それっぽければActivityで十分なんだよなぁ…」と思ってしまった私への、「ActivityだけでDialogぽい見た目の画面(というかダイアログ)の作り方」備忘録です。

最小限の設定の場合

対象のActivityに以下のThemeを設定するだけです。

Theme.MaterialComponents.DayNight.Dialog

DialogFragmentStyleとして設定される値を、Activityに設定してあげるだけです。本当にそれっぽくできるだけで、これだけだと決定もキャンセルもなにもないのでレイアウト側で追加の実装が必要となります。

色々カスタマイズしたい場合

Themeを継承してカスタマイズします。

最低限の設定を参考にダイアログぽいものを実装するとテーマの設定が引き継がれていないため、他のActivityと統一感が取れていないダイアログが表示されます。レイアウト側で調整すればなんとかなりますが、いい感じの統一感を目指すならThemeを意識したカスタマイズが必要となります。

Theme.MaterialComponents.DayNight.Dialogの継承元を追っていくと分かりますが、ダイアログぽいActivityにしてくれるこのテーマはいくつかの属性が設定されています。以下抜粋。もしかしたら漏れてるかも。

<item name="android:windowFrame">@null</item>
<item name="android:windowTitleStyle">@style/RtlOverlay.DialogWindowTitle.AppCompat</item>
<item name="android:windowTitleBackgroundStyle">@style/Base.DialogWindowTitleBackground.AppCompat</item>
<item name="android:windowBackground">@drawable/abc_dialog_material_background</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@style/Animation.AppCompat.Dialog</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>

アプリ共通のテーマを継承しつつ、これらの設定をテーマに設定することで、統一感のあるダイアログを実装することができます。

まとめ

今回はActivityをダイアログぽく表示する方法について紹介しました。DialogFragmentは実装に少しクセがあるコンポーネントなので、単に表示するだけなら今回の設定で簡単に実装することができます。ただ、ここまで書いてていまさらだが、Activityをダイアログとして表示するのはAndroidのお作法的に正直あまりオススメしません。用法用量を守って計画的に。

2023年8月11日金曜日

Android 裏にいるActivityもすべて終了するfinishAffinityメソッドを紹介

どうも。どっことです。今回はスタックに積まれているActivityをすべて終了させるメソッドを紹介します。

裏のActivityもすべて終了するfinishAffinity

Activity AからActivity BstartActivity()でスタックを積んだとき、Activity Aが明示的に自身をfinish()させなければ、Activity Bの裏にActivity Aはスタックとして存在します。

そしてこのときActivity Bfinish()を呼び、自身を終了させても、スタックに残っているActivity Aが表示され、アプリを終了することができません。

今回は、Activity BからスタックにいるすべてのActivityを終了させるメソッドを紹介したいと思います。

Activity#finishAffinity()

すべてのActivityを終了させるにはfinishAffinity() というメソッドを使います。単純なケースであれば、このメソッドを呼び出すことで裏にいるActivityをすべて終了することができます。

単純なケースと書いたのは、Activityには親和性(affinity)という概念があるためです。これが厳格に管理されているActivityですと、今回のケースは期待した動作をしない可能性があります。

ただし基本的に同一のAndroidアプリという領域のActivityであるためaffinityが厳格に管理されているケースは非常に稀で、まずはやりたいことが実現できるかをこのメソッドを呼んで試してみるのが解決への一番の近道になるかと思います。

参考

2023年7月26日水曜日

Android Activityのスタックをクリアする

Intent.FLAG_ACTIVITY_CLEAR_TOPIntent#setFlag(int)でセットするだけ。

fun showTop(View view) {
  let intent = Intent(getApplication(), MainActivity::class.java)
  intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
  startActivity(intent);
}

参考

2022年8月13日土曜日

Android deprecatedとなったstartActivityForResult()の修正方法を解説

どうも。どっことです。今回は、deprecatedとなってしまったActivity#startActivityForResult()の修正方法について解説します。

deprecatedとなったstartActivityForResult()の対応

一昔前のAndroidアプリ開発であればActivity#startActivityForResult()による画面間のデータやり取りは鉄板中の鉄板として解説されていたネタですが、残念なことにこのメソッドがdeprecatedとなってしまいました。初級者でも使い勝手がよい背景から、さまざまなプロジェクトで使用されていたこのメソッドですが、いざdeprecatedとなっても修正できず困っている人も多いと思います。今回は、実は簡単にできるstartActivityForResult()の修正方法について解説します。

修正方法

修正方法は以下の手順です。

  1. registerForActivityResult()launcherを用意する。
    • Activityが終了したときの結果をここで実装しておく。
  2. Activityを起動するためのIntentを生成する。
  3. launcherを使ってIntentlaunchする。
順に解説していきます。

registerForActivityResult() でlauncherを用意する

Activityに新しく用意されているregisterForActivityResult()を使って、launcherを用意します。この時に、Activityから渡される結果を制御するための処理を実装しておきます。

val launcher = registerForActivityResult(StartActivityForResult()) { result ->
    // onActivityResultに対応するコールバック
    if (result.resultCode != Activity.RESULT_OK) {
        // Activity.RESULT_OK 以外
        return@registerForActivityResult
    }
    // RESULT_OK時の処理 
    // setResultで設定したintentから値を取得する
    val value = result.data.getStringExtra(key)
    // 取得した値を良しなにする
}

Activityを起動するためのIntentを生成する

ここまで実装すれば、あとはstartActivityForResult()の時と同じです。Intentを作成します。

val intent = Intent(applicationContext, NextActivity::class.java)

launcherを使ってIntentをlaunchする

作成したintentlauncherlaunchしてあげれば、修正できます。

launcher.launch(intent)

まとめ

今回はActivity#startActivityForResultのdeprecated解消方法について解説しました。いまだにstartActivityForResultを使っている開発者も少なからずいるかと思いますので、どんどん新しい機能を使えるよう情報をアップデートしていきたいですね。

参考

移行予定

どうも。どっことです。 タイトルの通りですが、諸事情により GitHubPage に移行予定です。 https://mkt120.github.io/ この備忘録に記載の内容を転記しつつ、今後はこちらのページを更新していく予定です。