アプリケーション開発ポータルサイト
ServerNote.NET
ServerNote.NET厳選キャンペーン・クーポンはこちら!
カテゴリー【AndroidJava
【Android】Buttonが常に最前面に来る問題を回避してボタンに画像を重ねる
POSTED BY
2022-07-13

単純なものならButtonにdrawableLeft等を指定すればよいが、複雑なカスタムボタンはFrameLayoutやRelativeLayoutを使ってButtonにImageViewを重ねてレイアウトすることがよくある。
画像の一番上のボタンは以下のようにレイアウトしている。

XMLlayout/arrow_button_under_api21.xmlGitHub Source
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/arrow_button_under_api21"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center">

    <Button
        android:id="@+id/arrow_button_under_api21_button"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:background="@drawable/round_gray_w"
        android:gravity="center"
        android:minWidth="0dp"
        android:minHeight="0dp"
        android:padding="8dp"
        android:text="選択してください"
        android:textColor="@color/white"
        android:textSize="16dp" />

    <ImageView
        android:layout_width="16dp"
        android:layout_height="16dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:src="@drawable/arrow_down" />
</RelativeLayout>

RelativeLayoutを使ってButtonの次にImageを重ねているのにもかかわらず、Imageが表示されていない。これはAPI LEVEL 21 = Lolipop 以上の時に起きる現象で、それ未満の場合は2番目のボタンのように正常にImageが左に出現する。

Lolipop以上の場合、Buttonに
android:stateListAnimator="@null"
を指定(影を無効にする)すれば、2番目のボタンのようにImageがちゃんと表示される。

XMLlayout/arrow_button_after_api21.xmlGitHub Source
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/arrow_button_after_api21"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center">

    <Button
        android:id="@+id/arrow_button_after_api21_button"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:background="@drawable/round_gray_w"
        android:gravity="center"
        android:minWidth="0dp"
        android:minHeight="0dp"
        android:padding="8dp"
        android:stateListAnimator="@null"
        android:text="選択してください"
        android:textColor="@color/white"
        android:textSize="16dp" />

    <ImageView
        android:layout_width="16dp"
        android:layout_height="16dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:src="@drawable/arrow_down" />
</RelativeLayout>

しかしこの命令はLolipop以降にしか存在しないため、minSdkVersion が 21未満の端末で実行しようとすると落ちる。よって21未満をサポートするならXMLでなくコードでバージョンにより処理を入れる必要があるが、setContentViewした後では効かない場合があり現実的ではない。

Button button = (Button)findViewById( R.id.button );
if( Build.VERSION.SDK_INT < 21 ){
    button.stateListAnimator = null; //addViewされたボタンには効かない?
}

なのでここからが本題だが、上記問題いずれにも対応するには、Buttonを使わずにTextViewとselectorの組み合わせでボタンを作ってしまえばよい。それが画像の一番下のボタンである。以下のように作成する。

XMLlayout/arrow_button.xmlGitHub Source
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/arrow_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:background="@drawable/selector_round_gray_w"
    android:clickable="true">

    <TextView
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="8dp"
        android:text="選択してください"
        android:textColor="@drawable/selector_color_black"
        android:textSize="16dp" />

    <ImageView
        android:layout_width="16dp"
        android:layout_height="16dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:src="@drawable/arrow_down" />
</RelativeLayout>

RelativeLayoutをclickableにしてselectorをbackgroundに作成。ButtonでなくTextViewにして、textColorをクリックに合わせて変えるselectorを作成。

XMLdrawable/selector_round_gray_w.xmlGitHub Source
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape xmlns:android="http://schemas.android.com/apk/res/android">
            <corners android:radius="10dp" />
            <solid android:color="@color/white" />
            <stroke android:width="1.5px" android:color="@color/white" />
        </shape>
    </item>
    <item android:state_pressed="false">
        <shape xmlns:android="http://schemas.android.com/apk/res/android">
            <corners android:radius="10dp" />
            <solid android:color="@color/gray" />
            <stroke android:width="1.5px" android:color="@color/white" />
        </shape>
    </item>
</selector>

XMLdrawable/selector_color_black.xmlGitHub Source
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/black" android:state_pressed="true" />
    <item android:color="@color/white" android:state_pressed="false" />
</selector>

XMLvalues/colors.xmlGitHub Source
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="black">#000000</color>
    <color name="white">#ffffff</color>
    <color name="red">#c44857</color>
    <color name="pink">#e59087</color>
    <color name="green">#77acae</color>
    <color name="blue">#8686af</color>
    <color name="aquamarine">#7fffd4</color>
    <color name="palegreen">#98fb98</color>
    <color name="lightyellow">#f7efdb</color>
    <color name="yellow">#dcb654</color>
    <color name="darkyellow">#b8b05d</color>
    <color name="lightgray">#999999</color>
    <color name="gray">#808080</color>
    <color name="trans">#00ffffff</color>
    <color name="whitetrans">#99ffffff</color>
    <color name="blacktrans">#aa000000</color>
</resources>

drawable/arrow_down.png drawable/arrow_down.png

ポイントはTextViewのtextColorに指定するselectorは色のみを指定する訳なのでitem android:colorが必須であり、RelativeLayoutのbackgroundに指定するselectorは塗りつぶしを指定する訳なのでitem android:drawableもしくはsolidが必須である。

これでこのボタンは、タップした時に背景が白く、テキストが黒くハイライトするボタンとなる。

獣医師がおススメする猫用サプリ「シニア猫の健康維持に」定期コース初回998円でお届け!【毎日一緒 DHA&EPA】
【獣医師が認めたシニア猫サポートサプリメント 毎日一緒DHA&EPA】 猫用・毎日一緒は、たった1粒にシニア...READ MORE
北欧スタイル家具と個性派インテリア家具の販売【CASA HILS】
■北欧スタイルと個性派インテリアのCASA HILS(カーサヒルズ) シンプルでスタイリッシュなローベッドなど...READ MORE
不動産仲介手数料無料+キャッシュバックならゼロ区!
株式会社ZERO BASEは、都内を中心に仲介手数料完全無料の 不動産売買仲介業者になります。 また新築戸建で物...READ MORE
※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【webmaster/管理人】
自営業プログラマー
ご連絡は以下アドレスまで★

☆ServerNote.NETショッピング↓
ShoppingNote
☆お仲間ブログ↓
一人社長の不動産業務日誌
【キーワード検索】