画像を使ってボタンのようにタップして何か処理をさせたい場合があります。そんな時は ImageButton が使えます。
2021.1.1
ImageButton
画像をタップして何かのActionが欲しい場合です。やり方はいろいろあり、そのまま画像にOnTouchListenerを設定する方法がストレートかもしれません。
ImageButtonという画像を使うことを前提にしたButtonがあるので画像を載せるとどうなるかやってます。
1. ImageButtonの画像設定
2. サンプルコード
3. 画像サイズが大きい場合
4. 画像サイズが小さい場合
5. ImageButtonをコードで作成
6. Buttonに画像を設定する
ImageButtonの画像設定
background と src:
ImageButtonを使って画像をボタンののようにタップでアクションを起こすことができますが、画像の設定には、「background」に指定する方法と「src」とする場合があります。
例として、400 x 267pix の画像(3:2)を res\drawable\ 以下に入れて表示させてみます。(画像はお好みのもので)
ImageButtonへの設定はそれぞれ以下のようにできます。
背景として
android:background
1 2 3 |
<ImageButton ... android:background="@drawable/image" /> |
画像をsourceとして
android:src
1 2 3 |
<ImageButton ... android:src="@drawable/image" /> |
サンプルコード
Android の Button アプリを作ってみる のようにやれば簡単にできます。
MainActivity.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
//package com.example.testimagebutton import androidx.appcompat.app.AppCompatActivity import android.os.Bundle // ViewBinding import com.example.testimagebutton.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) var flg = true binding.imageButton.setOnClickListener{ if (flg) { binding.textImagebutton.text = getString(R.string.tapped) flg = false } else { binding.textImagebutton.text = getString(R.string.image_button) flg = true } } } } |
レイアウトの設定ですが、画像をbackgroundで設定し、ImageButtonのサイズを指定しています。
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?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" android:background="#fdc" tools:context=".MainActivity"> <TextView android:id="@+id/text_imagebutton" android:text="@string/image_button" android:textSize="30sp" android:textColor="#ff0000" 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" app:layout_constraintVertical_bias="0.1" /> <ImageButton android:id="@+id/image_button" android:contentDescription="@string/image_description" android:background="@drawable/image" 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" app:layout_constraintVertical_bias="0.7" /> </androidx.constraintlayout.widget.ConstraintLayout> |
strings.xml
1 2 3 4 5 6 |
<resources> <string name="app_name">YourAppName</string> <string name="image_button">Image Button</string> <string name="tapped">Tapped</string> <string name="image_description">Serina</string> </resources> |
build.gralde
1 2 3 4 5 6 7 8 |
... android { ... buildFeatures { viewBinding true } } ... |
実行してみましょう
画像サイズが大きい場合
実はこの画像のサイズは画面サイズに合わせた大きさなので、画面サイズが異なる機種では不都合なことが起きます。
例えば、縦横倍の画像サイズにするとbackgroundに画像を設定するとアスペクトレシオが無視されてこうなります。
image_large.jpg (800 x 533pix)
android:background
1 2 3 4 5 |
<ImageButton ... android:background="@drawable/image_large" ... /> |
srcで画像を設定すると画像が切り取られてしまいます。
android:src
1 2 3 4 5 |
<ImageButton ... android:src="@drawable/image_large" ... /> |
対策:
android:background
スクリーン横幅に収まるように横幅と縦を計算して指定すれば改善できますが、機種の画面が変わるたびに画像サイズを自動計算して合わせないといけなくなります。
android:src
この場合は更にscaleTypeとして centerInside を入れて画像をボタン内に収めるようにします。
srcで画像を指定すると薄いグレーのboundsが画像の周りに見えてしまいます。
これはbackgroundに透明色などを設定すると
android:background=”#0000″
見えなくなります。
ただし! ボタン領域としては残ります。透明になっただけでタップに反応します。
1 2 3 4 5 6 7 |
<ImageButton android:id="@+id/image_button" android:src="@drawable/image_large" android:scaleType="centerInside" android:background="#0000" ... /> |
画像が小さい場合
画像はAndroidのスクリーンサイズよりも小さければ、wrap_contentが働き画像サイズのボタンになります。
1 2 3 4 5 6 7 |
<ImageButton ... android:src="@drawable/image_small" android:layout_width="wrap_content" android:layout_height="wrap_content" ... /> |
次はコードでImageButtonを記述する方法と、Buttonに画像を設定するやり方についてです。
ImageButtonをコードで作成
前の項目でXMLファイルを使ってImageButtonを設定できましたが、
コードで記述するとどうなるでしょうか、ダイナミックにボタンのサイズを変更したい場合はコードで書かないとXMLのレイアウトでは難しいでしょう。
同じようにボタンサイズを400dp x 267dpとして作成してみます。また、フラグで背景画像とするか画像ソースにするか切り替えてみます。
MainActivity.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
//package your.package.name import androidx.appcompat.app.AppCompatActivity import android.graphics.Color import android.os.Bundle import android.util.TypedValue import android.view.Gravity import android.widget.ImageButton import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import android.graphics.BitmapFactory import android.graphics.drawable.BitmapDrawable class MainActivity : AppCompatActivity() { private var flg = true private var textView: TextView? = null private var str1: String? = null private var str2: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val addSrc = true // リニアレイアウトの設定 val layout = LinearLayout(this) layout.orientation = LinearLayout.VERTICAL val mParent = LinearLayout.LayoutParams.MATCH_PARENT val wContent = LinearLayout.LayoutParams.WRAP_CONTENT layout.layoutParams = LinearLayout.LayoutParams( mParent, mParent ) // レイアウト中央寄せ layout.gravity = Gravity.CENTER // 背景色 layout.setBackgroundColor(Color.parseColor("#ffdfcf")) setContentView(layout) // TextView の設定 textView = TextView(this) str1 = "Image Button" str2 = "Tapped" textView!!.text = str1 val textViewLayoutParams = LinearLayout.LayoutParams( wContent, wContent ) textView!!.layoutParams = textViewLayoutParams // テキストカラー textView!!.setTextColor(Color.rgb(0xff, 0x0, 0x0)) // テキストサイズ textView!!.setTextSize(TypedValue.COMPLEX_UNIT_SP, 30f) // margin val margin10 = 10 * TypedValue.COMPLEX_UNIT_DIP textViewLayoutParams.setMargins(margin10, margin10, margin10, margin10) layout.addView(textView) // ボタンの設定 val imageButton = ImageButton(this) val dp400 = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 400f, resources.displayMetrics ).toInt() val dp267 = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 267f, resources.displayMetrics ).toInt() val buttonLayoutParams = LinearLayout.LayoutParams( dp400, dp267 ) // margin buttonLayoutParams.setMargins(margin10, margin10, margin10, margin10) // ボタンに画像を設定 val bitmap = BitmapFactory.decodeResource(resources, R.drawable.image) val drawable = BitmapDrawable(resources, bitmap) if (addSrc) { // Bitmapで画像を設定 imageButton.setImageBitmap(bitmap) // Drawableで画像設定 //imageButton.setImageDrawable(drawable); imageButton.scaleType = ImageView.ScaleType.CENTER_INSIDE imageButton.setBackgroundColor(Color.parseColor("#00000000")) } else { // 背景に画像を設定 imageButton.background = drawable } imageButton.layoutParams = buttonLayoutParams layout.addView(imageButton) // リスナーをボタンに登録 imageButton.setOnClickListener { if (flg) { textView!!.text = str2 flg = false } else { textView!!.text = str1 flg = true } } } } |
コードで記述したためレイアウトXMLはいりません。
Buttonに画像を設定する
ImageButtonの他に画像をボタンのようにするには、Buttonに画像を設定することでも可能でしたが、Android Studio 4 あたりからButtonに背景色がついたままになり背景の変更が容易ではなくなりました。
やり方はあると思いますが、あえてImageButtonがあるのでButtonを画像にするのは深入りするのはやめておきます。
ボタンのスタイル設定
References:
ボタン | Android デベロッパー | Android Developers
ImageButton | Android Developers