Примечание: не проверено
Студия Android должна разрешить преобразование кода, если вам нужен код Java при вставке копии
Kotlin:
private var autocompletePopup: PopupWindow? = null
// feed it parent view (View of activity/fragment)
private fun showAutoComplete(parentView: View) {
// fetch your list of string to show here
val items = arrayListOf<String>()
if (items.isNotEmpty()) {
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.auto_complete_layout, null)
val recyclerView = view.findViewById<RecyclerView>(R.id.rv_popup_autocomplete)
recyclerView.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
recyclerView.addItemDecoration(
DividerItemDecorator(
ContextCompat.getDrawable(
context!!,
R.drawable.presence_divider
)!!
)
)
val adapter = AutocompletePopupAdapter(context!!)
adapter.data = items
adapter.notifyDataSetChanged()
recyclerView.adapter = adapter
adapter.setOnClick(object : PopupCallbacks<String> {
override fun onItemClick(view: View, position: Int, item: String) {
// ToDo : Do something with selected item String here
// like parentView.findViewById<TextView>(R.id.selected_item_result).text = item
dismissAutoComplete()
}
})
dismissAutoComplete()
autocompletePopup = PopupWindow(
view,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
autocompletePopup?.isOutsideTouchable = true
autocompletePopup?.isFocusable = false
// ignore this code if you are not sure what it does.
view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
val measured = view.measuredHeight
// Max area that popup should be allowed to occupy
val availableArea = parentView.findViewById<[your view on which popup will cover]>(R.id.[viewid])
val maxHeight = availableArea.height - 20 // -20 for margin
val popupHeight = if (measured > maxHeight) maxHeight else measured
autocompletePopup?.height = popupHeight
// ignore this code if you are not sure what it does.
// ToDo : Set view on which the dropdown will be shown
val button = parentView.findViewById<Buttom>(R.id.navbar_button)
autocompletePopup?.showAsDropDown(button)
} else dismissAutoComplete()
}
class AutocompletePopupAdapter(val context: Context) : RecyclerView.Adapter<AutocompletePopupAdapter.MyViewHolder>() {
var data : ArrayList<String> = arrayListOf()
private var callback: PopupCallbacks<String>? = null
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.txtAutocompleteItem.text = data[position]
holder.itemView.setOnClickListener{
callback?.onItemClick(it, position, data[position])
}
}
fun setOnClick(click: PopupCallbacks<String>){ callback = click }
override fun onCreateViewHolder(parent: ViewGroup, position: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.auto_complete_item,parent,false)
return MyViewHolder(view)
}
override fun getItemCount(): Int { return data.size }
inner class MyViewHolder(item: View) : RecyclerView.ViewHolder(item) {
val txtAutocompleteItem = itemView.findViewById<TextView>(R.id.txt_autocomplete_item)!!
}
}
// Optional custom divider, doesn't add divider to last item
inner class DividerItemDecorator(private val mDivider: Drawable) :
RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val pos = parent.getChildAdapterPosition(view)
if (pos != parent.layoutManager!!.itemCount - 1) {
outRect.bottom = mDivider.intrinsicHeight
}
}
override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
val dividerLeft = parent.paddingLeft
val dividerRight = parent.width - parent.paddingRight
val childCount = parent.childCount
for (i in 0 until childCount) {
val child = parent.getChildAt(i)
val pos = parent.getChildAdapterPosition(child)
if (pos != parent.layoutManager!!.itemCount - 1) {
val params = child.layoutParams as RecyclerView.LayoutParams
val dividerTop = child.bottom + params.bottomMargin
val dividerBottom = dividerTop + mDivider.intrinsicHeight
mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom)
mDivider.draw(canvas)
}
}
}
}
fun dismissAutoComplete() {
autocompletePopup?.let { if (it.isShowing) it.dismiss() }
autocompletePopup = null
}
override fun onStop() {
super.onStop()
dismissAutoComplete()
}
interface PopupCallbacks<T> {
fun onItemClick(view: View, position: Int, item: T)
}
Xmls:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/popup_autocomplete_background"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="5dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_popup_autocomplete"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/txt_autocomplete_item"
android:layout_width="wrap_content"
android:layout_height="28dp"
android:padding="5dp"
android:text="TextView"
android:textColor="@color/colorTabs" />
</LinearLayout>