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

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

@ -20,8 +20,8 @@
package org.isoron.uhabits.utils package org.isoron.uhabits.utils
import android.app.Activity import android.app.Activity
import android.app.Dialog
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
@ -36,7 +36,6 @@ import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.view.WindowManager import android.view.WindowManager
import android.widget.PopupWindow
import android.widget.RelativeLayout import android.widget.RelativeLayout
import android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM import android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM
import android.widget.RelativeLayout.ALIGN_PARENT_TOP 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 val View.sres: StyledResources
get() = StyledResources(context) get() = StyledResources(context)
fun PopupWindow.dimBehind() { fun Dialog.dimBehind() {
// https://stackoverflow.com/questions/35874001/dim-the-background-using-popupwindow-in-android window?.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
val container = contentView.rootView window?.setDimAmount(0.5f)
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 View.requestFocusWithKeyboard() { fun View.requestFocusWithKeyboard() {

Loading…
Cancel
Save