自定义溢出菜单在android API 21和23+中无法提供相同的结果

问题描述 投票:0回答:1

我已经通过styles.xml定制了溢出菜单

<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
    <!-- Customize your theme here. -->
    ...
    <item name="popupTheme">@style/CustomOverFlow</item>
    ...
</style>

<style name="CustomOverFlow" parent="android:Widget.PopupMenu">
    <item name="android:bottomLeftRadius">25dp</item>
    <item name="android:bottomRightRadius">25dp</item>
    <item name="android:topLeftRadius">25dp</item>
    <item name="android:topRightRadius">25dp</item>
    <item name="android:selectableItemBackground">@drawable/rounded_ripple</item>
</style>

这是我通过API 21获得的结果:

enter image description here

但是这是我从23种以上的API中获得的:

enter image description here

请帮助我

我已经通过styles.xml自定义了溢出菜单

注意:未经测试

[Android Studio应该允许代码转换,如果您在复制粘贴时需要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>
java android user-interface menu android-styles
1个回答
0
投票

注意:未经测试

© www.soinside.com 2019 - 2024. All rights reserved.