LoginSignup
13
10

More than 5 years have passed since last update.

Android の AppWidget で Snackbar を使う

Posted at

概要

Android の AppWidget で Snackbar を使う方法について書きます。

What is "Snackbar"?

Toast に似た Android のポップアップ機能です。画面下からせり出し、一定時間が経過したら画面下へと引っ込みます。

特徴

  • 色を変えられる
  • ユーザに追加のアクションを提示できる
  • 下の方に出るので画面描画を阻害しない
  • Toast と同じようにすぐ消えるので、重要な通知ではなく確認程度に使う

実装

では早速使ってみましょう。

依存の追加

app/build.gradle に Design Support library の依存を追記して、sync してください。

app/build.gradle
dependencies {
    def supportLibVersion = '25.3.1'
    compile 'com.android.support:appcompat-v7:' + supportLibVersion
    compile 'com.android.support:support-v4:'   + supportLibVersion
    compile 'com.android.support:design:'       + supportLibVersion
}

メッセージを表示

ごく簡単なものは下記のコードで表示できます。見たところ、Context が View になっているほかは Toast とほぼ同じように書くことができます。

メッセージを表示
Snackbar.make(view, "Text", Snackbar.LENGTH_SHORT).show();

色を変える

Snackbar は色を変えることが可能です。その場合、一旦オブジェクトを保持して、getView() メソッドで View を取得して、setBackgroundColor で任意の色を設定します。もちろん透過させることも可能です。

色の変更
final Snackbar snackbar = Snackbar.make(view, "Text", Snackbar.LENGTH_SHORT);
snackbar.getView().setBackgroundColor(color);

Action

Snackbar はユーザに追加アクションを提示することが可能です。ラベルの Text と、押された時の Action を定義した Listener を setAction で渡します。

追加アクションの設定
snackbar.setAction("Next!", new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
                Toast.makeText(v.getContext(), "Why?", Toast.LENGTH_SHORT).show();
            }
});

注意

  • AppCompatActivity でないと使えない……レガシーアプリで TabActivity を継承しているような場合は諦める必要がある
  • View を必要とする……View を持たない箇所、特に AppWidget では使えない

AppWidget で Snackbar を使う

前述の通り、View を直接操作できない AppWidget では Snackbar を使うことができません。AppWidget 主体のアプリで、せっかくの機能を使えないのは残念なので、何とかならないかと考えました。
正攻法ではないですが、1つのアイデアとしてダミーの透明な Activity を表示し、そこの View を使って Snackbar を表示するというやり方を考えてみました。

サンプルコード

GitHub リポジトリ にアップしてあります。

サンプル GIF

snackbar.gif

AppWidget の各色をタップすると、その色の Snackbar が表示され、"Next!" と書かれたラベルをタップすると "Why?" という Toast を表示します。新旧共演です。

実装

DummyActivity

ポイントになるのは下記の4点です。

  1. AppCompatActivity を継承
  2. 透明テーマを使用
  3. onCreate メソッドでの overridePendingTransition(0, 0); で、 Activity 起動時の Transition を無効化
  4. StatusBar の透明化(APIレベル21以降)
  5. 自動で finish する Executor タスクの登録
  6. finish メソッドでのoverridePendingTransition(0, 0); で、 Activity 終了時の Transition を無効化

下記に詳述します。

1. AppCompatActivity を継承

Snackbar は AppCompatActivity でないと利用できないので、そうしてください。

2. 透明テーマを使用

下記の透明テーマを定義し、

app/src/main/res/values/styles.xml
<resources>

    <!-- ...... -->

    <style name="DummyTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:activityOpenExitAnimation">@null</item>
        <item name="android:colorBackgroundCacheHint">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowAnimationStyle">@android:style/Animation</item>
        <item name="android:windowIsTranslucent">true</item>
    </style>

</resources>

AndroidManifest.xml で設定してください。

app/src/main/AndroidManifest.xml
        <activity
            android:name=".DummyActivity"
            android:label="@string/app_name"
            android:theme="@style/DummyTheme"
            >

4. StatusBar の透明化(APIレベル21以降)

Window クラスの setStatusBarColor で上のバーを透明に、下のバーを Snackbar と同じ色に設定します。

透明化
    private void setStatusBarTransparent() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = getWindow();
            window.setStatusBarColor(Color.TRANSPARENT);
            window.setNavigationBarColor(mColor);
        }
    }

5. 自動で finish する Executor タスクの登録

そのままだと透明な Activity が残ってしまって邪魔なので、非同期のタスクで DummyActivity を finish() させる必要があります。今回は Executors.newSingleThreadExecutor でシンプルにこんな風にしてみました。

自動で_finish_する_Executor_タスクの登録
    private void executeFinisher() {
        final ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                finish();
            }
        });
        executorService.shutdown();
    }

どうでもいいこと

Snackbar というのは軽食堂や移動アイスクリーム店を指すそうです。snickers ではないみたいです。


終わりに

AppWidget で Snackbar を使う方法について述べました。まともな方法ではなく、今後OSの制限で使えなくなる可能性もあるので、良い子は真似しないでください。

  • Snackbar はよりデザイン性に優れユーザフレンドリなポップアップ
  • ダミーの Activity を用意すれば AppWidget からでも Snackbar を使える

リンク

13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10