Issue
I have looked through plenty of sources trying to find how to break the text in a dropdown item into two lines, so that is could be shown fully, but unfortunately I haven't found any solution.
Instead, only the beginning of the string is shown, and it ends with ellipsis.
Here is my code in LoginActivity:
autoSuggestAdapter = AutoSuggestAdapter(
this,
R.layout.abc
)
autoCompleteTextView.threshold = 2
autoCompleteTextView.setAdapter(autoSuggestAdapter)
autoCompleteTextView.onItemClickListener =
OnItemClickListener { parent, view, position, id ->
selectedText.text = autoSuggestAdapter!!.getObject(position)
}
handler = Handler(Looper.getMainLooper(), Handler.Callback { msg ->
if (msg.what === TRIGGER_AUTO_COMPLETE) {
if (!TextUtils.isEmpty(autoCompleteTextView.text)) {
makeApiCall(autoCompleteTextView.text.toString())
}
}
false
}
)
class AutoSuggestAdapter
class AutoSuggestAdapter(context: Context, resource: Int) :
ArrayAdapter<String>(context, resource), Filterable {
private val mlistData: MutableList<String>
fun setData(list: List<String>?) {
mlistData.clear()
mlistData.addAll(list!!)
}
override fun getCount(): Int {
return mlistData.size
}
@Nullable
override fun getItem(position: Int): String {
return mlistData[position]
}
fun getObject(position: Int): String {
return mlistData[position]
}
override fun getFilter(): Filter {
return object : Filter() {
protected override fun performFiltering(constraint: CharSequence?): FilterResults {
val filterResults = FilterResults()
if (constraint != null) {
filterResults.values = mlistData
filterResults.count = mlistData.size
}
return filterResults
}
protected override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
if (results != null && results.count > 0) {
notifyDataSetChanged()
} else {
notifyDataSetInvalidated()
}
}
}
}
init {
mlistData = ArrayList()
}
abc.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:ellipsize="end"
android:maxLines="2"
android:lines="2"
android:textAppearance="?attr/textAppearanceSubtitle1"
/>
Solution
I managed to solve the issue by overriding getView function in my AutoSuggestAdapter.
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view: TextView = convertView as TextView? ?: LayoutInflater.from(context).inflate(layoutResource, parent, false) as TextView
var r = mlistData[position]
// ...
return view
}
For line break, there is a specific android class, but I couldn't use it in Kotlin. Besides, it is supported only in API 29 and higher. So I wrote the following code that inspects spaces across the string and checks whether the current line exceeds the width of the screen or not:
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view: TextView = convertView as TextView? ?: LayoutInflater.from(context).inflate(layoutResource, parent, false) as TextView
var r = mlistData[position]
paint.textSize = scaledPx
var k = -1
var n = -1
var str = ""
while (k < r.length) {
if (r.indexOf(" ", k+1) == -1) {
if (paint.measureText(r.substring(n+1, r.length)) > widthPixels) {
var line1 = r.substring(n+1, k)
var line2 = r.substring(k+1, r.length)
str = "$str$line1\n$line2"
} else {
var line = r.substring(n+1, r.length)
str = "$str$line"
}
break
} else {
if (paint.measureText(r.substring(n+1, r.indexOf(" ", k+1))) > widthPixels) {
var line = r.substring(n+1, k)
n = k
str = "$str$line\n"
} else {
k = r.indexOf(" ", k+1)
}
}
}
view.text = str.substring(0, str.length)
return view
}
Future improvements might be implementing some kind of word wrap. Any suggestions are appreciated.
Answered By - prosyanoy
Answer Checked By - Cary Denson (JavaFixing Admin)