Fixes issues with editText focus

hh
Laurent 6 years ago
parent 5799a17fa9
commit 67155d382a
  1. 10
      app/src/main/java/net/pokeranalytics/android/model/handhistory/HHBuilder.kt
  2. 91
      app/src/main/java/net/pokeranalytics/android/ui/adapter/HandHistoryAdapter.kt
  3. 39
      app/src/main/java/net/pokeranalytics/android/ui/fragment/HandHistoryFragment.kt
  4. 4
      app/src/main/java/net/pokeranalytics/android/ui/view/handhistory/KeyboardAmountView.kt
  5. 1
      app/src/main/java/net/pokeranalytics/android/ui/view/handhistory/KeyboardContainer.kt
  6. 4
      app/src/main/java/net/pokeranalytics/android/ui/viewmodel/HandHistoryViewModel.kt
  7. 29
      app/src/main/res/layout/row_hand_action.xml

@ -233,6 +233,16 @@ class HHBuilder {
} }
/***
* Clears the amount at the given [index]
*/
fun clearAmount(index: Int) {
val computedAction = this.actionForIndex(index)
computedAction.action.amount = null
// TODO consequences?
}
/*** /***
* Returns the committed amount by the player for the street at the current [index] * Returns the committed amount by the player for the street at the current [index]
*/ */

@ -1,14 +1,15 @@
package net.pokeranalytics.android.ui.adapter package net.pokeranalytics.android.ui.adapter
import android.content.res.ColorStateList
import android.text.Editable import android.text.Editable
import android.text.InputType import android.text.InputType
import android.text.TextWatcher import android.text.TextWatcher
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Button import android.widget.Button
import android.widget.EditText import android.widget.EditText
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.exceptions.PAIllegalStateException
@ -68,13 +69,6 @@ class HandHistoryAdapter(
} }
} }
/**
* Update UI
*/
fun updateRows(diffResult: DiffUtil.DiffResult) {
diffResult.dispatchUpdatesTo(this)
}
inner class TextListener : TextWatcher { inner class TextListener : TextWatcher {
var position: Int = 0 var position: Int = 0
@ -98,17 +92,18 @@ class HandHistoryAdapter(
private var listener = TextListener() private var listener = TextListener()
private var currentPosition = 0 private var currentPosition = 0
private var actionCanBeEdited = true
private var amountCanBeEdited = true
init { init {
// Action // Action
itemView.findViewById<EditText>(R.id.actionEditText)?.let { actionEditText -> itemView.findViewById<Button>(R.id.actionButton)?.let { actionButton ->
actionEditText.inputType = InputType.TYPE_NULL actionButton.setOnClickListener {
actionEditText.setTextIsSelectable(false)
actionEditText.setOnFocusChangeListener { v, hasFocus -> if (this.actionCanBeEdited) {
Timber.d("ACTION > focus change = $hasFocus at position = $currentPosition") buttonEdited(actionButton, true, HHKeyboard.ACTION.ordinal)
editTextSelected(actionEditText, hasFocus, HHKeyboard.ACTION.ordinal) }
} }
} }
@ -116,20 +111,43 @@ class HandHistoryAdapter(
itemView.findViewById<EditText>(R.id.amountEditText)?.let { amountEditText -> itemView.findViewById<EditText>(R.id.amountEditText)?.let { amountEditText ->
amountEditText.inputType = InputType.TYPE_NUMBER_FLAG_DECIMAL amountEditText.inputType = InputType.TYPE_NUMBER_FLAG_DECIMAL
amountEditText.isFocusableInTouchMode = true
amountEditText.setOnTouchListener { v, event ->
if (this.amountCanBeEdited) {
amountEditText.setOnFocusChangeListener { v, hasFocus -> // Both are required, otherwise requestFocus() fails
Timber.d("AMOUNT > focus change = $hasFocus at position = $currentPosition") amountEditText.isFocusable = true
editTextSelected(amountEditText, hasFocus, HHKeyboard.AMOUNT.ordinal) amountEditText.isFocusableInTouchMode = true
amountEditText.requestFocus()
if (event.action == MotionEvent.ACTION_DOWN) {
editTextSelected(amountEditText, true, HHKeyboard.AMOUNT.ordinal)
}
}
return@setOnTouchListener true
} }
amountEditText.addTextChangedListener(this.listener) amountEditText.addTextChangedListener(this.listener)
}
}
private fun editTextSelected(editText: EditText, selected: Boolean, tag: Int) {
editText.setBackgroundColor(color(selected))
val row = dataSource.rowRepresentableForPosition(currentPosition)
?: throw PAIllegalStateException("Row Representable not found at index: $currentPosition")
val alreadySelected = dataSource.isSelected(currentPosition, row, tag)
if (!alreadySelected && selected) {
delegate?.onRowSelected(currentPosition, row, tag)
} }
} }
private fun editTextSelected(editText: EditText, hasFocus: Boolean, tag: Int) { private fun buttonEdited(button: Button, selected: Boolean, tag: Int) {
editText.setBackgroundColor(color(hasFocus))
if (hasFocus) { button.backgroundTintList = ColorStateList.valueOf(color(selected))
if (selected) {
val row = dataSource.rowRepresentableForPosition(currentPosition) val row = dataSource.rowRepresentableForPosition(currentPosition)
?: throw PAIllegalStateException("Row Representable not found at index: $currentPosition") ?: throw PAIllegalStateException("Row Representable not found at index: $currentPosition")
delegate?.onRowSelected(currentPosition, row, tag) delegate?.onRowSelected(currentPosition, row, tag)
@ -137,15 +155,19 @@ class HandHistoryAdapter(
} }
private fun color(isFocused: Boolean) : Int { private fun color(isFocused: Boolean) : Int {
val color = if (isFocused) R.color.green_light else R.color.kaki_medium val color = if (isFocused) R.color.kaki else R.color.kaki_medium
return itemView.context.getColor(color) return itemView.context.getColor(color)
} }
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) { override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
Timber.d("onbind @position = $position")
this.currentPosition = position this.currentPosition = position
val computedAction = row as ComputedAction val computedAction = row as ComputedAction
this.actionCanBeEdited = computedAction.actionTypeCanBeEdited
this.amountCanBeEdited = computedAction.amountCanBeEdited
// Position // Position
itemView.findViewById<Button>(R.id.positionButton)?.let { button -> itemView.findViewById<Button>(R.id.positionButton)?.let { button ->
@ -153,36 +175,43 @@ class HandHistoryAdapter(
} }
// Action // Action
itemView.findViewById<EditText>(R.id.actionEditText)?.let { actionEditText -> itemView.findViewById<Button>(R.id.actionButton)?.let { actionButton ->
val tag = HHKeyboard.ACTION.ordinal val tag = HHKeyboard.ACTION.ordinal
val selected = adapter.dataSource.isSelected(position, row, tag) val selected = adapter.dataSource.isSelected(position, row, tag)
// Timber.d("Action at $position is selected: $selected") // Timber.d("Action at $position is selected: $selected")
actionEditText.setBackgroundColor(color(selected)) actionButton.backgroundTintList = ColorStateList.valueOf(color(selected))
computedAction.action.type?.resId?.let { computedAction.action.type?.resId?.let {
actionEditText.setText(it) actionButton.setText(it)
} ?: run { } ?: run {
actionEditText.text = null actionButton.text = null
} }
if (selected) actionEditText.requestFocus()// else actionEditText.clearFocus()
} }
// Amount // Amount
itemView.findViewById<EditText>(R.id.amountEditText)?.let { amountEditText -> itemView.findViewById<EditText>(R.id.amountEditText)?.let { amountEditText ->
amountEditText.isFocusable = computedAction.amountCanBeEdited
val tag = HHKeyboard.AMOUNT.ordinal val tag = HHKeyboard.AMOUNT.ordinal
val selected = adapter.dataSource.isSelected(position, row, tag) val selected = adapter.dataSource.isSelected(position, row, tag)
// Timber.d("Amount at $position is selected: $selected")
// Both are required, otherwise requestFocus() fails
amountEditText.isFocusable = selected && computedAction.amountCanBeEdited
amountEditText.isFocusableInTouchMode = selected && computedAction.amountCanBeEdited
Timber.d("Amount at $position is selected: $selected, focusable = ${amountEditText.isFocusable}, isFocusableInTouchMode = ${amountEditText.isFocusableInTouchMode}, hasFocus = ${amountEditText.hasFocus()}, enabled = ${amountEditText.isEnabled}")
amountEditText.setBackgroundColor(color(selected)) amountEditText.setBackgroundColor(color(selected))
amountEditText.setText(computedAction.action.displayedFormattedAmount) amountEditText.setText(computedAction.action.displayedFormattedAmount)
if (selected && !amountEditText.hasFocus()) amountEditText.requestFocus()// else amountEditText.clearFocus() val tookFocus = if (selected) {
amountEditText.requestFocus()
} else {
amountEditText.clearFocus()
false
}
Timber.d("tookFocus: $tookFocus")
} }

@ -124,17 +124,6 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDataSource, RowRepr
} }
} }
private fun refreshCells(oldIndex: Int) {
this.handHistoryAdapter.notifyItemChanged(oldIndex)
this.model.currentSelection?.index?.let {
Timber.d("refreshes old = $oldIndex, new = $it")
this.handHistoryAdapter.notifyItemChanged(it)
}
// this.handHistoryAdapter.notifyDataSetChanged()
}
// RowRepresentableDataSource // RowRepresentableDataSource
override fun adapterRows(): List<RowRepresentable>? { override fun adapterRows(): List<RowRepresentable>? {
@ -160,8 +149,17 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDataSource, RowRepr
return return
} }
// if (tag == HHKeyboard.ACTION.ordinal) {
this.model.currentSelection?.index?.let { oldIndex ->
refreshCells(oldIndex)
}
// }
this.model.currentSelection = HHSelection(position, HHKeyboard.values()[tag]) this.model.currentSelection = HHSelection(position, HHKeyboard.values()[tag])
// scrolls to selected position
this.recyclerView.scrollToPosition(position)
val keyboard = when (row) { val keyboard = when (row) {
is ComputedAction -> { is ComputedAction -> {
when (tag) { when (tag) {
@ -228,4 +226,23 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDataSource, RowRepr
this.findNextActionToEdit() this.findNextActionToEdit()
} }
override fun clearAmount() {
this.model.clearAmount()
this.refreshCurrentRow()
}
// Table refresh
private fun refreshCells(oldIndex: Int) {
this.handHistoryAdapter.notifyItemChanged(oldIndex)
refreshCurrentRow()
}
private fun refreshCurrentRow() {
this.model.currentSelection?.index?.let {
Timber.d("refreshes row at index = $it")
this.handHistoryAdapter.notifyItemChanged(it)
}
}
} }

@ -14,6 +14,10 @@ class KeyboardAmountView(context: Context) : AbstractKeyboardView(context) {
this.nextButton.setOnClickListener { this.nextButton.setOnClickListener {
this.keyboardListener?.amountValidated() this.keyboardListener?.amountValidated()
} }
this.clearButton.setOnClickListener {
this.keyboardListener?.clearAmount()
}
} }
} }

@ -16,6 +16,7 @@ interface KeyboardListener {
fun cardValueSelected(value: Int) fun cardValueSelected(value: Int)
fun cardSuitSelected(suit: Card.Suit) fun cardSuitSelected(suit: Card.Suit)
fun amountValidated() fun amountValidated()
fun clearAmount()
} }
class KeyboardContainer(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) { class KeyboardContainer(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {

@ -61,6 +61,10 @@ class HandHistoryViewModel : ViewModel() {
} }
} }
fun clearAmount() {
builder.value?.clearAmount(this.actionIndexForSelection)
}
fun cardValueSelected(value: Int) { fun cardValueSelected(value: Int) {
this.currentSelection?.let { selection -> this.currentSelection?.let { selection ->

@ -2,9 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:descendantFocusability="beforeDescendants"
>
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/playerButton" android:id="@+id/playerButton"
@ -20,15 +18,22 @@
android:layout_height="44dp" android:layout_height="44dp"
android:layout_marginStart="8dp"/> android:layout_marginStart="8dp"/>
<androidx.appcompat.widget.AppCompatEditText <com.google.android.material.button.MaterialButton
android:id="@+id/actionEditText" android:id="@+id/actionButton"
style="@style/PokerAnalyticsTheme.EditText" style="@style/PokerAnalyticsTheme.HHButton"
android:layout_width="0dp" android:layout_width="64dp"
android:layout_weight="1" android:layout_height="44dp"
android:layout_height="wrap_content" android:layout_marginStart="8dp"/>
android:layout_marginStart="8dp"
android:gravity="center" <!-- <androidx.appcompat.widget.AppCompatEditText-->
android:maxLines="1" /> <!-- android:id="@+id/actionEditText"-->
<!-- style="@style/PokerAnalyticsTheme.EditText"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_weight="1"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginStart="8dp"-->
<!-- android:gravity="center"-->
<!-- android:maxLines="1" />-->
<androidx.appcompat.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/amountEditText" android:id="@+id/amountEditText"

Loading…
Cancel
Save