From cf1aaa3fbbd97a1ccbc78c4d45feaa92e77b2a9a Mon Sep 17 00:00:00 2001 From: nikita-kladov Date: Thu, 14 Nov 2024 17:06:06 +0300 Subject: [PATCH] Add enter key type and actions commit_hash:276a7f182ddbb9475a44970d8c021df99ced8d65 --- .../java/com/yandex/div/core/Div2Logger.java | 13 +++++++ .../com/yandex/div/core/DivActionHandler.java | 1 + .../div/core/view2/divs/DivActionBinder.kt | 6 ++- .../div/core/view2/divs/DivInputBinder.kt | 39 +++++++++++++++++++ schema/div-input.json | 6 ++- 5 files changed, 62 insertions(+), 3 deletions(-) diff --git a/client/android/div/src/main/java/com/yandex/div/core/Div2Logger.java b/client/android/div/src/main/java/com/yandex/div/core/Div2Logger.java index 29dc679a1..da5ace2a9 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/Div2Logger.java +++ b/client/android/div/src/main/java/com/yandex/div/core/Div2Logger.java @@ -135,6 +135,19 @@ public interface Div2Logger { // do nothing } + /** + * Is called when IME enter action called. + * @noinspection unused + */ + default void logImeEnter( + @NonNull Div2View divView, + @NonNull ExpressionResolver resolver, + @NonNull View inputView, + @NonNull DivAction action + ) { + // do nothing + } + /** * Is called when title bar in tabs div is scrolled. */ diff --git a/client/android/div/src/main/java/com/yandex/div/core/DivActionHandler.java b/client/android/div/src/main/java/com/yandex/div/core/DivActionHandler.java index 85e2de9ea..b6310f7f8 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/DivActionHandler.java +++ b/client/android/div/src/main/java/com/yandex/div/core/DivActionHandler.java @@ -48,6 +48,7 @@ public class DivActionHandler { public static final String VIDEO = "video"; public static final String ANIMATION_END = "animation_end"; public static final String ANIMATION_CANCEL = "animation_cancel"; + public static final String ENTER = "enter"; } private static final String SCHEME_DIV_ACTION = "div-action"; diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivActionBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivActionBinder.kt index 016cbd85c..89b12e91a 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivActionBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivActionBinder.kt @@ -27,6 +27,7 @@ import com.yandex.div.core.view2.DivGestureListener import com.yandex.div.core.view2.divs.DivActionBinder.LogType.Companion.LOG_BLUR import com.yandex.div.core.view2.divs.DivActionBinder.LogType.Companion.LOG_CLICK import com.yandex.div.core.view2.divs.DivActionBinder.LogType.Companion.LOG_DOUBLE_CLICK +import com.yandex.div.core.view2.divs.DivActionBinder.LogType.Companion.LOG_ENTER import com.yandex.div.core.view2.divs.DivActionBinder.LogType.Companion.LOG_FOCUS import com.yandex.div.core.view2.divs.DivActionBinder.LogType.Companion.LOG_LONG_CLICK import com.yandex.div.internal.Assert @@ -323,6 +324,7 @@ internal class DivActionBinder @Inject constructor( LOG_DOUBLE_CLICK -> logger.logDoubleClick(divView, resolver, target, action, uuid) LOG_FOCUS -> logger.logFocusChanged(divView, resolver, target, action, true) LOG_BLUR -> logger.logFocusChanged(divView, resolver, target, action, false) + LOG_ENTER -> logger.logImeEnter(divView, resolver, target, action) else -> Assert.fail("Please, add new logType") } divActionBeaconSender.sendTapActionBeacon(action, resolver) @@ -337,6 +339,7 @@ internal class DivActionBinder @Inject constructor( LOG_DOUBLE_CLICK -> DivActionReason.DOUBLE_CLICK LOG_FOCUS -> DivActionReason.FOCUS LOG_BLUR -> DivActionReason.BLUR + LOG_ENTER -> DivActionReason.ENTER else -> DivActionReason.EXTERNAL } @@ -471,7 +474,7 @@ internal class DivActionBinder @Inject constructor( @Retention(AnnotationRetention.SOURCE) - @StringDef(LOG_CLICK, LOG_LONG_CLICK, LOG_DOUBLE_CLICK, LOG_FOCUS, LOG_BLUR) + @StringDef(LOG_CLICK, LOG_LONG_CLICK, LOG_DOUBLE_CLICK, LOG_FOCUS, LOG_BLUR, LOG_ENTER) internal annotation class LogType { companion object { const val LOG_CLICK = "click" @@ -479,6 +482,7 @@ internal class DivActionBinder @Inject constructor( const val LOG_DOUBLE_CLICK = "double_click" const val LOG_FOCUS = "focus" const val LOG_BLUR = "blur" + const val LOG_ENTER = "enter" } } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivInputBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivInputBinder.kt index 849830659..804cdbe2c 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivInputBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivInputBinder.kt @@ -5,6 +5,7 @@ import android.text.InputFilter import android.text.InputType import android.text.method.DigitsKeyListener import android.view.View +import android.view.inputmethod.EditorInfo import android.widget.TextView import androidx.core.view.doOnLayout import androidx.core.widget.doAfterTextChanged @@ -29,6 +30,7 @@ import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivTypefaceResolver import com.yandex.div.core.view2.DivViewBinder +import com.yandex.div.core.view2.divs.DivActionBinder.LogType.Companion.LOG_ENTER import com.yandex.div.core.view2.divs.widgets.DivInputView import com.yandex.div.core.view2.errors.ErrorCollector import com.yandex.div.core.view2.errors.ErrorCollectors @@ -54,6 +56,7 @@ internal class DivInputBinder @Inject constructor( private val baseBinder: DivBaseBinder, private val typefaceResolver: DivTypefaceResolver, private val variableBinder: TwoWayStringVariableBinder, + private val actionBinder: DivActionBinder, private val accessibilityStateProvider: AccessibilityStateProvider, private val errorCollectors: ErrorCollectors ) : DivViewBinder { @@ -87,6 +90,7 @@ internal class DivInputBinder @Inject constructor( observeHighlightColor(div, expressionResolver) observeKeyboardTypeAndCapitalization(div, expressionResolver) + observeEnterTypeAndActions(div, context, expressionResolver) observeSelectAllOnFocus(div, expressionResolver) observeIsEnabled(div, expressionResolver) @@ -273,6 +277,41 @@ internal class DivInputBinder @Inject constructor( } } + private fun DivInputView.observeEnterTypeAndActions( + div: DivInput, + bindingContext: BindingContext, + resolver: ExpressionResolver + ) { + val callback = { _: Any -> + val enterKeyType = div.enterKeyType.evaluate(resolver) + this.imeOptions = getImeAction(enterKeyType) + + val actions = div.enterKeyActions + if (!actions.isNullOrEmpty()) { + this.setOnEditorActionListener { _, actionId, _ -> + if ((actionId and EditorInfo.IME_MASK_ACTION) != 0) { + actionBinder.handleBulkActions(bindingContext, this, actions, LOG_ENTER) + } + + false + } + } else { + this.setOnEditorActionListener(null) + } + } + addSubscription(div.enterKeyType.observeAndGet(resolver, callback)) + } + + private fun getImeAction(type: DivInput.EnterKeyType): Int { + return when (type) { + DivInput.EnterKeyType.DEFAULT -> EditorInfo.IME_NULL + DivInput.EnterKeyType.SEND -> EditorInfo.IME_ACTION_SEND + DivInput.EnterKeyType.DONE -> EditorInfo.IME_ACTION_DONE + DivInput.EnterKeyType.SEARCH -> EditorInfo.IME_ACTION_SEARCH + DivInput.EnterKeyType.GO -> EditorInfo.IME_ACTION_GO + } + } + private fun DivInputView.observeSelectAllOnFocus(div: DivInput, resolver: ExpressionResolver) { val callback = { _: Any -> setSelectAllOnFocus(div.selectAllOnFocus.evaluate(resolver)) } addSubscription(div.selectAllOnFocus.observeAndGet(resolver, callback)) diff --git a/schema/div-input.json b/schema/div-input.json index 38197d220..3e112cce8 100644 --- a/schema/div-input.json +++ b/schema/div-input.json @@ -160,7 +160,8 @@ }, "$description": "translations.json#/div_input_enter_key_actions", "platforms": [ - "ios" + "ios", + "android" ] }, "enter_key_type": { @@ -175,7 +176,8 @@ "default_value": "default", "$description": "translations.json#/div_input_enter_key_type", "platforms": [ - "ios" + "ios", + "android" ] }, "keyboard_type": {