Using now Otalia Studios Autocomplete for Bank Autocomplete list in AddAccountDialog as it's way more performant than Android's AutoCompleteTextView
This commit is contained in:
parent
5ce48322a1
commit
a8ae3e9006
|
@ -5,6 +5,7 @@ ext {
|
||||||
appVersionCode = 1
|
appVersionCode = 1
|
||||||
|
|
||||||
kotlinVersion = '1.3.72'
|
kotlinVersion = '1.3.72'
|
||||||
|
kotlinCoroutinesVersion = "1.3.5"
|
||||||
|
|
||||||
javaUtilsVersion = '1.0.16-SNAPSHOT'
|
javaUtilsVersion = '1.0.16-SNAPSHOT'
|
||||||
|
|
||||||
|
@ -20,6 +21,8 @@ ext {
|
||||||
|
|
||||||
clansFloatingActionButtonVersion = '1.6.4'
|
clansFloatingActionButtonVersion = '1.6.4'
|
||||||
|
|
||||||
|
autocompleteVersion = "1.1.0"
|
||||||
|
|
||||||
multiDexVersion = "2.0.1"
|
multiDexVersion = "2.0.1"
|
||||||
|
|
||||||
appCompatVersion = "1.1.0"
|
appCompatVersion = "1.1.0"
|
||||||
|
|
|
@ -58,7 +58,10 @@ dependencies {
|
||||||
|
|
||||||
implementation "com.github.clans:fab:$clansFloatingActionButtonVersion"
|
implementation "com.github.clans:fab:$clansFloatingActionButtonVersion"
|
||||||
|
|
||||||
|
implementation "com.otaliastudios:autocomplete:$autocompleteVersion"
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
|
||||||
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutinesVersion"
|
||||||
|
|
||||||
implementation "net.dankito.utils:android-utils:$androidUtilsVersion", {
|
implementation "net.dankito.utils:android-utils:$androidUtilsVersion", {
|
||||||
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk7'
|
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk7'
|
||||||
|
|
|
@ -1,53 +1,39 @@
|
||||||
package net.dankito.banking.fints4java.android.ui.adapter
|
package net.dankito.banking.fints4java.android.ui.adapter
|
||||||
|
|
||||||
import android.content.Context.LAYOUT_INFLATER_SERVICE
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.Filter
|
|
||||||
import android.widget.Filterable
|
|
||||||
import kotlinx.android.synthetic.main.list_item_bank_info.view.*
|
|
||||||
import net.dankito.banking.fints4java.android.R
|
import net.dankito.banking.fints4java.android.R
|
||||||
import net.dankito.banking.ui.presenter.BankingPresenter
|
import net.dankito.banking.fints4java.android.ui.adapter.viewholder.BankInfoViewHolder
|
||||||
import net.dankito.banking.fints4java.android.ui.adapter.filter.BankInfoFilter
|
|
||||||
import net.dankito.fints.model.BankInfo
|
import net.dankito.fints.model.BankInfo
|
||||||
import net.dankito.utils.android.extensions.setTintColor
|
import net.dankito.utils.android.extensions.setTintColor
|
||||||
import net.dankito.utils.android.ui.adapter.ListAdapter
|
import net.dankito.utils.android.ui.adapter.ListRecyclerAdapter
|
||||||
|
|
||||||
|
|
||||||
open class BankListAdapter(protected val presenter: BankingPresenter) : ListAdapter<BankInfo>(), Filterable {
|
open class BankListAdapter(protected val itemClicked: ((BankInfo) -> Unit)? = null) : ListRecyclerAdapter<BankInfo, BankInfoViewHolder>() {
|
||||||
|
|
||||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View? {
|
override fun getListItemLayoutId() = R.layout.list_item_bank_info
|
||||||
|
|
||||||
val item = getItem(position)
|
override fun createViewHolder(itemView: View): BankInfoViewHolder {
|
||||||
|
return BankInfoViewHolder(itemView)
|
||||||
val inflater = parent?.context?.getSystemService(LAYOUT_INFLATER_SERVICE) as? LayoutInflater
|
|
||||||
val view = convertView ?: inflater?.inflate(R.layout.list_item_bank_info, parent, false)
|
|
||||||
|
|
||||||
view?.let {
|
|
||||||
if (item.supportsFinTs3_0) {
|
|
||||||
view.imgSupportsFints30.setImageResource(R.drawable.ic_check_circle_white_48dp)
|
|
||||||
view.imgSupportsFints30.setTintColor(R.color.list_item_bank_info_bank_supported)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
view.imgSupportsFints30.setImageResource(R.drawable.ic_clear_white_48dp)
|
|
||||||
view.imgSupportsFints30.setTintColor(R.color.list_item_bank_info_bank_not_supported)
|
|
||||||
}
|
|
||||||
|
|
||||||
view.txtvwBankName.text = item.name
|
|
||||||
|
|
||||||
view.txtvwBankCode.text = item.bankCode
|
|
||||||
|
|
||||||
view.txtvwBankAddress.text = item.postalCode + " " + item.city
|
|
||||||
}
|
|
||||||
|
|
||||||
return view
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun bindItemToView(viewHolder: BankInfoViewHolder, item: BankInfo) {
|
||||||
|
if (item.supportsFinTs3_0) {
|
||||||
|
viewHolder.imgSupportsFints30.setImageResource(R.drawable.ic_check_circle_white_48dp)
|
||||||
|
viewHolder.imgSupportsFints30.setTintColor(R.color.list_item_bank_info_bank_supported)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
viewHolder.imgSupportsFints30.setImageResource(R.drawable.ic_clear_white_48dp)
|
||||||
|
viewHolder.imgSupportsFints30.setTintColor(R.color.list_item_bank_info_bank_not_supported)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getFilter(): Filter {
|
viewHolder.txtvwBankName.text = item.name
|
||||||
return BankInfoFilter(presenter) {
|
|
||||||
this.setItems(it)
|
viewHolder.txtvwBankCode.text = item.bankCode
|
||||||
|
|
||||||
|
viewHolder.txtvwBankAddress.text = item.postalCode + " " + item.city
|
||||||
|
|
||||||
|
viewHolder.itemView.setOnClickListener {
|
||||||
|
itemClicked?.invoke(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
package net.dankito.banking.fints4java.android.ui.adapter.filter
|
|
||||||
|
|
||||||
import android.widget.Filter
|
|
||||||
import net.dankito.banking.ui.presenter.BankingPresenter
|
|
||||||
import net.dankito.fints.model.BankInfo
|
|
||||||
|
|
||||||
|
|
||||||
open class BankInfoFilter(protected val presenter: BankingPresenter,
|
|
||||||
protected val publishResultsCallback: (List<BankInfo>) -> Unit) : Filter() {
|
|
||||||
|
|
||||||
|
|
||||||
override fun performFiltering(constraint: CharSequence?): FilterResults {
|
|
||||||
val filteredBanks = presenter.searchBanksByNameBankCodeOrCity(constraint?.toString())
|
|
||||||
|
|
||||||
val results = FilterResults()
|
|
||||||
results.values = filteredBanks
|
|
||||||
|
|
||||||
return results
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun publishResults(constraint: CharSequence?, results: FilterResults) {
|
|
||||||
publishResultsCallback(results.values as List<BankInfo>)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package net.dankito.banking.fints4java.android.ui.adapter.presenter
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.otaliastudios.autocomplete.RecyclerViewPresenter
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import net.dankito.banking.fints4java.android.ui.adapter.BankListAdapter
|
||||||
|
import net.dankito.banking.ui.presenter.BankingPresenter
|
||||||
|
import net.dankito.fints.model.BankInfo
|
||||||
|
|
||||||
|
|
||||||
|
open class BankInfoPresenter(protected val presenter: BankingPresenter, context: Context) : RecyclerViewPresenter<BankInfo>(context) {
|
||||||
|
|
||||||
|
protected val adapter = BankListAdapter { dispatchClick(it) }
|
||||||
|
|
||||||
|
protected var lastSearchBanksJob: Job? = null
|
||||||
|
|
||||||
|
|
||||||
|
override fun instantiateAdapter(): RecyclerView.Adapter<*> {
|
||||||
|
return adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onQuery(query: CharSequence?) {
|
||||||
|
lastSearchBanksJob?.cancel()
|
||||||
|
|
||||||
|
lastSearchBanksJob = GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
val filteredBanks = presenter.searchBanksByNameBankCodeOrCity(query?.toString())
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
adapter.items = filteredBanks
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package net.dankito.banking.fints4java.android.ui.adapter.viewholder
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import kotlinx.android.synthetic.main.list_item_bank_info.view.*
|
||||||
|
|
||||||
|
|
||||||
|
open class BankInfoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
|
|
||||||
|
val imgSupportsFints30: ImageView = itemView.imgSupportsFints30
|
||||||
|
|
||||||
|
val txtvwBankName: TextView = itemView.txtvwBankName
|
||||||
|
|
||||||
|
val txtvwBankCode: TextView = itemView.txtvwBankCode
|
||||||
|
|
||||||
|
val txtvwBankAddress: TextView = itemView.txtvwBankAddress
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,8 @@ package net.dankito.banking.fints4java.android.ui.dialogs
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
|
@ -12,10 +14,12 @@ import android.widget.TextView
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import com.otaliastudios.autocomplete.Autocomplete
|
||||||
|
import com.otaliastudios.autocomplete.AutocompleteCallback
|
||||||
import kotlinx.android.synthetic.main.dialog_add_account.*
|
import kotlinx.android.synthetic.main.dialog_add_account.*
|
||||||
import kotlinx.android.synthetic.main.dialog_add_account.view.*
|
import kotlinx.android.synthetic.main.dialog_add_account.view.*
|
||||||
import net.dankito.banking.fints4java.android.R
|
import net.dankito.banking.fints4java.android.R
|
||||||
import net.dankito.banking.fints4java.android.ui.adapter.BankListAdapter
|
import net.dankito.banking.fints4java.android.ui.adapter.presenter.BankInfoPresenter
|
||||||
import net.dankito.banking.ui.model.responses.AddAccountResponse
|
import net.dankito.banking.ui.model.responses.AddAccountResponse
|
||||||
import net.dankito.banking.ui.presenter.BankingPresenter
|
import net.dankito.banking.ui.presenter.BankingPresenter
|
||||||
import net.dankito.fints.model.BankInfo
|
import net.dankito.fints.model.BankInfo
|
||||||
|
@ -31,8 +35,6 @@ open class AddAccountDialog : DialogFragment() {
|
||||||
|
|
||||||
protected lateinit var presenter: BankingPresenter
|
protected lateinit var presenter: BankingPresenter
|
||||||
|
|
||||||
protected lateinit var adapter: BankListAdapter
|
|
||||||
|
|
||||||
protected var selectedBank: BankInfo? = null
|
protected var selectedBank: BankInfo? = null
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,7 +42,6 @@ open class AddAccountDialog : DialogFragment() {
|
||||||
this.presenter = presenter
|
this.presenter = presenter
|
||||||
|
|
||||||
presenter.preloadBanksAsync()
|
presenter.preloadBanksAsync()
|
||||||
this.adapter = BankListAdapter(presenter)
|
|
||||||
|
|
||||||
val style = if(fullscreen) R.style.FullscreenDialogWithStatusBar else R.style.FloatingDialog
|
val style = if(fullscreen) R.style.FullscreenDialogWithStatusBar else R.style.FloatingDialog
|
||||||
setStyle(STYLE_NORMAL, style)
|
setStyle(STYLE_NORMAL, style)
|
||||||
|
@ -60,10 +61,7 @@ open class AddAccountDialog : DialogFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun setupUI(rootView: View) {
|
protected open fun setupUI(rootView: View) {
|
||||||
rootView.edtxtBankCode.threshold = 1 // will start working from first character
|
initBankListAutocompletion(rootView)
|
||||||
rootView.edtxtBankCode.setAdapter(adapter)
|
|
||||||
|
|
||||||
rootView.edtxtBankCode.setOnItemClickListener { _, _, position, _ -> bankSelected(adapter.getItem(position)) }
|
|
||||||
|
|
||||||
rootView.edtxtCustomerId.addTextChangedListener(otherEditTextChangedWatcher)
|
rootView.edtxtCustomerId.addTextChangedListener(otherEditTextChangedWatcher)
|
||||||
rootView.edtxtPin.addTextChangedListener(otherEditTextChangedWatcher)
|
rootView.edtxtPin.addTextChangedListener(otherEditTextChangedWatcher)
|
||||||
|
@ -72,6 +70,26 @@ open class AddAccountDialog : DialogFragment() {
|
||||||
rootView.btnCancel.setOnClickListener { dismiss() }
|
rootView.btnCancel.setOnClickListener { dismiss() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initBankListAutocompletion(rootView: View) {
|
||||||
|
val autocompleteCallback = object : AutocompleteCallback<BankInfo> {
|
||||||
|
|
||||||
|
override fun onPopupItemClicked(editable: Editable, item: BankInfo): Boolean {
|
||||||
|
bankSelected(item)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPopupVisibilityChanged(shown: Boolean) {}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Autocomplete.on<BankInfo>(rootView.edtxtBankCode)
|
||||||
|
.with(6f)
|
||||||
|
.with(ColorDrawable(Color.WHITE))
|
||||||
|
.with(autocompleteCallback)
|
||||||
|
.with(BankInfoPresenter(presenter, rootView.context))
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun addAccount() {
|
protected open fun addAccount() {
|
||||||
selectedBank?.let { selectedBank -> // should always be non-null at this stage
|
selectedBank?.let { selectedBank -> // should always be non-null at this stage
|
||||||
val customerId = edtxtCustomerId.text.toString()
|
val customerId = edtxtCustomerId.text.toString()
|
||||||
|
@ -156,8 +174,6 @@ open class AddAccountDialog : DialogFragment() {
|
||||||
|
|
||||||
edtxtFinTsServerAddress.setText(bank.pinTanAddress)
|
edtxtFinTsServerAddress.setText(bank.pinTanAddress)
|
||||||
|
|
||||||
edtxtBankCode.clearListSelection()
|
|
||||||
|
|
||||||
checkIfRequiredDataEnteredOnUiThread()
|
checkIfRequiredDataEnteredOnUiThread()
|
||||||
|
|
||||||
if (bank.supportsFinTs3_0 == false) {
|
if (bank.supportsFinTs3_0 == false) {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
android:hint="@string/dialog_add_account_enter_bank_code"
|
android:hint="@string/dialog_add_account_enter_bank_code"
|
||||||
>
|
>
|
||||||
|
|
||||||
<AutoCompleteTextView
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/edtxtBankCode"
|
android:id="@+id/edtxtBankCode"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/dialog_add_account_edit_text_height"
|
android:layout_height="@dimen/dialog_add_account_edit_text_height"
|
||||||
|
|
Loading…
Reference in New Issue