From 622e7a775a5da1b6f5a930d7f34ae90cd2758ce1 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 14 Mar 2019 16:19:18 -0300 Subject: [PATCH] [android] Soft keyboard fixes 1. Manually request focus for input fields and show keyboard This is needed when targetting API 28 which doesn't give focus anymore automatically like it used to be. Closes #1505 2. Remember keyboard states across screen rotations This also upgrades the emoji library and gets rid of the KeyboardAwareLinearLayout that is still a relict from the time when we were using Signal's emoji implementation. 3. Move soft keyboard showing/hiding into UiUtils --- briar-android/build.gradle | 2 +- briar-android/src/main/AndroidManifest.xml | 14 +- .../briar/android/activity/BaseActivity.java | 10 +- .../android/blog/RssFeedImportActivity.java | 6 + .../android/blog/WriteBlogPostActivity.java | 1 + .../conversation/AliasDialogFragment.java | 12 + .../conversation/ConversationActivity.java | 2 +- .../android/forum/CreateForumActivity.java | 2 +- .../android/login/ChangePasswordActivity.java | 4 + .../creation/CreateGroupFragment.java | 2 +- .../android/threaded/ThreadListActivity.java | 13 +- .../android/view/EmojiTextInputView.java | 54 ++++- .../view/KeyboardAwareLinearLayout.java | 225 ------------------ .../briar/android/view/TextInputView.java | 12 +- .../res/layout/activity_change_password.xml | 6 +- .../main/res/layout/activity_create_forum.xml | 2 +- .../main/res/layout/emoji_text_input_view.xml | 2 +- .../main/res/layout/fragment_create_group.xml | 2 +- .../src/main/res/layout/fragment_password.xml | 1 + briar-android/src/main/res/values/dimens.xml | 12 - briar-android/witness.gradle | 4 +- 21 files changed, 99 insertions(+), 289 deletions(-) delete mode 100644 briar-android/src/main/java/org/briarproject/briar/android/view/KeyboardAwareLinearLayout.java diff --git a/briar-android/build.gradle b/briar-android/build.gradle index 915248827..c9b7ed78f 100644 --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -117,7 +117,7 @@ dependencies { implementation 'de.hdodenhof:circleimageview:2.2.0' implementation 'com.google.zxing:core:3.3.3' implementation 'uk.co.samuelwall:material-tap-target-prompt:2.14.0' - implementation 'com.vanniktech:emoji-google:0.5.1' + implementation 'com.vanniktech:emoji-google:0.6.0' // later versions already use androidx implementation 'com.github.kobakei:MaterialFabSpeedDial:1.2.1' // later versions already use androidx def glideVersion = '4.9.0' implementation("com.github.bumptech.glide:glide:$glideVersion") { diff --git a/briar-android/src/main/AndroidManifest.xml b/briar-android/src/main/AndroidManifest.xml index 0afef62b0..7e5db298f 100644 --- a/briar-android/src/main/AndroidManifest.xml +++ b/briar-android/src/main/AndroidManifest.xml @@ -89,7 +89,7 @@ + android:windowSoftInputMode="stateVisible|adjustResize"> + android:windowSoftInputMode="stateUnchanged|adjustResize"> @@ -145,7 +145,7 @@ android:name="org.briarproject.briar.android.privategroup.creation.CreateGroupActivity" android:label="@string/groups_create_group_title" android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity" - android:windowSoftInputMode="adjustResize"> + android:windowSoftInputMode="stateVisible|adjustResize"> @@ -156,7 +156,7 @@ android:label="@string/app_name" android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity" android:theme="@style/BriarTheme.NoActionBar" - android:windowSoftInputMode="adjustResize|stateHidden"> + android:windowSoftInputMode="adjustResize|stateUnchanged"> @@ -223,7 +223,7 @@ android:name="org.briarproject.briar.android.forum.CreateForumActivity" android:label="@string/create_forum_title" android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity" - android:windowSoftInputMode="adjustResize"> + android:windowSoftInputMode="stateVisible|adjustResize"> @@ -234,7 +234,7 @@ android:label="@string/app_name" android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity" android:theme="@style/BriarTheme.NoActionBar" - android:windowSoftInputMode="adjustResize|stateHidden"> + android:windowSoftInputMode="adjustResize|stateUnchanged"> @@ -302,7 +302,7 @@ android:name="org.briarproject.briar.android.blog.ReblogActivity" android:label="@string/blogs_reblog_button" android:parentActivityName="org.briarproject.briar.android.blog.BlogActivity" - android:windowSoftInputMode="stateHidden"> + android:windowSoftInputMode="stateUnchanged"> diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java index 49e86c469..c7b5761f2 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java @@ -2,7 +2,6 @@ package org.briarproject.briar.android.activity; import android.content.Context; import android.os.Bundle; -import android.os.IBinder; import android.support.annotation.LayoutRes; import android.support.annotation.UiThread; import android.support.v4.app.Fragment; @@ -12,7 +11,6 @@ import android.support.v7.widget.Toolbar; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; -import android.view.inputmethod.InputMethodManager; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; @@ -44,7 +42,6 @@ import javax.inject.Inject; import static android.arch.lifecycle.Lifecycle.State.STARTED; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; -import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT; import static java.util.logging.Level.INFO; import static java.util.logging.Logger.getLogger; import static org.briarproject.briar.android.TestingConstants.PREVENT_SCREENSHOTS; @@ -218,14 +215,11 @@ public abstract class BaseActivity extends AppCompatActivity } public void showSoftKeyboard(View view) { - Object o = getSystemService(INPUT_METHOD_SERVICE); - ((InputMethodManager) o).showSoftInput(view, SHOW_IMPLICIT); + UiUtils.showSoftKeyboard(view); } public void hideSoftKeyboard(View view) { - IBinder token = view.getWindowToken(); - Object o = getSystemService(INPUT_METHOD_SERVICE); - ((InputMethodManager) o).hideSoftInputFromWindow(token, 0); + UiUtils.hideSoftKeyboard(view); } @UiThread diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java index 0a3ab6994..0a0558dfb 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java @@ -89,6 +89,12 @@ public class RssFeedImportActivity extends BriarActivity { progressBar = findViewById(R.id.progressBar); } + @Override + public void onStart() { + super.onStart(); + if (urlInput.requestFocus()) showSoftKeyboard(urlInput); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { return super.onCreateOptionsMenu(menu); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/WriteBlogPostActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/WriteBlogPostActivity.java index 1ea824b79..5032e1241 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/blog/WriteBlogPostActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/WriteBlogPostActivity.java @@ -89,6 +89,7 @@ public class WriteBlogPostActivity extends BriarActivity public void onStart() { super.onStart(); notificationManager.blockNotification(groupId); + if (input.requestFocus()) showSoftKeyboard(input); } @Override diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/AliasDialogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/AliasDialogFragment.java index b91256bef..03ed92b7f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/AliasDialogFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/AliasDialogFragment.java @@ -21,9 +21,11 @@ import org.briarproject.briar.android.activity.BaseActivity; import javax.inject.Inject; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE; import static java.util.Objects.requireNonNull; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.util.StringUtils.toUtf8; +import static org.briarproject.briar.android.util.UiUtils.showSoftKeyboard; @MethodsNotNullByDefault @ParametersNotNullByDefault @@ -91,4 +93,14 @@ public class AliasDialogFragment extends AppCompatDialogFragment { } } + @Override + public void onStart() { + super.onStart(); + if (aliasEditText.requestFocus()) { + requireNonNull(getDialog().getWindow()) + .setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE); + showSoftKeyboard(aliasEditText); + } + } + } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java index 01bc51c3e..9b89740e3 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java @@ -276,7 +276,7 @@ public class ConversationActivity extends BriarActivity textInputView.setSendController(sendController); textInputView.setMaxTextLength(MAX_PRIVATE_MESSAGE_TEXT_LENGTH); textInputView.setReady(false); - textInputView.addOnKeyboardShownListener(this::scrollToBottom); + textInputView.setOnKeyboardShownListener(this::scrollToBottom); } private void scrollToBottom() { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/CreateForumActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/CreateForumActivity.java index 96574abbe..5279b6449 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/forum/CreateForumActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/CreateForumActivity.java @@ -94,7 +94,7 @@ public class CreateForumActivity extends BriarActivity { @Override public void onStart() { super.onStart(); - showSoftKeyboard(nameEntry); + if (nameEntry.requestFocus()) showSoftKeyboard(nameEntry); } @Override diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/ChangePasswordActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/login/ChangePasswordActivity.java index 136e9e19d..af53df32b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/login/ChangePasswordActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/login/ChangePasswordActivity.java @@ -83,6 +83,10 @@ public class ChangePasswordActivity extends BriarActivity newPasswordConfirmation.addTextChangedListener(tw); newPasswordConfirmation.setOnEditorActionListener(this); changePasswordButton.setOnClickListener(this); + + if (state == null && currentPassword.requestFocus()) { + showSoftKeyboard(currentPassword); + } } @Override diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupFragment.java index f36c749ef..24caee716 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupFragment.java @@ -94,7 +94,7 @@ public class CreateGroupFragment extends BaseFragment { @Override public void onStart() { super.onStart(); - listener.showSoftKeyboard(nameEntry); + if (nameEntry.requestFocus()) listener.showSoftKeyboard(nameEntry); } @Override diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java index 80456c453..88c8edda8 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java @@ -27,7 +27,6 @@ import org.briarproject.briar.android.threaded.ThreadListController.ThreadListDa import org.briarproject.briar.android.threaded.ThreadListController.ThreadListListener; import org.briarproject.briar.android.util.BriarSnackbarBuilder; import org.briarproject.briar.android.view.BriarRecyclerView; -import org.briarproject.briar.android.view.KeyboardAwareLinearLayout; import org.briarproject.briar.android.view.TextInputView; import org.briarproject.briar.android.view.TextSendController; import org.briarproject.briar.android.view.TextSendController.SendListener; @@ -284,14 +283,10 @@ public abstract class ThreadListActivity { + scrollToItemAtTop(item); + textInput.setOnKeyboardShownListener(null); + }); } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/EmojiTextInputView.java b/briar-android/src/main/java/org/briarproject/briar/android/view/EmojiTextInputView.java index b9036b6df..3127d287f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/view/EmojiTextInputView.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/view/EmojiTextInputView.java @@ -13,8 +13,8 @@ import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; +import android.widget.LinearLayout; -import com.vanniktech.emoji.EmojiEditText; import com.vanniktech.emoji.EmojiPopup; import com.vanniktech.emoji.RecentEmoji; @@ -31,8 +31,9 @@ import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT; import static java.lang.Character.isWhitespace; import static java.util.Objects.requireNonNull; import static org.briarproject.bramble.util.StringUtils.utf8IsTooLong; +import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute; -public class EmojiTextInputView extends KeyboardAwareLinearLayout implements +public class EmojiTextInputView extends LinearLayout implements TextWatcher { @Inject @@ -41,12 +42,16 @@ public class EmojiTextInputView extends KeyboardAwareLinearLayout implements private final AppCompatImageButton emojiToggle; private final EmojiPopup emojiPopup; private final EditText editText; + private final InputMethodManager imm; @Nullable private TextInputListener listener; + @Nullable + private OnKeyboardShownListener keyboardShownListener; private int maxLength = Integer.MAX_VALUE; private boolean emptyTextAllowed = false; private boolean isEmpty = true; + private boolean keyboardOpen = false; public EmojiTextInputView(Context context) { this(context, null); @@ -104,17 +109,26 @@ public class EmojiTextInputView extends KeyboardAwareLinearLayout implements // stuff we can't do in edit mode goes below if (isInEditMode()) { emojiPopup = null; + imm = null; return; } + Object o = getContext().getSystemService(INPUT_METHOD_SERVICE); + imm = (InputMethodManager) requireNonNull(o); + BriarApplication app = (BriarApplication) context.getApplicationContext(); app.getApplicationComponent().inject(this); emojiPopup = EmojiPopup.Builder - .fromRootView(this) + .fromRootView(getRootView()) .setRecentEmoji(recentEmoji) .setOnEmojiPopupShownListener(this::showKeyboardIcon) .setOnEmojiPopupDismissListener(this::showEmojiIcon) - .build((EmojiEditText) editText); + .setKeyboardAnimationStyle(R.style.emoji_fade_animation_style) + .setOnSoftKeyboardOpenListener(this::onKeyboardOpened) + .setOnSoftKeyboardCloseListener(this::onKeyboardClosed) + .setIconColor(resolveColorAttribute(getContext(), + R.attr.colorControlNormal)) + .build(editText); emojiToggle.setOnClickListener(v -> emojiPopup.toggle()); } @@ -231,6 +245,10 @@ public class EmojiTextInputView extends KeyboardAwareLinearLayout implements editText.setHint(hint); } + boolean isKeyboardOpen() { + return keyboardOpen || imm.isFullscreenMode(); + } + private void showEmojiIcon() { emojiToggle.setImageResource(R.drawable.ic_emoji_toggle); } @@ -240,23 +258,43 @@ public class EmojiTextInputView extends KeyboardAwareLinearLayout implements } void showSoftKeyboard() { - Object o = getContext().getSystemService(INPUT_METHOD_SERVICE); - InputMethodManager imm = (InputMethodManager) requireNonNull(o); imm.showSoftInput(editText, SHOW_IMPLICIT); } void hideSoftKeyboard() { if (emojiPopup.isShowing()) emojiPopup.dismiss(); IBinder token = editText.getWindowToken(); - Object o = getContext().getSystemService(INPUT_METHOD_SERVICE); - InputMethodManager imm = (InputMethodManager) requireNonNull(o); imm.hideSoftInputFromWindow(token, 0); } + private void onKeyboardOpened( + @SuppressWarnings("unused") int keyboardHeight) { + keyboardOpen = true; + if (keyboardShownListener != null) + keyboardShownListener.onKeyboardShown(); + } + + private void onKeyboardClosed() { + if (imm.isFullscreenMode()) { + onKeyboardOpened(0); + return; + } + keyboardOpen = false; + } + + void setOnKeyboardShownListener( + @Nullable OnKeyboardShownListener listener) { + keyboardShownListener = listener; + } + interface TextInputListener { void onTextIsEmptyChanged(boolean isEmpty); void onSendEvent(); } + public interface OnKeyboardShownListener { + void onKeyboardShown(); + } + } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/KeyboardAwareLinearLayout.java b/briar-android/src/main/java/org/briarproject/briar/android/view/KeyboardAwareLinearLayout.java deleted file mode 100644 index fa4028aeb..000000000 --- a/briar-android/src/main/java/org/briarproject/briar/android/view/KeyboardAwareLinearLayout.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - Taken from Signal, licences under GPLv3 - */ - -package org.briarproject.briar.android.view; - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.SharedPreferences; -import android.graphics.Rect; -import android.os.Build; -import android.preference.PreferenceManager; -import android.support.annotation.UiThread; -import android.util.AttributeSet; -import android.view.View; -import android.view.WindowManager; -import android.widget.LinearLayout; - -import org.briarproject.briar.R; - -import java.lang.reflect.Field; -import java.util.HashSet; -import java.util.Set; -import java.util.logging.Logger; - -import javax.annotation.Nullable; - -import static android.content.Context.WINDOW_SERVICE; -import static android.view.Surface.ROTATION_270; -import static android.view.Surface.ROTATION_90; -import static java.util.Objects.requireNonNull; -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; - -/** - * RelativeLayout that, when a view container, will report back when it thinks - * a soft keyboard has been opened and what its height would be. - */ -@UiThread -public class KeyboardAwareLinearLayout extends LinearLayout { - - private static final Logger LOG = - Logger.getLogger(KeyboardAwareLinearLayout.class.getName()); - - private final Rect rect = new Rect(); - private final Set shownListeners = new HashSet<>(); - private final int minKeyboardSize; - private final int minCustomKeyboardSize; - private final int defaultCustomKeyboardSize; - private final int minCustomKeyboardTopMargin; - private final int statusBarHeight; - - private int viewInset; - - private boolean keyboardOpen = false; - private int rotation = -1; - - public KeyboardAwareLinearLayout(Context context) { - this(context, null); - } - - public KeyboardAwareLinearLayout(Context context, - @Nullable AttributeSet attrs) { - this(context, attrs, 0); - } - - public KeyboardAwareLinearLayout(Context context, - @Nullable AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - rotation = getDeviceRotation(); - int statusBarRes = getResources() - .getIdentifier("status_bar_height", "dimen", "android"); - minKeyboardSize = - getResources().getDimensionPixelSize(R.dimen.min_keyboard_size); - minCustomKeyboardSize = getResources() - .getDimensionPixelSize(R.dimen.min_custom_keyboard_size); - defaultCustomKeyboardSize = getResources() - .getDimensionPixelSize(R.dimen.default_custom_keyboard_size); - minCustomKeyboardTopMargin = getResources() - .getDimensionPixelSize(R.dimen.min_custom_keyboard_top_margin); - statusBarHeight = statusBarRes > 0 ? - getResources().getDimensionPixelSize(statusBarRes) : 0; - viewInset = getViewInset(); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - updateRotation(); - updateKeyboardState(); - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - - private void updateRotation() { - int oldRotation = rotation; - rotation = getDeviceRotation(); - if (oldRotation != rotation) { - LOG.info("Rotation changed"); - onKeyboardClose(); - } - } - - private void updateKeyboardState() { - if (isLandscape()) { - if (keyboardOpen) onKeyboardClose(); - return; - } - - if (viewInset == 0 && Build.VERSION.SDK_INT >= 21) - viewInset = getViewInset(); - int availableHeight = - getRootView().getHeight() - statusBarHeight - viewInset; - getWindowVisibleDisplayFrame(rect); - - int keyboardHeight = availableHeight - (rect.bottom - rect.top); - - if (keyboardHeight > minKeyboardSize) { - if (getKeyboardHeight() != keyboardHeight) - setKeyboardPortraitHeight(keyboardHeight); - if (!keyboardOpen) onKeyboardOpen(keyboardHeight); - } else if (keyboardOpen) { - onKeyboardClose(); - } - } - - @TargetApi(21) - private int getViewInset() { - try { - Field attachInfoField = View.class.getDeclaredField("mAttachInfo"); - attachInfoField.setAccessible(true); - Object attachInfo = attachInfoField.get(this); - if (attachInfo != null) { - Field stableInsetsField = - attachInfo.getClass().getDeclaredField("mStableInsets"); - stableInsetsField.setAccessible(true); - Rect insets = (Rect) stableInsetsField.get(attachInfo); - return insets.bottom; - } - } catch (NoSuchFieldException e) { - LOG.log(WARNING, - "field reflection error when measuring view inset", e); - } catch (IllegalAccessException e) { - LOG.log(WARNING, - "access reflection error when measuring view inset", e); - } - return 0; - } - - protected void onKeyboardOpen(int keyboardHeight) { - if (LOG.isLoggable(INFO)) - LOG.info("onKeyboardOpen(" + keyboardHeight + ")"); - keyboardOpen = true; - - notifyShownListeners(); - } - - protected void onKeyboardClose() { - LOG.info("onKeyboardClose()"); - keyboardOpen = false; - } - - public boolean isKeyboardOpen() { - return keyboardOpen; - } - - public int getKeyboardHeight() { - return isLandscape() ? getKeyboardLandscapeHeight() : - getKeyboardPortraitHeight(); - } - - public boolean isLandscape() { - int rotation = getDeviceRotation(); - return rotation == ROTATION_90 || rotation == ROTATION_270; - } - - private int getDeviceRotation() { - WindowManager windowManager = - (WindowManager) getContext().getSystemService(WINDOW_SERVICE); - return requireNonNull(windowManager).getDefaultDisplay().getRotation(); - } - - private int getKeyboardLandscapeHeight() { - return Math.max(getHeight(), getRootView().getHeight()) / 2; - } - - private int getKeyboardPortraitHeight() { - SharedPreferences prefs = - PreferenceManager.getDefaultSharedPreferences(getContext()); - int keyboardHeight = prefs.getInt("keyboard_height_portrait", - defaultCustomKeyboardSize); - return clamp(keyboardHeight, minCustomKeyboardSize, - getRootView().getHeight() - minCustomKeyboardTopMargin); - } - - private int clamp(int value, int min, int max) { - return Math.min(Math.max(value, min), max); - } - - private void setKeyboardPortraitHeight(int height) { - SharedPreferences prefs = - PreferenceManager.getDefaultSharedPreferences(getContext()); - prefs.edit().putInt("keyboard_height_portrait", height).apply(); - } - - public void addOnKeyboardShownListener(OnKeyboardShownListener listener) { - shownListeners.add(listener); - } - - public void removeOnKeyboardShownListener( - OnKeyboardShownListener listener) { - shownListeners.remove(listener); - } - - private void notifyShownListeners() { - // Make a copy as listeners may remove themselves when called - Set listeners = new HashSet<>(shownListeners); - for (OnKeyboardShownListener listener : listeners) { - listener.onKeyboardShown(); - } - } - - public interface OnKeyboardShownListener { - void onKeyboardShown(); - } - -} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/TextInputView.java b/briar-android/src/main/java/org/briarproject/briar/android/view/TextInputView.java index 89a32c1e4..1fbb4301d 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/view/TextInputView.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/view/TextInputView.java @@ -16,7 +16,7 @@ import android.widget.LinearLayout; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.briar.R; -import org.briarproject.briar.android.view.KeyboardAwareLinearLayout.OnKeyboardShownListener; +import org.briarproject.briar.android.view.EmojiTextInputView.OnKeyboardShownListener; import static android.content.Context.LAYOUT_INFLATER_SERVICE; import static java.util.Objects.requireNonNull; @@ -139,13 +139,9 @@ public class TextInputView extends LinearLayout { textInput.hideSoftKeyboard(); } - public void addOnKeyboardShownListener(OnKeyboardShownListener listener) { - textInput.addOnKeyboardShownListener(listener); - } - - public void removeOnKeyboardShownListener( - OnKeyboardShownListener listener) { - textInput.removeOnKeyboardShownListener(listener); + public void setOnKeyboardShownListener( + @Nullable OnKeyboardShownListener listener) { + textInput.setOnKeyboardShownListener(listener); } } diff --git a/briar-android/src/main/res/layout/activity_change_password.xml b/briar-android/src/main/res/layout/activity_change_password.xml index fad60ccbc..a67060cfd 100644 --- a/briar-android/src/main/res/layout/activity_change_password.xml +++ b/briar-android/src/main/res/layout/activity_change_password.xml @@ -29,7 +29,7 @@ app:layout_constraintTop_toTopOf="parent" app:passwordToggleEnabled="true"> - - - - - +