mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
[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
This commit is contained in:
@@ -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") {
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.account.SetupActivity"
|
||||
android:label="@string/setup_title"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
android:windowSoftInputMode="stateVisible|adjustResize">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -126,7 +126,7 @@
|
||||
android:label="@string/app_name"
|
||||
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity"
|
||||
android:theme="@style/BriarTheme.NoActionBar"
|
||||
android:windowSoftInputMode="stateHidden|adjustResize">
|
||||
android:windowSoftInputMode="stateUnchanged|adjustResize">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
@@ -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">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
@@ -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">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
@@ -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">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
@@ -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">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
@@ -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">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.blog.BlogActivity"/>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -89,6 +89,7 @@ public class WriteBlogPostActivity extends BriarActivity
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
notificationManager.blockNotification(groupId);
|
||||
if (input.requestFocus()) showSoftKeyboard(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -94,7 +94,7 @@ public class CreateForumActivity extends BriarActivity {
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
showSoftKeyboard(nameEntry);
|
||||
if (nameEntry.requestFocus()) showSoftKeyboard(nameEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<G extends NamedGroup, I extends ThreadI
|
||||
scrollToItemAtTop(item);
|
||||
} else {
|
||||
// wait with scrolling until keyboard opened
|
||||
textInput.addOnKeyboardShownListener(
|
||||
new KeyboardAwareLinearLayout.OnKeyboardShownListener() {
|
||||
@Override
|
||||
public void onKeyboardShown() {
|
||||
scrollToItemAtTop(item);
|
||||
textInput.removeOnKeyboardShownListener(this);
|
||||
}
|
||||
});
|
||||
textInput.setOnKeyboardShownListener(() -> {
|
||||
scrollToItemAtTop(item);
|
||||
textInput.setOnKeyboardShownListener(null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<OnKeyboardShownListener> 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<OnKeyboardShownListener> listeners = new HashSet<>(shownListeners);
|
||||
for (OnKeyboardShownListener listener : listeners) {
|
||||
listener.onKeyboardShown();
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnKeyboardShownListener {
|
||||
void onKeyboardShown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:passwordToggleEnabled="true">
|
||||
|
||||
<EditText
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/current_password_entry"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -49,7 +49,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/current_password_entry_wrapper"
|
||||
app:passwordToggleEnabled="true">
|
||||
|
||||
<EditText
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/new_password_entry"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -69,7 +69,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/new_password_entry_wrapper"
|
||||
app:passwordToggleEnabled="true">
|
||||
|
||||
<EditText
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/new_password_confirm"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
app:errorEnabled="true"
|
||||
app:hintEnabled="false">
|
||||
|
||||
<EditText
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/createForumNameEntry"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
tools:parentTag="org.briarproject.briar.android.view.KeyboardAwareLinearLayout"
|
||||
tools:parentTag="android.widget.LinearLayout"
|
||||
tools:showIn="@layout/fragment_reblog">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageButton
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
app:errorEnabled="true"
|
||||
app:hintEnabled="false">
|
||||
|
||||
<EditText
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textPassword"
|
||||
android:maxLines="1"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<Button
|
||||
|
||||
@@ -68,18 +68,6 @@
|
||||
<dimen name="blogs_avatar_icon_size">15dp</dimen>
|
||||
<dimen name="blogs_avatar_comment_size">20dp</dimen>
|
||||
|
||||
<!-- Emoji -->
|
||||
<dimen name="text_input_height">42dp</dimen>
|
||||
<dimen name="conversation_item_body_text_size">16sp</dimen>
|
||||
<dimen name="emoji_drawer_size">32sp</dimen>
|
||||
<dimen name="emoji_drawer_indicator_height">2dp</dimen>
|
||||
<dimen name="emoji_drawer_item_padding">5dp</dimen>
|
||||
<dimen name="emoji_drawer_left_right_padding">2dp</dimen>
|
||||
|
||||
<!-- Keyboard Sizes -->
|
||||
<dimen name="min_keyboard_size">50dp</dimen>
|
||||
<dimen name="default_custom_keyboard_size">220dp</dimen>
|
||||
<dimen name="min_custom_keyboard_size">110dp</dimen>
|
||||
<dimen name="min_custom_keyboard_top_margin">170dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -118,8 +118,8 @@ dependencyVerification {
|
||||
'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce',
|
||||
'com.sun.istack:istack-commons-runtime:2.21:istack-commons-runtime-2.21.jar:c33e67a0807095f02a0e2da139412dd7c4f9cc1a4c054b3e434f96831ba950f4',
|
||||
'com.sun.xml.fastinfoset:FastInfoset:1.2.13:FastInfoset-1.2.13.jar:27a77db909f3c2833c0b1a37c55af1db06045118ad2eed96ce567b6632bce038',
|
||||
'com.vanniktech:emoji-google:0.5.1:emoji-google-0.5.1.aar:5f4a88e1a3bb5f694ddccf2e49dc9ccc44431f1d4f980bc453c178f57869dea0',
|
||||
'com.vanniktech:emoji:0.5.1:emoji-0.5.1.aar:d55f44e04e31895647d62c33c34a8d501995e9e1b5c5f5cee6cbb8630eeb37f7',
|
||||
'com.vanniktech:emoji-google:0.6.0:emoji-google-0.6.0.aar:029d6a954cebfe3f0a5bac0c9539a054fa7db2e1272d006a8f0e850f3794d44b',
|
||||
'com.vanniktech:emoji:0.6.0:emoji-0.6.0.aar:a5fcde58902305c004f03c6dc2241e718400ac4162226079791d87fac83ef639',
|
||||
'commons-codec:commons-codec:1.10:commons-codec-1.10.jar:4241dfa94e711d435f29a4604a3e2de5c4aa3c165e23bd066be6fc1fc4309569',
|
||||
'commons-logging:commons-logging:1.2:commons-logging-1.2.jar:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636',
|
||||
'de.hdodenhof:circleimageview:2.2.0:circleimageview-2.2.0.aar:bc34761dcd5036229ac1ffed6b5b1bef722ad5b097a2c8bba1c5ed2cd4b5c82b',
|
||||
|
||||
Reference in New Issue
Block a user