Replace PopupWindow by Dialog

Fixes issues with copy & paste, text selection and spell checking.
pull/1370/head
Alinson S. Xavier 3 years ago
parent 3021e408a7
commit e4b16f6d59

@ -19,15 +19,12 @@
package org.isoron.uhabits.activities.common.dialogs
import android.app.Dialog
import android.content.Context
import android.text.InputType
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.widget.PopupWindow
import kotlinx.android.synthetic.main.checkmark_popup.view.*
import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.Entry.Companion.NO
import org.isoron.uhabits.core.models.Entry.Companion.SKIP
@ -53,15 +50,11 @@ class CheckmarkPopup(
private val anchor: View,
) {
var onToggle: (Int, String) -> Unit = { _, _ -> }
private lateinit var popup: PopupWindow
private lateinit var dialog: Dialog
private val view = CheckmarkPopupBinding.inflate(LayoutInflater.from(context)).apply {
// Required for round corners
container.clipToOutline = true
// Android bugfix: Allowing suggestions in a popup causes a crash.
// stackoverflow.com/questions/4829718
container.notes.inputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
}
init {
@ -105,12 +98,15 @@ class CheckmarkPopup(
}
fun show() {
popup = PopupWindow()
popup.contentView = view.root
popup.width = view.root.dp(POPUP_WIDTH).toInt()
popup.height = view.root.dp(POPUP_HEIGHT).toInt()
popup.isFocusable = true
popup.elevation = view.root.dp(24f)
dialog = Dialog(context, android.R.style.Theme_NoTitleBar)
dialog.setContentView(view.root)
dialog.window?.apply {
setLayout(
view.root.dp(POPUP_WIDTH).toInt(),
view.root.dp(POPUP_HEIGHT).toInt()
)
setBackgroundDrawableResource(android.R.color.transparent)
}
fun onClick(v: Int) {
this.value = v
save()
@ -119,12 +115,13 @@ class CheckmarkPopup(
view.noBtn.setOnClickListener { onClick(NO) }
view.skipBtn.setOnClickListener { onClick(SKIP) }
view.unknownBtn.setOnClickListener { onClick(UNKNOWN) }
popup.showAtLocation(anchor, Gravity.CENTER, 0, 0)
popup.dimBehind()
dialog.setCanceledOnTouchOutside(true)
dialog.dimBehind()
dialog.show()
}
fun save() {
onToggle(value, view.notes.text.toString().trim())
popup.dismiss()
dialog.dismiss()
}
}

@ -19,17 +19,14 @@
package org.isoron.uhabits.activities.common.dialogs
import android.app.Dialog
import android.content.Context
import android.text.InputType
import android.view.Gravity
import android.view.KeyEvent.KEYCODE_ENTER
import android.view.LayoutInflater
import android.view.MotionEvent.ACTION_DOWN
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.widget.PopupWindow
import kotlinx.android.synthetic.main.checkmark_popup.view.*
import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.databinding.CheckmarkPopupBinding
@ -47,15 +44,11 @@ class NumberPopup(
) {
var onToggle: (Double, String) -> Unit = { _, _ -> }
private val originalValue = value
private lateinit var popup: PopupWindow
private lateinit var dialog: Dialog
private val view = CheckmarkPopupBinding.inflate(LayoutInflater.from(context)).apply {
// Required for round corners
container.clipToOutline = true
// Android bugfix: Allowing suggestions in a popup causes a crash.
// stackoverflow.com/questions/4829718
container.notes.inputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
}
init {
@ -79,12 +72,16 @@ class NumberPopup(
}
fun show() {
popup = PopupWindow()
popup.contentView = view.root
popup.width = view.root.dp(POPUP_WIDTH).toInt()
popup.height = view.root.dp(POPUP_HEIGHT).toInt()
popup.isFocusable = true
popup.elevation = view.root.dp(24f)
dialog = Dialog(context, android.R.style.Theme_NoTitleBar)
dialog.setContentView(view.root)
dialog.window?.apply {
setLayout(
view.root.dp(POPUP_WIDTH).toInt(),
view.root.dp(POPUP_HEIGHT).toInt()
)
setBackgroundDrawableResource(android.R.color.transparent)
}
view.value.setOnKeyListener { _, keyCode, event ->
if (event.action == ACTION_DOWN && keyCode == KEYCODE_ENTER) {
save()
@ -99,15 +96,16 @@ class NumberPopup(
view.value.setText((Entry.SKIP.toDouble() / 1000).toString())
save()
}
popup.showAtLocation(anchor, Gravity.CENTER, 0, 0)
view.value.requestFocusWithKeyboard()
popup.dimBehind()
dialog.setCanceledOnTouchOutside(true)
dialog.dimBehind()
dialog.show()
}
fun save() {
val value = view.value.text.toString().toDoubleOrNull() ?: originalValue
val notes = view.notes.text.toString()
onToggle(value, notes)
popup.dismiss()
dialog.dismiss()
}
}

@ -20,8 +20,8 @@
package org.isoron.uhabits.utils
import android.app.Activity
import android.app.Dialog
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.graphics.Canvas
import android.graphics.Color
@ -36,7 +36,6 @@ import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.view.WindowManager
import android.widget.PopupWindow
import android.widget.RelativeLayout
import android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM
import android.widget.RelativeLayout.ALIGN_PARENT_TOP
@ -219,15 +218,9 @@ fun View.drawNotesIndicator(canvas: Canvas, color: Int, size: Float, notes: Stri
val View.sres: StyledResources
get() = StyledResources(context)
fun PopupWindow.dimBehind() {
// https://stackoverflow.com/questions/35874001/dim-the-background-using-popupwindow-in-android
val container = contentView.rootView
val context = contentView.context
val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val p = container.layoutParams as WindowManager.LayoutParams
p.flags = p.flags or WindowManager.LayoutParams.FLAG_DIM_BEHIND
p.dimAmount = 0.5f
wm.updateViewLayout(container, p)
fun Dialog.dimBehind() {
window?.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
window?.setDimAmount(0.5f)
}
fun View.requestFocusWithKeyboard() {

Loading…
Cancel
Save