stop using PopupWindow for emoji. too many android bugs.
Closes #3655 // FREEBIE
This commit is contained in:
parent
c7599094f5
commit
b519fd2533
7 changed files with 85 additions and 114 deletions
|
@ -1,20 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/layout_container"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/quick_attachment_drawer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black">
|
||||
|
||||
<org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout
|
||||
android:id="@+id/layout_container"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
|
@ -159,6 +159,11 @@
|
|||
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
</org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer>
|
||||
|
||||
<ViewStub android:id="@+id/emoji_drawer_stub"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inflatedId="@+id/emoji_drawer"
|
||||
android:layout="@layout/emoji_drawer_stub" />
|
||||
</org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout>
|
||||
</org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer>
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/container"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout android:background="?emoji_tab_strip_background"
|
||||
android:orientation="horizontal"
|
||||
|
@ -47,4 +43,4 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="?emoji_background" />
|
||||
|
||||
</LinearLayout>
|
||||
</merge>
|
|
@ -49,6 +49,7 @@ import android.view.View;
|
|||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnFocusChangeListener;
|
||||
import android.view.View.OnKeyListener;
|
||||
import android.view.ViewStub;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
|
@ -68,13 +69,12 @@ import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
|
|||
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout.OnKeyboardShownListener;
|
||||
import org.thoughtcrime.securesms.components.SendButton;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer.EmojiEventListener;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiPopup;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiToggle;
|
||||
import org.thoughtcrime.securesms.contacts.ContactAccessor;
|
||||
import org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData;
|
||||
import org.thoughtcrime.securesms.components.camera.HidingImageButton;
|
||||
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer.AttachmentDrawerListener;
|
||||
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer.DrawerState;
|
||||
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer;
|
||||
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
|
@ -178,7 +178,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
private AttachmentManager attachmentManager;
|
||||
private BroadcastReceiver securityUpdateReceiver;
|
||||
private BroadcastReceiver groupUpdateReceiver;
|
||||
private Optional<EmojiPopup> emojiPopup = Optional.absent();
|
||||
private Optional<EmojiDrawer> emojiDrawer = Optional.absent();
|
||||
private EmojiToggle emojiToggle;
|
||||
protected HidingImageButton quickAttachmentToggle;
|
||||
private QuickAttachmentDrawer quickAttachmentDrawer;
|
||||
|
@ -267,7 +267,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
@Override public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
quickAttachmentDrawer.onConfigurationChanged();
|
||||
hideEmojiPopup(false);
|
||||
hideEmojiDrawer(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -276,7 +276,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
if (recipients != null) recipients.removeListener(this);
|
||||
if (securityUpdateReceiver != null) unregisterReceiver(securityUpdateReceiver);
|
||||
if (groupUpdateReceiver != null) unregisterReceiver(groupUpdateReceiver);
|
||||
if (isEmojiDrawerOpen()) hideEmojiPopup(false);
|
||||
if (isEmojiDrawerOpen()) hideEmojiDrawer(false);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
@ -384,8 +384,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
Log.w(TAG, "onBackPressed()");
|
||||
if (isEmojiDrawerOpen()) {
|
||||
hideEmojiPopup(false);
|
||||
Log.w(TAG, "hiding emoji popup");
|
||||
hideEmojiDrawer(false);
|
||||
} else if (quickAttachmentDrawer.isOpen()) {
|
||||
quickAttachmentDrawer.close();
|
||||
} else {
|
||||
|
@ -395,7 +397,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
|
||||
@Override
|
||||
public void onKeyboardShown() {
|
||||
hideEmojiPopup(true);
|
||||
hideEmojiDrawer(true);
|
||||
}
|
||||
|
||||
//////// Event Handlers
|
||||
|
@ -866,10 +868,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
||||
}
|
||||
|
||||
private EmojiPopup getEmojiPopup() {
|
||||
if (!emojiPopup.isPresent()) {
|
||||
EmojiPopup emojiPopup = new EmojiPopup(container);
|
||||
emojiPopup.setEmojiEventListener(new EmojiEventListener() {
|
||||
private EmojiDrawer getEmojiDrawer() {
|
||||
if (!emojiDrawer.isPresent()) {
|
||||
EmojiDrawer emojiDrawer = (EmojiDrawer)((ViewStub)findViewById(R.id.emoji_drawer_stub)).inflate();
|
||||
emojiDrawer.setEmojiEventListener(new EmojiEventListener() {
|
||||
@Override public void onKeyEvent(KeyEvent keyEvent) {
|
||||
composeText.dispatchKeyEvent(keyEvent);
|
||||
}
|
||||
|
@ -879,28 +881,33 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
composeText.insertEmoji(emoji);
|
||||
}
|
||||
});
|
||||
this.emojiPopup = Optional.of(emojiPopup);
|
||||
this.emojiDrawer = Optional.of(emojiDrawer);
|
||||
}
|
||||
return emojiPopup.get();
|
||||
return emojiDrawer.get();
|
||||
}
|
||||
|
||||
private void showEmojiPopup() {
|
||||
getEmojiPopup().show();
|
||||
private void showEmojiDrawer() {
|
||||
getEmojiDrawer().show(container);
|
||||
emojiToggle.setToIme();
|
||||
}
|
||||
|
||||
protected void hideEmojiPopup(boolean expectingKeyboard) {
|
||||
protected void hideEmojiDrawer(boolean expectingKeyboard) {
|
||||
if (isEmojiDrawerOpen()) {
|
||||
getEmojiPopup().dismiss();
|
||||
if (!expectingKeyboard || container.isLandscape()) {
|
||||
container.unpadForCustomKeyboard();
|
||||
getEmojiDrawer().dismiss();
|
||||
} else {
|
||||
container.postOnKeyboardOpen(new Runnable() {
|
||||
@Override public void run() {
|
||||
getEmojiDrawer().dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
emojiToggle.setToEmoji();
|
||||
}
|
||||
|
||||
private boolean isEmojiDrawerOpen() {
|
||||
return emojiPopup.isPresent() && emojiPopup.get().isShowing();
|
||||
return emojiDrawer.isPresent() && emojiDrawer.get().isShowing();
|
||||
}
|
||||
|
||||
private void initializeResources() {
|
||||
|
@ -1358,12 +1365,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
public void onClick(View v) {
|
||||
Log.w(TAG, "EmojiToggleListener onClick()");
|
||||
if (isEmojiDrawerOpen()) {
|
||||
hideEmojiPopup(true);
|
||||
hideEmojiDrawer(true);
|
||||
openKeyboardForComposition();
|
||||
} else {
|
||||
container.postOnKeyboardClose(new Runnable() {
|
||||
@Override public void run() {
|
||||
showEmojiPopup();
|
||||
showEmojiDrawer();
|
||||
}
|
||||
});
|
||||
quickAttachmentDrawer.close();
|
||||
|
@ -1378,7 +1385,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
InputMethodManager input = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
input.hideSoftInputFromWindow(composeText.getWindowToken(), 0);
|
||||
composeText.clearFocus();
|
||||
hideEmojiPopup(false);
|
||||
hideEmojiDrawer(false);
|
||||
quickAttachmentDrawer.open();
|
||||
}
|
||||
}
|
||||
|
@ -1426,7 +1433,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
hideEmojiPopup(true);
|
||||
hideEmojiDrawer(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1454,7 +1461,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus && isEmojiDrawerOpen()) {
|
||||
hideEmojiPopup(true);
|
||||
hideEmojiDrawer(true);
|
||||
} else if (hasFocus && quickAttachmentDrawer.isOpen()) {
|
||||
quickAttachmentDrawer.close();
|
||||
}
|
||||
|
|
|
@ -114,8 +114,8 @@ public class ConversationPopupActivity extends ConversationActivity {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void hideEmojiPopup(boolean expectingKeyboard) {
|
||||
super.hideEmojiPopup(false);
|
||||
protected void hideEmojiDrawer(boolean expectingKeyboard) {
|
||||
super.hideEmojiDrawer(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -97,14 +97,6 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
|||
oldRect.set(newRect);
|
||||
}
|
||||
|
||||
public void padForCustomKeyboard(final int height) {
|
||||
setPadding(0, 0, 0, height);
|
||||
}
|
||||
|
||||
public void unpadForCustomKeyboard() {
|
||||
setPadding(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
private int getViewInset() {
|
||||
if (Build.VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
|
||||
return 0;
|
||||
|
@ -135,7 +127,6 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
|||
setKeyboardPortraitHeight(keyboardHeight);
|
||||
}
|
||||
notifyShownListeners();
|
||||
unpadForCustomKeyboard();
|
||||
}
|
||||
|
||||
protected void onKeyboardClose() {
|
||||
|
@ -188,6 +179,19 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
|||
}
|
||||
}
|
||||
|
||||
public void postOnKeyboardOpen(final Runnable runnable) {
|
||||
if (!keyboardOpen) {
|
||||
addOnKeyboardShownListener(new OnKeyboardShownListener() {
|
||||
@Override public void onKeyboardShown() {
|
||||
removeOnKeyboardShownListener(this);
|
||||
runnable.run();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
public void addOnKeyboardHiddenListener(OnKeyboardHiddenListener listener) {
|
||||
hiddenListeners.add(listener);
|
||||
}
|
||||
|
@ -205,13 +209,15 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
|||
}
|
||||
|
||||
private void notifyHiddenListeners() {
|
||||
for (OnKeyboardHiddenListener listener : hiddenListeners) {
|
||||
final Set<OnKeyboardHiddenListener> listeners = new HashSet<>(hiddenListeners);
|
||||
for (OnKeyboardHiddenListener listener : listeners) {
|
||||
listener.onKeyboardHidden();
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyShownListeners() {
|
||||
for (OnKeyboardShownListener listener : shownListeners) {
|
||||
final Set<OnKeyboardShownListener> listeners = new HashSet<>(shownListeners);
|
||||
for (OnKeyboardShownListener listener : listeners) {
|
||||
listener.onKeyboardShown();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.support.annotation.NonNull;
|
|||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.widget.LinearLayoutCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
|
@ -19,6 +18,7 @@ import android.widget.LinearLayout;
|
|||
import com.astuetz.PagerSlidingTabStrip;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
|
||||
import org.thoughtcrime.securesms.components.RepeatableImageKey;
|
||||
import org.thoughtcrime.securesms.components.RepeatableImageKey.KeyEventListener;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiPageView.EmojiSelectionListener;
|
||||
|
@ -27,10 +27,9 @@ import org.thoughtcrime.securesms.util.ResUtil;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class EmojiDrawer extends LinearLayoutCompat {
|
||||
public class EmojiDrawer extends LinearLayout {
|
||||
private static final KeyEvent DELETE_KEY_EVENT = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
|
||||
|
||||
private LinearLayout container;
|
||||
private ViewPager pager;
|
||||
private List<EmojiPageModel> models;
|
||||
private PagerSlidingTabStrip strip;
|
||||
|
@ -42,11 +41,8 @@ public class EmojiDrawer extends LinearLayoutCompat {
|
|||
}
|
||||
|
||||
public EmojiDrawer(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public EmojiDrawer(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
super(context, attrs);
|
||||
setOrientation(VERTICAL);
|
||||
final View v = LayoutInflater.from(getContext()).inflate(R.layout.emoji_drawer, this, true);
|
||||
initializeResources(v);
|
||||
initializePageModels();
|
||||
|
@ -59,7 +55,6 @@ public class EmojiDrawer extends LinearLayoutCompat {
|
|||
|
||||
private void initializeResources(View v) {
|
||||
Log.w("EmojiDrawer", "initializeResources()");
|
||||
this.container = (LinearLayout) v.findViewById(R.id.container);
|
||||
this.pager = (ViewPager) v.findViewById(R.id.emoji_pager);
|
||||
this.strip = (PagerSlidingTabStrip) v.findViewById(R.id.tabs);
|
||||
|
||||
|
@ -71,8 +66,19 @@ public class EmojiDrawer extends LinearLayoutCompat {
|
|||
});
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return container.getVisibility() == View.VISIBLE;
|
||||
public boolean isShowing() {
|
||||
return getVisibility() == VISIBLE;
|
||||
}
|
||||
|
||||
public void show(KeyboardAwareLinearLayout container) {
|
||||
ViewGroup.LayoutParams params = getLayoutParams();
|
||||
params.height = container.getKeyboardHeight();
|
||||
setLayoutParams(params);
|
||||
setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
setVisibility(GONE);
|
||||
}
|
||||
|
||||
private void initializeEmojiGrid() {
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
package org.thoughtcrime.securesms.components.emoji;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer.EmojiEventListener;
|
||||
|
||||
public class EmojiPopup extends PopupWindow {
|
||||
private static final String TAG = EmojiPopup.class.getSimpleName();
|
||||
private KeyboardAwareLinearLayout parent;
|
||||
|
||||
public EmojiPopup(KeyboardAwareLinearLayout parent) {
|
||||
super(new EmojiDrawer(parent.getContext()),
|
||||
parent.getWidth(),
|
||||
parent.getResources().getDimensionPixelSize(R.dimen.min_emoji_drawer_height));
|
||||
this.parent = parent;
|
||||
getContentView().setClickable(true);
|
||||
getContentView().setFocusableInTouchMode(true);
|
||||
getContentView().setFocusable(true);
|
||||
setTouchable(true);
|
||||
setFocusable(true);
|
||||
}
|
||||
|
||||
public void setEmojiEventListener(EmojiEventListener listener) {
|
||||
((EmojiDrawer)getContentView()).setEmojiEventListener(listener);
|
||||
}
|
||||
|
||||
public void show() {
|
||||
setHeight(parent.getKeyboardHeight());
|
||||
setWidth(parent.getWidth());
|
||||
parent.padForCustomKeyboard(getHeight());
|
||||
Log.w(TAG, String.format("show(%d, %d)", getWidth(), getHeight()));
|
||||
showAtLocation(parent, Gravity.BOTTOM | Gravity.LEFT, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismiss() {
|
||||
super.dismiss();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
update(parent, 0, 0, parent.getWidth(), -1);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue