SearchView에서는 커스텀 불가능한 부분이 있어 EditText를 이용하여 ListView의 제목을 검색할 수 있도록 만들어 보았다.
시작 전에는 겁먹었으나 막상 하다보니 간단했다.
입력 값이 없을 때는 아답터에게 기존 데이터 배열을 붙이고,
입력 값을 있을 때는 입력값에 해당하는 값이 있는지 확인하고 있다면 해당 데이터만 배열에 add하여 아답터에게 노티파이해주면 된다.
① EditText와 ListView 정의
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounded_rec_blue"
android:hint="@string/search_name"
android:lines="1"
android:inputType="text"
android:drawableEnd="@drawable/svg_search"/>
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@id/edittext"
app:layout_constraintBottom_toBottomOf="parent"/>
② ListView의 아답터 정의
미리 만들어둔 ListView 하나의 아이템을 이용하여 데이터 연결
특별할 것 없이 일반적으로 사용하던대로 만들면 된다.
(나는 디바이스 내 이미지 파일을 가져오기 때문에 File 배열을 받아서 각 File의 이름을 TextView에 연결하였다.)
class ListAdapter(val files: MutableList<File>, val parentFrag: ControllerFragment): BaseAdapter() {
override fun getCount(): Int = files.size
override fun getItem(p0: Int): Any = files[p0]
override fun getItemId(p0: Int): Long = p0.toLong()
override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
val context = p2!!.context
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
var temp = p1
if (temp == null) temp = inflater.inflate(R.layout.item_list, p2, false)
temp!!.apply {
// 이곳에서 데이터를 붙이는 작업
return temp
}
}
③ EditText에 TextWatcher를 붙인다.
입력값이 변경되면 기존 배열 clear
if 값이 없거나 빈 문자만 있을 경우 -> 기존 데이터 모두 add
else 값이 파일의 이름에 포함되어 있다면 -> 해당 데이터만 add
아답터에게 데이터 수정되었음을 알리기
(여기서 files는 미리 디렉토리에서 받아온 파일 리스트)
if (files != null) {
searchList = files.toMutableList()
val adapter = LogListAdapter(searchList, parentFragment as ControllerFragment)
listview.adapter = adapter
edittext.addTextChangedListener(object : TextWatcher{
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun afterTextChanged(p0: Editable?) {
val text = edittext.text.toString()
searchList.clear()
if (text.isEmpty() || text == "") searchList.addAll(files)
else {
for (i in files.indices) {
val name = files[i].name
if (name.contains(text)) searchList.add(files[i])
}
}
adapter.notifyDataSetChanged()
}
})
}