【AndroidStudio】Kotlinでボタンに画像とテキストを表示する方法

AndroidStudioでボタンに画像とテキストを表示させたいときはButtonタグにdrawableStart等を使ってやれば，ボタンの中に画像とテキストを表示することができる．しかし元々drawableに用意していた画像を表示させたくなった時，画像が大きいと画像がボタンに収まりきらない．これは小さいサイズの画像を作ることで簡単に解決できるが，別の解決方法が知りたかった(画像を作るのが面倒だった)のでdrawableStart等を使わずに表示する方法を載せる．
# 完成イメージ
完成したときのイメージはこんな感じ．
![2022-09-04 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671458/612babec-90bc-cd1a-2a2f-b273e6cce09a.png)

# ボタンの見た目を作成
ボタンの見た目を作成するためにまずレイアウトファイルを作成する．
layoutフォルダで右クリック →　New -> XML -> Layout XML Fileの順にクリック　→　Layout File Nameに好きな名前を付けてFinish

![2022-09-04 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671458/6aea606d-ebfb-8bba-9c3c-004c71709913.png)
![2022-09-04 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671458/4f18035a-9a02-babd-442d-b421ab3ca96d.png)

作成したレイアウトファイルに以下を記述
ImageViewのsrcに表示させたい画像を指定する．
```xml:my_custom_button.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    style="@style/Widget.AppCompat.Button">

    <ImageView
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:src="@drawable/dog_akitainu"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="テキスト"
        android:textSize="20sp"/>

</LinearLayout>
```

# ボタンのClassファイルを作る
パッケージで右クリック →　New -> Kotlin Class Fileの順にクリック　→　好きな名前を付けてClassを選択
![2022-09-04 (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671458/a149cc2b-d3c1-f049-ae16-d2f260c66950.png)
![2022-09-04 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671458/b469301a-c48c-a9f5-af4e-3510f70d8818.png)

作成したClassファイルに以下を記述
LayoutInflaterには先ほど作成したレイアウトファイルを指定

```kotlin:MyCustomButon.kt
class MyCustomButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0): LinearLayout(context, attrs, defStyleAttr) {
    init {
        LayoutInflater.from(context).inflate(R.layout.my_custom_button, this)
    }

    private var listener: OnClickListener? = null

    override fun setOnClickListener( l: OnClickListener?) {
        listener = l
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (ev.action == MotionEvent.ACTION_UP) {
            if (listener != null) {
                post { listener!!.onClick(this) }
            }
        }
        return super.dispatchTouchEvent(ev)
    }
}
```

# 作成したボタンを使う
使いたいactivityのレイアウトファイルで作成したボタンのClassファイルを指定する

```xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.nokopi.custombutton.MyCustomButton
        android:id="@+id/customBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
```

activity内での記述は変数の型に注意すれば普通のボタンと一緒．

```kotlin:MainActivity.kt
val customBtn: MyCustomButton = findViewById(R.id.customBtn)
customBtn.setOnClickListener {
   //ボタン押したときの処理
}
```

# 参考資料
* [カスタムビューでボタンを作る](https://blog.tkt989.info/2018/01/06/%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%83%93%E3%83%A5%E3%83%BC%E3%81%A7%E3%83%9C%E3%82%BF%E3%83%B3%E3%82%92%E4%BD%9C%E3%82%8B "カスタムビューでボタンを作る")

# おわりに
この作り方を覚えておけばレイアウト次第で自分好みのボタンが作れるようになるので便利だなと思いました．
最後まで読んでいただきありがとうございました！何かありましたらコメントお願いします．