Quantcast
Channel: アカベコマイリ » Android
Viewing all articles
Browse latest Browse all 10

Android で画像なしの光沢グラデーション

$
0
0

スマートフォンなどでよく見かける、光沢のあるグラデーションを持ったツールバーを画像なしで作成してみる。

Android ではコントロールの描画方法を drawable リソースから指定できる。これは画像と XML に大別できる。

画像はデザインの自由度が高く美しいのだが、解像度 ( ldpi、mdpi、hdpi、…etc ) と引き延ばし ( 詳しくは Draw 9-patch を参照のこと。有志による日本語訳はこちら ) を意識する必要がある。

一方、XML はデザイン指定の方法がかなり限定されるため、希望どおりの描画結果を得るのが難しい。

しかし dp ( または dip。密度非依存ピクセル。詳しくは Supporting Multiple Screens を参照のこと。有志による日本語訳はこちら ) によるサイズ指定と標準で用意されている形状・塗りは解像度に依存しないため、様々な端末への対応が容易になる。

これらの立ち位置は、Web 開発における CSS と画像の関係によく似ている。

Web 開発の場合、描画に関する指定はなるべく CSS でおこない、それが難しい箇所で画像を用いるものだが、
Android でも同様に、アイコンなど複雑な形状を持つものは画像、それ以外は XML というように使い分けることでメンテナンス性が向上する。

さて、本題に入ろう。

まずは光沢グラデーションがどのように構成されているかを画像で表してみる。

光沢グラデーションの構造例

光沢グラデーションの構造例

下地となるグラデーションがあり、そこへ半分の高さをもつ半透明な陰影を乗せることで、あたかも光沢があるように見える。
これを Android の drawable リソースで再現すると以下のようになる。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- グラデーション下地 -->
    <item>
        <shape android:shape="rectangle">
            <gradient
                android:angle="270"
                android:startColor="#DDDDDD"
                android:endColor="#000000"
                android:type="linear" />
        </shape>
    </item>
    <!-- グラデーション陰影 -->
    <item android:top="20dp">
        <shape android:shape="rectangle">
            <solid android:color="#40000000" />
        </shape>
    </item>
</layer-list>

layer-list を利用すると、複数の形状をレイヤーとして重ね合わせた状態を定義できる。各レイヤーは item として表し、その中へ shapr などを入れ子にできる。

この定義は前述の画像で表したように、下地を描き、その上に陰影を重ねている。陰影レイヤーとなる item の android:top が、垂直方向の描画を開始する始点となる。
これは描画領域における相対位置となり、他にも bottom、left、right を指定できる。相対位置ではあるが、感覚としては余白の指定に近い。

位置の指定はディメンション値 ( dp、px、…etc ) となっているので、50% といった割合の定義はできないので注意する。
そのような指定を行いたい場合は、対象となる領域のサイズを決めてから、その割合を固定値として設定する。

今回は領域の高さを 40dp として、その下半分へ陰影が付くように android:top=”20dp” としている。
割合で指定できないのは仕様としてはイマイチな気がする。けれど、Android アプリの画面と GUI の点数はそれほど多くないから、実用上、困ることもないだろう。

これをツールバーの背景に利用するとして、次はその上に乗るボタンを定義してみたい。デザイン的には周辺にくぼみを持つボタンとする。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- くぼみ -->
    <item>
        <shape android:shape="rectangle">
            <corners
                android:bottomRightRadius="4dp"
                android:bottomLeftRadius="4dp"
                android:topLeftRadius="4dp"
                android:topRightRadius="4dp" />

            <gradient
                android:angle="270"
                android:startColor="#CC222222"
                android:endColor="#CCEEEEEE"
                android:type="linear" />
        </shape>
    </item>
    <!-- グラデーション下地 -->
    <item
        android:top="2dp"
        android:left="2dp"
        android:right="2dp"
        android:bottom="2dp">
        <shape android:shape="rectangle">
            <corners
                android:bottomRightRadius="4dp"
                android:bottomLeftRadius="4dp"
                android:topLeftRadius="4dp"
                android:topRightRadius="4dp" />

            <gradient
                android:angle="270"
                android:startColor="#DDDDDD"
                android:endColor="#222222"
                android:type="linear" />
        </shape>
    </item>
    <!-- グラデーション陰影 -->
    <item
        android:top="16dp"
        android:left="2dp"
        android:right="2dp"
        android:bottom="2dp">
        <shape android:shape="rectangle">
            <corners
                android:bottomRightRadius="0dp"
                android:bottomLeftRadius="0dp"
                android:topLeftRadius="4dp"
                android:topRightRadius="4dp" />

            <solid android:color="#40000000" />
        </shape>
    </item>
</layer-list>

少し長いが、基本的な考え方はツールバーと同じである。

一つ目のレイヤーでくぼみを定義する。これは上から下へ暗くなるグラデーションとなる。corners の指定はすべての角を丸めるようにする。透過と明るさを変更することで、くぼみ具合を調整できる。

二つ目のレイヤーは、ボタン部分の下地となる。これは前述のツールバー下地と同じような定義となる。

描画の開始をすべて 2dp で指定することにより、描画領域に対して 2dp の余白ができ、この部分にくぼみが描画される。つまりくぼみが枠線的に扱われるため、corners も同様の設定にしておく。

最後のレイヤーで、ボタンの下地に対する陰影を定義する。透過ありの単色塗りである。

これはボタンの下半分に乗せるため、corners の指定は下側だけ丸めるようにする。上も丸めてしまうと、ボタンの中腹にそれが表示されて不自然になるので注意する。

以上でツールバーとボタン用の光沢グラデーション指定ができた。さっそく利用してみよう。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#FF6A00"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <LinearLayout
        android:background="@drawable/toolbar"
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="40dp">
        <Button
            android:background="@drawable/toolbar_button"
            android:text="TEXT"
            android:textColor="#FFFFFF"
            android:textStyle="bold"
            android:textSize="16dp"
            android:shadowColor="#000000"
            android:shadowRadius="2.0"
            android:shadowDx="1.0"
            android:shadowDy="2.0"
            android:paddingLeft="8dp"
            android:paddingRight="8dp"
            android:paddingTop="4dp"
            android:paddingBottom="4dp"
            android:layout_marginLeft="4dp"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="32dp" />
    </LinearLayout>
</LinearLayout>


10 行目はツールバー、15 行目がボタンの背景指定。これを Android エミュレータで表示すると以下のようになる。

ツールバーとボタン

ツールバーとボタン

色や透明度を少し変更するだけで、かなり見た目が変わって面白い。

最後に、今回作成したサンプルのプロジェクトを公開しておく

サンプル プロジェクト
TestGlossyGradient.zip 13.8KB

Android 2.1 update 1 ( API Level 7 ) でビルドし、エミュレータと初代 Xperia ( SO-01B ) にて動作確認をおこなった。


Viewing all articles
Browse latest Browse all 10

Trending Articles