ActionBarのメニューにCheckBoxを表示する
前置き
ActionBar
では、メニューをすべて表示することができなかったり"showAsAction="never"
を設定したメニューがある場合、一部のメニューをActionBar
右端のドロップダウンに格納することがあります。
Andorid Developersではこの機能をAction Overflowと呼んでいます。
Action Overflowに関する細かい機能名称などが見つけられなかったため、この記事ではオーバーフローに格納されているメニューを「オーバーフローメニュー」と呼ぶことにします。
http://developer.android.com/design/patterns/actionbar.html
オーバーフローメニューの活用
ActionBarのオーバーフローメニューにはチェックボックスやラジオボタンを表示することができます。 メニューと違って常時表示されないデメリットはありますが、タイトルが表示されるのでどのような機能かわかりやすく、アイコンを用意しなくても良いというメリットもあります。
下の画像はPlayストアアプリでの例です。
以下、チェックボックスとラジオボタン、それぞれの実装について説明します。
サンプルではappcompat-v7
版のActionBarを使用しています。
チェックボックスの実装
チェックボックスを利用する際、オーバーフローメニュー以外ではチェックボックスが表示されない事に気をつけてください。
<item>
要素にshowAsAction="never"
を設定しておくことで確実にオーバーフローメニューにすることができますが、
showAsAction="always"
やshowAsAction="ifRoom"
を定義するとチェックボックスが表示されなくなります。
チェックボックス自体はメニューを定義しているxmlにandroid:checkable="true"
を加えるだけで表示されます。
最初からチェック済みにしたい場合はandroid:checked="true"
を定義してください。
<menu 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" tools:context=".MyActivity" > <item android:id="@+id/action_checkbox" android:title="チェックボックス" android:checkable="true" app:showAsAction="never" /> </menu>
最も注意すべき点として、チェックボックスの状態変更をソースコード上で行う必要があることに気をつけてください。
また、チェックボックスの状態はMenuItem.isChecked()
で取得できますが、ユーザ操作がチェックボックスに反映された後かどうかを意識する必要があります。
````MyActivity.java @Override public boolean onCreateOptionsMenu(Menu menu) { // メニュー生成 getMenuInflater().inflate(R.menu.menu, menu); return true; }
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_checkbox) {
// チェックボックスの状態変更を行う
item.setChecked(!item.isChecked());
// 反映後の状態を取得する
boolean checked = item.isChecked();
return true;
}
return super.onOptionsItemSelected(item);
}
````
以下の様な表示になります。
ラジオボタンの実装
ラジオボタンを使うといくつかのオーバーフローメニューからひとつを選ばせるようなUIを作ることができます。
チェックボックス同様、オーバーフローメニュー以外ではラジオボタンが表示されないことに注意してください。
各<item>
要素にはshowAsAction="never"
を指定する必要があります。
ラジオボタンでは、選択肢となる<item>
要素の親として<group>
を定義します。
この<group>
要素にandroid:checkableBehavior="single"
を定義することで、checked
状態になる<item>
要素をひとつだけに限定することができます。
このとき、各<item>
要素にはandroid:checkable="true"
を定義するとチェックボックスが表示されてしまうので注意してください。
また、特定の<item>
を最初から選択状態にしたい場合はその<item>
にandroid:checked="true"
を定義してください。
<menu 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" tools:context=".MyActivity"> <group android:checkableBehavior="single"> <item android:id="@+id/action_radio1" android:title="ラジオ1" app:showAsAction="never" /> <item android:id="@+id/action_radio2" android:title="ラジオ2" app:showAsAction="never" /> </group> </menu>
ラジオボタンでもチェックボックス同様、状態変更をソースコード上で行う必要があることに気をつけてください。
ただし、android:checkableBehavior="single"
を定義している場合、<group>
内のどれかひとつがMenuItem#setChecked(true)
されたときに他のMenuItem
はMenuItem#setChecked(false)
された状態になるため、選択された要素の状態のみ反映すれば良いことになります。
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); switch (id){ case R.id.action_radio1: item.setChecked(!item.isChecked()); Toast.makeText(this,"action_radio1",Toast.LENGTH_SHORT).show(); return true; case R.id.action_radio2: item.setChecked(!item.isChecked()); Toast.makeText(this,"action_radio2",Toast.LENGTH_SHORT).show(); return true; } return super.onOptionsItemSelected(item); }
以下のような表示になります。
トグルボタンの実装
トグルボタンとは
トグルボタンとは、ユーザが2つの状態(On/Off)を交互に切り替えることのできるUIです。
AndroidではToggleButton
やCheckBox
がこれに当たります。
API Level 14でON/OFFをわかりやすく切り替えるためのView
としてSwitch
が追加されました。
http://developer.android.com/reference/android/widget/Switch.html
トグルボタンについてより詳しい解説は以下にあります。 http://developer.android.com/guide/topics/ui/controls/togglebutton.html
問題
残念ながら、Switch
はSupportLibraryに含まれていません。
そのため、API Level 14未満の端末ではSwitch
を使うことができません。
解決方法
主な解決方法は2つあります。
ひとつはAPI Level 14未満でも動作するSwitch
と似たView
を自作することです。
GitHubでも以下のようなバックポートプロジェクトがいくつか存在します。
BoD/android-switch-backport
https://github.com/BoD/android-switch-backport
もうひとつの方法は、API Levelに応じて表示するView
を差し替える方法です。
API Level 14以降ではSwitch
、それ以前の端末であればToggleButton
というように出し分けを行います。
一件複雑に思えますが、Androidではトグルボタン系のViewをまとめてCompoundButton
として扱うことができるため、レイアウトファイルを分けるだけで簡単に対応することができます。
実装
まず、API Level 14未満の端末向けにToggleButton
を使ったレイアウトを定義します。
レイアウト階層に「API Level 14未満」という記述はできないので、デフォルトレイアウトに定義する形になります。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MyActivity"> <ToggleButton android:id="@+id/toggle" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
次に、API Level 14以上の端末向けにSwitch
を使ったレイアウトを定義します。
このとき、レイアウトファイル名とトグルボタンのandroid:id
はは完全に一致させる必要があります。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MyActivity"> <Switch android:id="@+id/toggle" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
最後に、Activity
側の処理です。
ソースコード上ではSwitch
もToggleButton
も一括してCompoundButton
として扱います。
CompoundButton
はSwitch
のように2つの状態を持つView
の抽象クラスで、状態の取得やリスナ関連の処理などが集約されており、
Switch
、ToggleButton
、CheckBox
などはいずれもCompoundButton
を継承したサブクラスになっています。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity); CompoundButton toggle = (CompoundButton)findViewById(R.id.compoundButton); toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // 状態が変更された Toast.makeText(MyActivity.this, "isChecked : " + isChecked, Toast.LENGTH_SHORT).show(); } }); }
これでどちらのトグルボタンもタップ時に現在の状態に応じたトーストが表示されるようになります。
結果
ここまでの実装で、以下のように端末バージョンに応じて表示の出し分けができるようになりました。 1枚目が2.3端末、2枚目が4.4端末での表示となります。
<uses-permission>設定の罠
<uses-permission>
Androidアプリが特定の機能を利用する場合、AndroidManifest.xml
にその機能の一覧を<uses-permission>として記述します。
たとえば、マイクによる録音を行うアプリの場合、以下の様な記述が必要となります。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.nein37.kanidaisuki" > <uses-permission android:name="android.permission.RECORD_AUDIO" />
この<uses-permission>の定義はアプリの中で使用する全ての機能に関して記述します。 <uses-permission>の内容はPlayストアのアプリページに記載され、その機能が重要なものであればインストール時に権限を許可しても良いかを確認するダイアログが表示されます。
<uses-feature>
Androidアプリが特定の機能を必要とする場合、AndroidManifest.xml
にその機能の一覧を<uses-feature>として記述します。
必要とするというのは、例えばOpenGL ESの特定のVersion以降が必要であるとか、カメラ機能が必須であるという場合です。
たとえば、マイク機能が必須であるアプリは以下の様な記述が必要となります。
(この記述だけでは録音機能を使うことはできませんが、マイクは必須となります)
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.nein37.kanidaisuki" > <uses-feature android:name="android.hardware.microphone" android:required="true" />
この<uses-feature>情報はPlayストアには記載されません。 <uses-feature>を満たしている端末の場合、Playストア上から何の問題もなくインストールされます。 このとき、<uses-permission>と違い、特に確認ダイアログなどは表示されません。 <uses-feature>を満たしていない端末の場合、そもそもアプリがPlayストア上に表示されません。 ブラウザ版から該当端末にインストールしようとした場合でも「お使いの端末にはインストールできません」という旨のメッセージが表示され、インストールすることができません。
2つの設定の違い
<uses-permission>と<uses-feature>の違いは、それがチェックされるタイミングになります。 <uses-permission>がアプリを許可するかどうかをユーザに判断させているのに対し、 <uses-feature>はそもそもアプリがインストール可能かどうかをPlayストアが判定しています。 <uses-feature>の設定を失敗すると潜在的なアプリユーザを狭めてしまうので、要注意です。
<uses-permission>の罠
<uses-permission>を設定した時、その機能が参照するハードウェア機能の<uses-feature>が暗黙的に設定されます。
<uses-permission android:name="android.permission.RECORD_AUDIO" />
上記の設定は、Playストア上では以下のように解釈されます。
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-feature android:name="android.hardware.microphone" android:required="true" />
通常、上記のような場合はあまり問題になることはありません。 録音機能を利用するためにマイクが必要なのは当然だからです。 しかし、次の様な場合もあります。
このアプリはメモ録音と文字起こしのためにマイク機能を利用します。しかし必須ではありません。 マイクがない端末でもキーボードによる文字入力で代替したいです。
この時、<uses-permission>だけ設定してしまうと、<uses-feature>も補完されてしまい、マイクがない端末にはインストールできなくなってしまいます。 このように<uses-permission>が必須機能でない場合、以下のように記述します。
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-feature android:name="android.hardware.microphone" android:required="false" />
これでこのアプリにマイクは必須ではないと宣言することができました。 マイクのない端末でもインストールできるようになります。 ただし、実行時にマイクがあるかどうかを判定する必要があるので注意が必要です。
おまけ
<uses-permission>と<uses-feature>の対応表はAndroid Developersの以下のページに書いてあります。 http://developer.android.com/guide/topics/manifest/uses-feature-element.html#permissions
AndroidのUtilsクラスまとめ
はじめに
androidのUtilsをまとめた資料が見当たらなかったので作りました。 android.*パッケージに含まれるものだけまとめています。
TextUtils
文字列操作用Utils。
isEmpty()
とかequals()
とかよく使う。
文字列操作系も大体揃っていて便利。
isGraphic()
とかellipsize()
とか使ったことないけど気になるメソッドもある。
SupportLibrary
に最新版との差分をまとめたTextUtilsCompat
がある。
http://developer.android.com/reference/android/text/TextUtils.html
http://developer.android.com/reference/android/support/v4/text/TextUtilsCompat.html
NavUtils
Up動作を実装するのに使う。 これだけ使っても思ったように実装できないことが多い気がする。 Up動作の実装については以前まとめた。 http://developer.android.com/reference/android/support/v4/app/NavUtils.html
DatabaseUtils
DBとCursor
を扱うためのUtils。
Cursor
の中身をContentValues
に入れるメソッドが大量にある。
concatenateWhere()
という2つのwhere句をAND
でつないでくれるメソッドが微妙に便利。
SupportLibrary
に最新版との差分をまとめたDatabaseUtilsCompat
がある。
http://developer.android.com/reference/android/database/DatabaseUtils.html
http://developer.android.com/reference/android/support/v4/database/DatabaseUtilsCompat.html
DateUtils
formatDateRange()
とformatDateTime()
で色々な日付表現ができる。
でも大抵はSimpleDateFormatで事足りるイメージ。
非推奨のメソッドもあるので、使う際は注意。
http://developer.android.com/reference/android/text/format/DateUtils.html
URLUtil
URLを扱うためのUtils。
ただしURL
型ではなくString
のみ受け付ける。
有効なURLかどうかを判定してくれるisValidUrl()
やウェブURL判定のisNetworkUrl()
、isHttpsUrl()
あたりは使えそう。
なぜかこいつだけ名前がUtil。
http://developer.android.com/reference/android/webkit/URLUtil.html
PhoneNumberUtils
電話番号を扱うためのUtils。
Intent
から電話番号を取得するgetNumberFromIntent()
がtel:
もsip:
も対応してて便利。
表示用に日本向け(!)に整形してくれるformatJapaneseNumber()
というのもあるらしい。
isDialable()
とか便利そうだけどちゃんと動くのか未確認…。
http://developer.android.com/reference/android/telephony/PhoneNumberUtils.html
AnimationUtils
リソースからアニメーションの生成をしてくれるUtils。
loadInterpolator()
くらいしか使ったことがない…。
http://developer.android.com/reference/android/view/animation/AnimationUtils.html
ThumbnailUtils
サムネイルの生成Utils。 なんと画像だけでなく動画からもサムネイルの生成をしてくれる。 ただし、動画の場合はサイズが2種類しか選べない。 画像からは指定サイズで作れるから二重に生成すれば良いのだが…。 http://developer.android.com/reference/android/media/ThumbnailUtils.html
TouchUtils
タッチイベントをシミュレートするためのUtils。 ActivityInstrumentationTestCase2と合わせてUIテストに使う。 http://developer.android.com/reference/android/test/TouchUtils.html
GLUtils
OpenGL
扱うときに使うっぽいUtils。
使ったことがない…。
http://developer.android.com/reference/android/opengl/GLUtils.html
GestureUtils
ジェスチャー関連の解析とかをやるときに使うらしい。 使ったことがない…。 http://developer.android.com/reference/android/gesture/GestureUtils.html
DebugUtils
DebugUtils.isObjectSelected()
メソッドしかない。
ログ出すときにオブジェクトの状態がANDROID_OBJECT_FILTER
という環境変数の設定とマッチするかチェックしてくれる。
ANDROID_OBJECT_FILTER
環境変数ってどうやってセットするんだ?
http://developer.android.com/reference/android/util/DebugUtils.html
Androidに最適化されたJavaクラス一覧
はじめに
Androidではモバイル端末での処理に最適化されたいくつかの代替クラスが用意されています。 ほとんどがHashMap関係のメモリ消費を抑えるためのものですが、Android Developersにも代替クラスをまとめたページはないようなので、知っている範囲でまとめてみました。
SparseArray
似ている機能:HashMap<Integer,T>
SparseArrayはAndroid向けにパフォーマンスが改良されたHashMap<Integer,T>
の代替クラス。
Supportライブラリに最新のSparseArray
と同じ実装になったSparseArrayCompat
がある。
http://developer.android.com/reference/android/support/v4/util/SparseArrayCompat.html
LongSparseArray
似ている機能:HashMap<Long,T>
API level 16から追加された、keyがint
からlong
になったSparseArray
。
Supportライブラリにもある。
http://developer.android.com/reference/android/support/v4/util/LongSparseArray.html
SparseBooleanArray
似ている機能:HashMap<Integer,Boolean>
valueがboolean
型のSparseArray
。
HashMap<Integer,Boolean>
の置き換えができるが、value型がBoolean
ではなくboolean
なので注意。
http://developer.android.com/reference/android/util/SparseBooleanArray.html
SparseIntArray
似ている機能:HashMap<Integer,Integer>
valueがint
型のSparseArray
。
HashMap<Integer,Integer>
の置き換えができるが、value型がInteger
ではなくint
なので注意。
http://developer.android.com/reference/android/util/SparseIntArray.html
SparseLongArray
似ている機能:HashMap<Integer,Long>
API level 18から追加された、valueがlong
型のSparseArray
。
HashMap<Integer,Long>
の置き換えができるが、value型がLong
ではなくlong
なので注意。
Supporライブラリには存在しない。
https://developer.android.com/reference/android/util/SparseLongArray.html
ArrayMap
似ている機能:HashMap<K,V>
API level 19で追加された、Map<K,V>
の新しい実装。
HashMap
よりもメモリ効率が良い。
Supportライブラリにもある。
http://developer.android.com/reference/android/support/v4/util/ArrayMap.html
SimpleArrayMap
似ている機能:HashMap<K,V>
Supportライブラリにしか存在しない。
ArrayMap
からMap
インターフェイスの実装を外したバージョン。
…というよりも、ArrayMap
がこのクラスにMap
の実装を追加している。
おそらくこちらのほうが軽い。
http://developer.android.com/reference/android/support/v4/util/SimpleArrayMap.html
FloatMath
似ている機能:Math
(一部)
float
専用の数値演算処理クラス。
javaのMath
に比べて速いが、肝心のメソッドが少ない…。
http://developer.android.com/reference/android/util/FloatMath.html
Pair
似ている機能:AbstractMap.SimpleEntry<K,V>
key,valueの2つの値を任意の型で保持することができるクラス。
AndroidSDK上ではPair
のほうが先に実装されているが、AbstractMap.SimpleEntry<K,V>
とほぼ同様。
http://developer.android.com/reference/android/util/Pair.html
xmlns:toolsでAndroid Studioのレイアウトエディタを活用する
xmlns:tools?
Androidのレイアウトファイルに以下のような記述が含まれていることがあります。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".MyActivity"
このxmlns:tools
やtools:context
とはなんでしょうか。
答えは、Android Tools Projectに書いてありました。 http://tools.android.com/tech-docs/tools-attributes
英語よくわからん
という僕自身のために、内容を簡単にまとめました。
tools:ignore
lint用
tools:ignore
はリソースのすべてのxml要素に定義できる。
これを定義したxml要素とその子孫要素は、lintによるチェックで指定したissueが無視されるようになる。
複数のissueを無視したい場合、カンマ区切りで指定する。
<string name="show_all_apps" tools:ignore="MissingTranslation">All</string>
tools:targetApi
lint用 javaの@TargetApiと同じようなものでlintによるチェック時に適用される。 ApiLevelの指定はコードネームと整数両方いけるらしい。
<GridLayout tools:targetApi="ICE_CREAM_SANDWICH" >
tools:locale
lint/AndroidStudio用 values系リソースファイルのルート要素に定義できる。 これを指定したリソースの文字列は指定ロケール扱いになるらしい。 …デフォルトvaluesの文字列リソースが英語じゃない場合に使うと思うのだけど正直わからん。 結局日本語アプリではどうするべきなの?
<resources xmlns:tools="http://schemas.android.com/tools" tools:locale="es">
tools:context
lint/AndroidStudio/Eclipse用
レイアウトxmlのルート要素で定義する。
レイアウトエディタでの表示に指定Activity
のテーマが適用されるようになる。
Activity
の指定はAndroidManifest
同様package
からの相対パスで指定できるらしい。
<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"
tools:layout
AndroidStudio/Eclipse用 レイアウトxmlのfragment要素で定義する。 レイアウトエディタでのfragment要素の表示に指定したレイアウトが適用されるようになる。
<fragment android:name="com.example.master.ItemListFragment" tools:layout="@android:layout/list_content" />
tools:listitem / listheader / listfooter
AdapterView の子要素(ListViewなど)に定義できる。 それぞれ子要素のレイアウト、ヘッダのレイアウト、フッタのレイアウトを指定する。 レイアウトエディタでのAdapterViewの表示時に指定したレイアウトが適用されるようになる。
<ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" tools:listitem="@android:layout/simple_list_item_2" />
tools:showIn
AndroidStudio(0.5.8以降)用。
他のレイアウトから<include>
されるレイアウトのルート要素に定義できる。
AndroidStudioでレイアウトエディタ表示時に親レイアウトに埋め込まれた状態で表示されるらしい。
http://tools.android.com/recent/androidstudio058released
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:text="@string/hello_world" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:showIn="@layout/activity_main" />
tools:menu
AndroidStudio(0.8.0以降)用。
レイアウトのルート要素に定義できる。
AndroidStudioのレイアウトエディタではtools:context
でActivity
が指定されている場合、
Activity#onCreateOptionsMenu
までみてメニューアイテムを表示するらしい。
この要素が定義されているとそれを無視して指定したメニューアイテムを描画するようだ。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:menu="menu1,menu2" />
tools:actionBarNavMode
AndroidStudio(0.8.0以降)用。 レイアウトのルート要素に定義できる。 この要素が定義されている場合、レイアウトエディタにおいてActionBarを指定したモードで描画することができる。 "standard", "list", "tabs"のいずれかを指定する。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:actionBarNavMode="tabs" />
まとめ
toolsについて調べていたつもりがAndroidStudioのレイアウトエディタの進化に驚かされました。 レイアウトエディタからキャプチャも作れるので、tools属性を駆使すれば実機で確認ステップを少し減らせそうですね。 ぜひ活用していきたいです。
レイアウトの余白を埋める
余白を埋める
開発中、ViewとViewの間に余白を設けたい場合があります。
通常はmargin
やdivider
で調整しますが、間に余白のためのViewを置く場合もあると思います。
実はAndroidには、余白調整のためのSpaceというViewが存在しているのです。
Space
Space
はApi level 14で追加されたGridLayout
で発生する空のカラムを表現するために作られました。
Support Library v7にGridLayout
が収録された際、Space
も同時に収録されました。
Spaceと
他のViewとの大きな違いとして、描画を行わないという特徴があります。
以下のコードはSpace#draw
メソッドの実装になります。
/** * Draw nothing. * * @param canvas an unused parameter. */ @Override public void draw(Canvas canvas) { }
Draw nothingの言葉通り、Space
では背景色を含む一切の描画が行われません。
余白のみ背景色を変えたいという場合には使えませんが、Viewの中で最も描画負荷が少ないというメリットがあります。
実装
Gradleの場合、以下のようにgridlayout-v7
ライブラリを取り込みます。
compile 'com.android.support:gridlayout-v7:20.0.+'
例として、縦に並んだカニ画像の間に50dpの余白を設けてみます。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/darker_gray" android:orientation="vertical"> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/kani" /> <android.support.v7.widget.Space android:layout_width="match_parent" android:layout_height="50dp" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/kani" /> </LinearLayout>
こうなりました。
余白部分はLinearLayout
の背景が透過されています。
注意点
繰り返しになりますが、Space
に背景色を設定しても無視されます。
以下のような記述はできますが、描画には反映されません。
<android.support.v7.widget.Space android:layout_width="match_parent" android:background="@android:color/white" android:layout_height="50dp" />
使いどころ
正直、GridLayout
以外で使える場面はあまりないと思います。
大抵はmargin
やdivider
で十分です。
しかし、どうしても余白のためにViewを配置したい場合Space
の存在を思い出してください。