I have following scenario:
Chip definition:
<chip xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:chipIcon="@drawable/ic_baseline_house_24"
android:text="@string/chips_holder"
app:closeIconEnabled="true"
/>
section of xml containing a TextInputTeditText:
...
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:enabled="true"
android:hint="Gallery Selections"
android:layout_weight="1">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/fragment_gallery_text_input_edit_text_selections"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:cursorVisible="false"
android:focusable="false"
android:focusableInTouchMode="false" />
</com.google.android.material.textfield.TextInputLayout>
...
a room liveData result observer which provides data from a set of variables:
...
liveDataFilterGallery?.observe(
viewLifecycleOwner
){filterGalleryResult->
filterGalleryResult?.let { safeFilterGalleryResult->
safeFilterGalleryResult.apply {
val prefixes = arrayOf(
"Site No",
"Farm No",
"Site Id",
"Assignment Id",
"Category",
"Time Stamp")
fragmentGalleryTextInputEditTextSelections.setText(
(if(siteNo.isNullOrEmpty()) "" else "${prefixes[0]} = '$siteNo';") +
(if(farmNo.isNullOrEmpty()) "" else "${prefixes[1]} = '$farmNo';") +
(if(siteId.isNullOrEmpty()) "" else "${prefixes[2]} = '$siteId';") +
(if(assignmentId.isNullOrEmpty()) "" else "${prefixes[3]} = '$assignmentId';") +
(if(category.isNullOrEmpty()) "" else "${prefixes[4]} = '$category';") +
(if(timeStamp.isNullOrEmpty()) "" else "${prefixes[5]} = '$timeStamp';"))
setEntryChips(fragmentGalleryTextInputEditTextSelections.text!!)
}
}
}
...
A function setEntryChips
which creates chips and uses spannable
to "replace" text with this ChipDrawable. Searches editables for ;
and creates chips upon that. (The ;
is addded through a selection function and replacing function not shown here.)
private fun setEntryChips(editable: Editable)
{
var position = 0
Log.i(TAG, "setEntryChips: editable.length = ${editable.length}")
Log.i(TAG, "setEntryChips: editable = '$editable'")
if(editable.isNotEmpty()) {
editable.split(';').mapIndexed { index, string ->
Log.i(TAG, "setEntryChips: split='$string'")
Log.i(TAG, "setEntryChips: index=$index")
if(string.isEmpty()) return@mapIndexed
val chipDrawable =
ChipDrawable.createFromResource(requireContext(), R.xml.input_selection_chip)
chipDrawable.text = string
chipDrawable.setBounds(
0,
0,
chipDrawable.intrinsicWidth,
chipDrawable.intrinsicHeight
)
val span = ImageSpan(chipDrawable)
editable.setSpan(
span,
position,
position + string.length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
position += string.length+1
/*
val chip = Chip(requireContext())
chip.setChipDrawable(chipDrawable)
chip.setOnCloseIconClickListener {
Log.i(TAG, "setEntryChips: closeIcon clicked = $string")
}
*/
Log.i(TAG, "setEntryChips: it.length = ${string.length}")
Log.i(TAG, "setEntryChips: position = $position")
}
}
}
My suggestion to wrap the chipDrawable
into a Chip
view programmatically fails, because the chip disappear from the TextInputEditText
, and therefore is no valid solution.
How do I add a clickListener
to the closeIcon
then, and keep the chip visible in the TextInputEditText
view ?
RG