Hello Wor.log

IT系大学生4人による備忘録のようなもの

【android】ハンバーガーメニューに背景を付ける

こんにちは、CPPXのXです。

ハンバーガーメニューに背景を付ける方法を紹介します。

概要

androidハンバーガーメニューに背景を付けようとしたら詰まったので、解決した話をします。

ここで言っている背景とは、下画像で指している部分です。

f:id:cppx:20170604223946p:plain

背景が付くまでを、順を追って説明していきたいと思います。

今回の環境とか

ハンバーガー部分を見つける

初めに、問題のハンバーガーメニューのハンバーガー部分がどこにあるのか探しました。

ありました。

ActionBarDrawerToggleの中のDrawerArrowDrawableがそれのようです。
コード内だと、ActionBarDrawerToggleは、onCreateの中でこのようにインスタンスが作られていました。

ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);

背景が付いたハンバーガーを描画したいため、このActionBarDrawerToggleに対して新しいハンバーガーを突っ込みます。

toggle.setDrawerArrowDrawable(new DrawerArrowDrawable(this));

new DrawerArrowDrawable(this) の部分が問題のハンバーガー部分です。
これに対して背景を描画する処理を付けていきたいと思います。

ハンバーガーの背景を付ける

オプション的なもので背景を付ける方法を見つけられなかったため、ハンバーガの背景に何かを自分で描画する方針を取りました。

さっそくハンバーガーの描画部分をフックしちゃいましょう。

先程作成したハンバーガーを拡張します。
オーバーライドするメソッドは、drawメソッドです。

toggle.setDrawerArrowDrawable(new DrawerArrowDrawable(this){
    @Override
    public void draw(Canvas canvas) {
        // ここに背景を描画する処理を追加する。

        super.draw(canvas); // ハンバーガーを描画
    }
});

ここから、canvasを使っていきます。
canvasについては詳しく触れませんが、様々な描画が出来るようです。
今回は、このcanvasで四角をハンバーガーの後ろに描画して背景とします。

ハンバーガーのサイズに合わせて四角を描画するために、ハンバーガーのサイズを取得します。

getIntrinsicWidth() // ハンバーガーの横幅取得
getIntrinsicHeight() // ハンバーガーの縦幅取得

最後にいよいよ四角を描画するのですが、原点(0, 0)の位置がcanvasの左上に居ません。
ハンバーガーを描画する際に、原点がずらされるようです。

原点は、ハンバーガー自体の左上が原点になるみたいなので、四角の引数は、(0, 0, ハンバーガーの横幅, ハンバーガーの縦幅)になります。

四角を作成するための引数は、(四角の左上x座標, 四角の右上x座標, 四角の横幅, 四角の縦幅)です。

こんな感じです。

new RectF(0, 0, getIntrinsicWidth(), getIntrinsicHeight())

作成した四角と、角の曲がり具合とpaintを引数に、四角を描画します。
paintの説明は後述します。

canvas.drawRoundRect(new RectF(0, 0, getIntrinsicWidth(), getIntrinsicHeight()), 10f, 10f, getPaint());

今回は、曲がり具合を10fとしましたが、適当です。

これでハンバーガーの後ろに四角い枠が出来ると思います。
現段階のハンバーガーの全容も載せておきます。

toggle.setDrawerArrowDrawable(new DrawerArrowDrawable(this){
    @Override
    public void draw(Canvas canvas) {
        // 丸角の四角を描画
        // getIntrinsicWidth でハンバーガーの横幅が取れます
        // getIntrinsicHeight でハンバーガーの縦幅が取れます
        canvas.drawRoundRect(new RectF(0, 0, getIntrinsicWidth(), getIntrinsicHeight()), 10f, 10f, getPaint());

        super.draw(canvas); // ハンバーガーを描画
    }
});

背景を塗る

このままだと、四角い枠だけで背景っぽくないです。
色を塗りましょう。

色を塗るために、先程出てきたpaintを使っていきます。

調べてないので適当な事言いますが、このpaintはどのように描画するか、を詳しく決めるもののようです。
getPaint()を用いると、共通のpaintを使うような雰囲気です。

今回は新しくpaintを作っちゃいましょう。

Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL); // 四角の中全塗り
paint.setColor(Color.WHITE); // 白で塗る

四角の描画に今回作成したpaintを用います。

canvas.drawRoundRect(new RectF(0, 0, getIntrinsicWidth(), getIntrinsicHeight()), 10f, 10f, paint);

ハンバーガーの全容を載せます。

toggle.setDrawerArrowDrawable(new DrawerArrowDrawable(this){
    @Override
    public void draw(Canvas canvas) {
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL); // 四角の中全塗り
        paint.setColor(Color.WHITE); // 白で塗る

        // 丸角の四角を描画
        // getIntrinsicWidth でハンバーガーの横幅が取れます
        // getIntrinsicHeight でハンバーガーの縦幅が取れます
        canvas.drawRoundRect(new RectF(0, 0, getIntrinsicWidth(), getIntrinsicHeight()), 10f, 10f, paint);

        super.draw(canvas); // ハンバーガーを描画
    }
});

おわり

これにて終了です。

恐らく今回紹介した処理を書くと、トップに載せたようなハンバーガーになると思います。

canvasに四角を描画する際に、res/drawableのShapeDrawableから引っ張ってきたかったのですが、また詰まりました。
今回は諦めてdrawの中に四角描画を書いたのですが、解決出来たらまた記事書きます。

ここまで読んでくださってありがとうございます。
あなたの問題が解決出来たら幸いです。

リンク