|
|
@@ -0,0 +1,132 @@
|
|
|
+package com.atmob.keyboard_android.popup
|
|
|
+
|
|
|
+import android.annotation.SuppressLint
|
|
|
+import android.content.Context
|
|
|
+import android.view.Gravity
|
|
|
+import android.view.LayoutInflater
|
|
|
+import android.view.View
|
|
|
+import android.view.ViewGroup
|
|
|
+import android.widget.PopupWindow
|
|
|
+import android.widget.TextView
|
|
|
+import androidx.recyclerview.widget.LinearLayoutManager
|
|
|
+import androidx.recyclerview.widget.RecyclerView
|
|
|
+import com.atmob.keyboard_android.R
|
|
|
+import com.atmob.keyboard_android.enums.Mode
|
|
|
+import com.atmob.keyboard_android.model.ModeItem
|
|
|
+import com.atmob.keyboard_android.popup.item.ModeListItemViewBinder
|
|
|
+import com.blankj.utilcode.util.ConvertUtils
|
|
|
+import me.drakeet.multitype.Items
|
|
|
+import me.drakeet.multitype.MultiTypeAdapter
|
|
|
+
|
|
|
+/**
|
|
|
+ * 模式切换PopupWindow弹窗
|
|
|
+ */
|
|
|
+class ModeSwitchPopupWindow(private val context: Context) {
|
|
|
+ private var popupWindow: PopupWindow? = null
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 显示弹窗
|
|
|
+ *
|
|
|
+ * @param anchorView 锚点View
|
|
|
+ */
|
|
|
+ @SuppressLint("InflateParams", "NotifyDataSetChanged")
|
|
|
+ fun show(anchorView: View) {
|
|
|
+ if (isShowing()) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ val context = anchorView.context
|
|
|
+
|
|
|
+ if (popupWindow == null) {
|
|
|
+ val contentView =
|
|
|
+ LayoutInflater.from(context).inflate(R.layout.popup_mode_switch_attach, null, false)
|
|
|
+
|
|
|
+ val currentSelectModeLayout: View =
|
|
|
+ contentView.findViewById(R.id.current_select_mode_layout)
|
|
|
+ val currentSelectMode: TextView = contentView.findViewById(R.id.current_select_mode)
|
|
|
+ val list: RecyclerView = contentView.findViewById(R.id.list)
|
|
|
+
|
|
|
+ currentSelectModeLayout.setOnClickListener {
|
|
|
+ dismiss()
|
|
|
+ }
|
|
|
+
|
|
|
+ val listItems = Items().apply {
|
|
|
+ addAll(Mode.getAll().mapIndexed { index, item ->
|
|
|
+ // TODO: 先写死选中第一个,后续根据flutter端传过来的模式,来决定选中哪个
|
|
|
+ ModeItem(item, selected = index == 0)
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ list.apply {
|
|
|
+ layoutManager = LinearLayoutManager(context)
|
|
|
+ adapter = MultiTypeAdapter(listItems).apply {
|
|
|
+ register(ModeItem::class.java, ModeListItemViewBinder { item ->
|
|
|
+ // 先全部反选
|
|
|
+ listItems.map {
|
|
|
+ if (it is ModeItem) {
|
|
|
+ it.selected = false
|
|
|
+ }
|
|
|
+ it
|
|
|
+ }
|
|
|
+ // 再选中当前选择的模式
|
|
|
+ val targetPosition = listItems.indexOf(item)
|
|
|
+ val targetItem = listItems[targetPosition] as ModeItem
|
|
|
+ targetItem.selected = true
|
|
|
+ notifyDataSetChanged()
|
|
|
+
|
|
|
+ // 更新当前选择的模式
|
|
|
+ currentSelectMode.text = targetItem.mode.modeName
|
|
|
+
|
|
|
+ // 关闭弹窗
|
|
|
+ dismiss()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ popupWindow = PopupWindow(
|
|
|
+ contentView,
|
|
|
+ ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
|
+ ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
|
+ true
|
|
|
+ ).apply {
|
|
|
+ // 不获取焦点,否则获取焦点会将软键盘关闭
|
|
|
+ isFocusable = false
|
|
|
+ // 点击外部关闭
|
|
|
+ isOutsideTouchable = true
|
|
|
+ // 保持输入法活跃
|
|
|
+ inputMethodMode = PopupWindow.INPUT_METHOD_NEEDED
|
|
|
+ // 设置弹出动画
|
|
|
+ animationStyle = R.style.PopupAnimation
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取相对于输入法窗口的坐标
|
|
|
+ val location = IntArray(2)
|
|
|
+ anchorView.getLocationInWindow(location)
|
|
|
+
|
|
|
+ // 计算弹窗显示位置
|
|
|
+ val popupX = location[0] - ConvertUtils.dp2px(5f)
|
|
|
+ val popupY = location[1] - ConvertUtils.dp2px(5f)
|
|
|
+
|
|
|
+ popupWindow?.showAtLocation(
|
|
|
+ anchorView,
|
|
|
+ Gravity.NO_GRAVITY,
|
|
|
+ popupX,
|
|
|
+ popupY
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 弹窗是否显示中
|
|
|
+ */
|
|
|
+ fun isShowing(): Boolean {
|
|
|
+ return popupWindow?.isShowing == true
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 关闭弹窗
|
|
|
+ */
|
|
|
+ fun dismiss() {
|
|
|
+ popupWindow?.dismiss()
|
|
|
+ }
|
|
|
+}
|