いきさつ
デザインがiOSに寄せられた結果、AndroidでSearchViewをカスタマイズする必要が出ることは往々にしてよくあることだと思う。
なので、情報はいくらでも転がっていてすんなりいくと思っていたけど、思った以上に詰まったので絶対忘れるから自分向けに備忘録として残す。
1番詰まったのは、inflate
しているのに何かがダメで、InflateException
が起きてクラッシュしていた。rootをLinearLayout等にして試行錯誤してるうちに上手くいったので、何が原因だったかははっきりとはわかっていない。
完成形
テキストなし
テキストあり
構造
class CustomSearchView : RelativeLayout {
constructor(context: Context) : super(context) {
init(context)
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
init(context)
}
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
init(context)
}
private fun init(context: Context) {
inflate(context, R.layout.custom_search_view, this)
hideSearchPlate()
setupTextView()
}
private fun hideSearchPlate() {
val searchPlateId = searchView.context.resources.getIdentifier("android:id/search_plate", null, null)
val searchPlateView = searchView.findViewById<View>(searchPlateId) ?: return
searchPlateView.setBackgroundResource(R.color.clear)
}
private fun setupTextView() {
val searchSrcTextId = searchView.context.resources.getIdentifier("android:id/search_src_text", null, null)
val textView = searchView.findViewById<AutoCompleteTextView>(searchSrcTextId) ?: return
val hintColor = ContextCompat.getColor(context, R.color.gray)
textView.setHintTextColor(hintColor)
val textColor = ContextCompat.getColor(context, R.color.textBody)
textView.setTextColor(textColor)
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13.0f)
}
fun updateHintText(text: String) {
searchView.queryHint = text
}
}
hideSearchPlate
SearchViewに標準でついてくる下線を消す処理を行っている。
一部サイトでは、背景色と同色を指定して誤魔化しているが、自分はclearカラー(#00000000)を指定している。
setupTextView
SearchViewのhintの文字色(placeholderの色)、入力時の文字色、文字サイズの変更を行っている。
CustomSearchView.kt
で指定しているlayoutは、以下の通り。
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:id="@+id/baseLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/backgroundColor"
android:orientation="vertical">
<SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:background="@drawable/search_view_background"
android:closeIcon="@drawable/icon_button_delete"
android:iconifiedByDefault="false"
android:searchIcon="@drawable/icon_search" />
</RelativeLayout>
</merge>
CustomSearchViewを使用する側で高さを任意に扱えるように、marginだけ設定して他はmatch_parent
で最大まで広げている。
android:background="@drawable/search_view_background"
角丸や周囲の枠線を表示するために別途指定。
詳しくは、search_view_background
参照。
android:iconifiedByDefault="false"
SearchViewはデフォルトだと虫眼鏡をタップして検索入力欄が表示されるようにな挙動をする。
最初から検索入力欄を表示するためにfalse
を明示的に指定。
view_custom_search.xml
で指定しているsearch_view_background
は以下の通り。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:radius="10dp" />
<stroke
android:width="1dp"
android:color="@color/separatorColor" />
<padding
android:bottom="0dp"
android:left="-8dp"
android:right="0dp"
android:top="0dp" />
</shape>
solid
背景色
corners
角丸の丸み具合
stroke
枠線の太さと色