Android AutoCompleteTextView with MVVM and Databinding in Kotlin

Sanjay Kakadiya
Droid by me
2 min readJul 7, 2020

--

Our code example for today is about a very useful Android widget called AutocompleteTextView. Specifically, we’ll code an Android AutocompleteTextView with API data as drop-down suggestions.

If you’re not yet familiar with AutocompleteTextView, this widget looks like an EditText but shows completion suggestions automatically while the user is typing. The list of suggestions is displayed in a drop-down menu from which the user can choose an item to replace the content of the edit box.

Let’s start from app build.gradle. Add below dependencies in app build.gradle.

//Retrofit and GSON
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.6.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.2.1'

//Kotlin Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0"

// ViewModel and LiveData
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"

//Kodein Dependency Injection
implementation "org.kodein.di:kodein-di-generic-jvm:6.2.1"
implementation "org.kodein.di:kodein-di-framework-android-x:6.2.1"

And in android block enable data binding.

android {
....
dataBinding {
enabled = true
}
}

Add AutoCompleteTextView in your layout file.

<AutoCompleteTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:hint="@string/users"
android:inputType="textPersonName"
android:maxLength="90"
android:padding="12dp"
android:text="@={viewmodel.user}" //<-----Don't forgot this
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

Now let’s build our ViewModel. We will add MutableLiveData and MediatorLiveData to an observer the changes of AutoCompleteTextView. I used the GitHub API to search the user.

val user = MutableLiveData("")
var userList: MutableLiveData<ArrayList<User>> = MutableLiveData()

val valid = MediatorLiveData<Boolean>().apply {
addSource(user) {
searchUser(it)
value = true
}
}

private fun searchUser(name: String) {
CoroutineScope(Dispatchers.Main).launch {
try {
val response = repository.searchUser(name)
if(response.isSuccessful){
userList.value = response.body()?.items
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}

Now let’s set up our API service using Retrofit.

interface APIService {

@GET("search/users")
suspend fun searchUser(@Query("q") name: String): Response<MainResponse>


companion object {
operator fun invoke () : APIService {
val httpLoggingInterceptor = HttpLoggingInterceptor()
httpLoggingInterceptor.level = if (true) HttpLoggingInterceptor.Level.BODY
else HttpLoggingInterceptor.Level.NONE

val okkHttpclient = OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build()

return Retrofit.Builder()
.client(okkHttpclient)
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(APIService::class.java)
}
}
}

And now the last step is to setup the adapter to AutoCompleteTextView.

viewModel.userList.observe(this, Observer {
autoCompleteTextView.setAdapter(ArrayAdapter(this, android.R.layout.select_dialog_item, it))
})

That’s it. Now here is the result.

You can download code from the GitHub repository.

If you liked this post, kindly give me some claps and follow me for more posts like this one. Be sure to leave a comment if you have any thoughts or questions.

--

--