Smooth transition for custom keyboards and softkey

Closes #3786
Fixes #3780
// FREEBIE
This commit is contained in:
Jake McGinty
2015-07-24 13:22:28 -07:00
committed by Moxie Marlinspike
parent 24e14cbc73
commit 13bad6dfed
10 changed files with 344 additions and 321 deletions

View File

@@ -0,0 +1,94 @@
package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.EditText;
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout.OnKeyboardShownListener;
import org.thoughtcrime.securesms.util.ServiceUtil;
public class InputAwareLayout extends KeyboardAwareLinearLayout implements OnKeyboardShownListener {
private InputView current;
public InputAwareLayout(Context context) {
this(context, null);
}
public InputAwareLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public InputAwareLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
addOnKeyboardShownListener(this);
}
@Override public void onKeyboardShown() {
hideAttachedInput();
}
public void show(@NonNull final EditText imeTarget, @NonNull final InputView input) {
if (isKeyboardOpen()) {
hideSoftkey(imeTarget, new Runnable() {
@Override public void run() {
input.show(getKeyboardHeight(), true);
}
});
} else if (current != null && current.isShowing()) {
current.hide(true);
input.show(getKeyboardHeight(), true);
} else {
input.show(getKeyboardHeight(), false);
}
current = input;
}
public InputView getCurrentInput() {
return current;
}
public void hideCurrentInput(EditText imeTarget) {
if (isKeyboardOpen()) hideSoftkey(imeTarget, null);
else hideAttachedInput();
}
public void hideAttachedInput() {
if (current != null) current.hide(true);
current = null;
}
public boolean isInputOpen() {
return (isKeyboardOpen() || (current != null && current.isShowing()));
}
public void showSoftkey(final EditText inputTarget) {
postOnKeyboardOpen(new Runnable() {
@Override public void run() {
hideAttachedInput();
}
});
inputTarget.post(new Runnable() {
@Override public void run() {
inputTarget.requestFocus();
ServiceUtil.getInputMethodManager(inputTarget.getContext()).showSoftInput(inputTarget, 0);
}
});
}
private void hideSoftkey(final EditText inputTarget, @Nullable Runnable runAfterClose) {
if (runAfterClose != null) postOnKeyboardClose(runAfterClose);
ServiceUtil.getInputMethodManager(inputTarget.getContext())
.hideSoftInputFromWindow(inputTarget.getWindowToken(), 0);
}
public interface InputView {
void show(int height, boolean immediate);
void hide(boolean immediate);
boolean isShowing();
}
}

View File

@@ -16,6 +16,7 @@
*/
package org.thoughtcrime.securesms.components;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
@@ -42,14 +43,17 @@ import java.util.Set;
public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
private static final String TAG = KeyboardAwareLinearLayout.class.getSimpleName();
private final Rect oldRect = new Rect();
private final Rect newRect = new Rect();
private final Set<OnKeyboardHiddenListener> hiddenListeners = new HashSet<>();
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 Rect oldRect = new Rect();
private final Rect newRect = new Rect();
private final Set<OnKeyboardHiddenListener> hiddenListeners = new HashSet<>();
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;
@@ -64,16 +68,19 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
public KeyboardAwareLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
final 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) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
updateRotation();
updateKeyboardState();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private void updateRotation() {
@@ -86,10 +93,8 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
}
private void updateKeyboardState() {
int res = getResources().getIdentifier("status_bar_height", "dimen", "android");
int statusBarHeight = res > 0 ? getResources().getDimensionPixelSize(res) : 0;
final int availableHeight = this.getRootView().getHeight() - statusBarHeight - getViewInset();
if (viewInset == 0 && Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) viewInset = getViewInset();
final int availableHeight = this.getRootView().getHeight() - statusBarHeight - viewInset;
getWindowVisibleDisplayFrame(newRect);
final int oldKeyboardHeight = availableHeight - (oldRect.bottom - oldRect.top);
@@ -104,11 +109,8 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
oldRect.set(newRect);
}
@TargetApi(VERSION_CODES.LOLLIPOP)
private int getViewInset() {
if (Build.VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
return 0;
}
try {
Field attachInfoField = View.class.getDeclaredField("mAttachInfo");
attachInfoField.setAccessible(true);
@@ -141,6 +143,10 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
notifyHiddenListeners();
}
public boolean isKeyboardOpen() {
return keyboardOpen;
}
public int getKeyboardHeight() {
return isLandscape() ? getKeyboardLandscapeHeight() : getKeyboardPortraitHeight();
}

View File

@@ -21,32 +21,31 @@ import android.view.ViewGroup;
import android.widget.ImageButton;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.InputManager.InputView;
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
import org.thoughtcrime.securesms.components.camera.QuickCamera.QuickCameraListener;
import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.Util;
public class QuickAttachmentDrawer extends ViewGroup {
private static final String TAG = QuickAttachmentDrawer.class.getSimpleName();
private static final float FULL_EXPANDED_ANCHOR_POINT = 1.f;
private static final float COLLAPSED_ANCHOR_POINT = 0.f;
public class QuickAttachmentDrawer extends ViewGroup implements InputView {
private static final String TAG = QuickAttachmentDrawer.class.getSimpleName();
private final ViewDragHelper dragHelper;
private QuickCamera quickCamera;
private int coverViewPosition;
private KeyboardAwareLinearLayout coverView;
private KeyboardAwareLinearLayout container;
private View coverView;
private View controls;
private ImageButton fullScreenButton;
private ImageButton swapCameraButton;
private ImageButton shutterButton;
private float slideOffset;
private int slideOffset;
private float initialMotionX;
private float initialMotionY;
private int rotation;
private int slideRange;
private AttachmentDrawerListener listener;
private int halfExpandedHeight;
private float halfExpandedAnchorPoint;
private DrawerState drawerState = DrawerState.COLLAPSED;
private boolean halfModeUnsupported = VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH;
@@ -82,16 +81,19 @@ public class QuickAttachmentDrawer extends ViewGroup {
Camera.getNumberOfCameras() > 0;
}
public boolean isOpen() {
@Override
public boolean isShowing() {
return drawerState.isVisible();
}
public void close() {
setDrawerStateAndAnimate(DrawerState.COLLAPSED);
@Override
public void hide(boolean immediate) {
setDrawerStateAndUpdate(DrawerState.COLLAPSED, immediate);
}
public void open() {
setDrawerStateAndAnimate(DrawerState.HALF_EXPANDED);
@Override
public void show(int height, boolean immediate) {
setDrawerStateAndUpdate(DrawerState.HALF_EXPANDED, immediate);
}
public void onConfigurationChanged() {
@@ -99,11 +101,11 @@ public class QuickAttachmentDrawer extends ViewGroup {
final boolean rotationChanged = this.rotation != rotation;
this.rotation = rotation;
if (rotationChanged) {
if (isOpen()) {
if (isShowing()) {
quickCamera.onPause();
}
updateControlsView();
setDrawerStateAndAnimate(drawerState);
setDrawerStateAndUpdate(drawerState);
}
}
@@ -134,23 +136,19 @@ public class QuickAttachmentDrawer extends ViewGroup {
return isLandscape() || halfModeUnsupported;
}
private KeyboardAwareLinearLayout getCoverView() {
if (coverView != null) return coverView;
final View coverViewChild = getChildAt(coverViewPosition);
if (coverViewChild != null && !(coverViewChild instanceof KeyboardAwareLinearLayout)) {
throw new IllegalStateException("cover view must be a KeyboardAwareLinearLayout");
}
coverView = (KeyboardAwareLinearLayout) coverViewChild;
private View getCoverView() {
if (coverView == null) coverView = getChildAt(coverViewPosition);
return coverView;
}
private KeyboardAwareLinearLayout getContainer() {
if (container == null) container = (KeyboardAwareLinearLayout)getParent();
return container;
}
private void updateHalfExpandedAnchorPoint() {
if (getCoverView() != null) {
slideRange = getMeasuredHeight();
halfExpandedHeight = coverView.getKeyboardHeight();
halfExpandedAnchorPoint = computeSlideOffsetFromCoverBottom(slideRange - halfExpandedHeight);
if (getContainer() != null) {
halfExpandedHeight = getContainer().getKeyboardHeight();
}
}
@@ -159,8 +157,6 @@ public class QuickAttachmentDrawer extends ViewGroup {
final int paddingLeft = getPaddingLeft();
final int paddingTop = getPaddingTop();
updateHalfExpandedAnchorPoint();
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
final int childHeight = child.getMeasuredHeight();
@@ -177,8 +173,8 @@ public class QuickAttachmentDrawer extends ViewGroup {
} else if (child == controls) {
childBottom = getMeasuredHeight();
} else {
childBottom = computeCoverBottomPosition(slideOffset);
childTop = childBottom - childHeight;
childTop = computeCoverTopPosition(slideOffset);
childBottom = childTop + childHeight;
}
final int childRight = childLeft + child.getMeasuredWidth();
@@ -233,7 +229,7 @@ public class QuickAttachmentDrawer extends ViewGroup {
default:
childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
break;
}
}
child.measure(childWidthSpec, childHeightSpec);
}
@@ -269,11 +265,11 @@ public class QuickAttachmentDrawer extends ViewGroup {
ViewCompat.postInvalidateOnAnimation(this);
}
if (slideOffset == COLLAPSED_ANCHOR_POINT && quickCamera.isStarted()) {
if (slideOffset == 0 && quickCamera.isStarted()) {
quickCamera.onPause();
controls.setVisibility(INVISIBLE);
quickCamera.setVisibility(INVISIBLE);
} else if (slideOffset != COLLAPSED_ANCHOR_POINT && !quickCamera.isStarted() & !paused) {
} else if (slideOffset != 0 && !quickCamera.isStarted() & !paused) {
controls.setVisibility(VISIBLE);
quickCamera.setVisibility(VISIBLE);
quickCamera.onResume();
@@ -284,7 +280,6 @@ public class QuickAttachmentDrawer extends ViewGroup {
switch (drawerState) {
case COLLAPSED:
fullScreenButton.setImageResource(R.drawable.quick_camera_fullscreen);
if (listener != null) listener.onAttachmentDrawerClosed();
break;
case HALF_EXPANDED:
if (isFullscreenOnly()) {
@@ -292,30 +287,37 @@ public class QuickAttachmentDrawer extends ViewGroup {
return;
}
fullScreenButton.setImageResource(R.drawable.quick_camera_fullscreen);
if (listener != null) listener.onAttachmentDrawerOpened();
break;
case FULL_EXPANDED:
fullScreenButton.setImageResource(isFullscreenOnly() ? R.drawable.quick_camera_hide
: R.drawable.quick_camera_exit_fullscreen);
if (listener != null) listener.onAttachmentDrawerOpened();
break;
}
this.drawerState = drawerState;
}
public float getTargetSlideOffset() {
switch (drawerState) {
case FULL_EXPANDED: return FULL_EXPANDED_ANCHOR_POINT;
case HALF_EXPANDED: return halfExpandedAnchorPoint;
default: return COLLAPSED_ANCHOR_POINT;
if (listener != null && drawerState != this.drawerState) {
this.drawerState = drawerState;
listener.onAttachmentDrawerStateChanged(drawerState);
}
}
public void setDrawerStateAndAnimate(final DrawerState requestedDrawerState) {
public int getTargetSlideOffset() {
switch (drawerState) {
case FULL_EXPANDED: return getMeasuredHeight();
case HALF_EXPANDED: return halfExpandedHeight;
default: return 0;
}
}
public void setDrawerStateAndUpdate(final DrawerState requestedDrawerState) {
setDrawerStateAndUpdate(requestedDrawerState, false);
}
public void setDrawerStateAndUpdate(final DrawerState requestedDrawerState, boolean instant) {
DrawerState oldDrawerState = this.drawerState;
setDrawerState(requestedDrawerState);
if (oldDrawerState != drawerState) {
slideTo(getTargetSlideOffset());
updateHalfExpandedAnchorPoint();
slideTo(getTargetSlideOffset(), instant);
}
}
@@ -325,8 +327,7 @@ public class QuickAttachmentDrawer extends ViewGroup {
}
public interface AttachmentDrawerListener extends QuickCameraListener {
void onAttachmentDrawerClosed();
void onAttachmentDrawerOpened();
void onAttachmentDrawerStateChanged(DrawerState drawerState);
}
private class ViewDragHelperCallback extends ViewDragHelper.Callback {
@@ -351,10 +352,7 @@ public class QuickAttachmentDrawer extends ViewGroup {
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
final int expandedTop = computeCoverBottomPosition(FULL_EXPANDED_ANCHOR_POINT) - coverView.getHeight();
final int collapsedTop = computeCoverBottomPosition(COLLAPSED_ANCHOR_POINT) - coverView.getHeight();
final int newTop = Math.min(Math.max(coverView.getTop() + dy, expandedTop), collapsedTop);
slideOffset = computeSlideOffsetFromCoverBottom(newTop + coverView.getHeight());
slideOffset = Util.clamp(slideOffset - dy, 0, getMeasuredHeight());
requestLayout();
}
@@ -367,25 +365,20 @@ public class QuickAttachmentDrawer extends ViewGroup {
if (direction > 1) {
drawerState = DrawerState.FULL_EXPANDED;
} else if (direction < -1) {
boolean halfExpand = (slideOffset > halfExpandedAnchorPoint && !isLandscape());
boolean halfExpand = (slideOffset > halfExpandedHeight && !isLandscape());
drawerState = halfExpand ? DrawerState.HALF_EXPANDED : DrawerState.COLLAPSED;
} else if (!isLandscape()) {
if (halfExpandedAnchorPoint != 1 && slideOffset >= (1.f + halfExpandedAnchorPoint) / 2) {
if (slideOffset >= (halfExpandedHeight + getMeasuredHeight()) / 2) {
drawerState = DrawerState.FULL_EXPANDED;
} else if (halfExpandedAnchorPoint == 1 && slideOffset >= 0.5f) {
drawerState = DrawerState.FULL_EXPANDED;
} else if (halfExpandedAnchorPoint != 1 && slideOffset >= halfExpandedAnchorPoint) {
drawerState = DrawerState.HALF_EXPANDED;
} else if (halfExpandedAnchorPoint != 1 && slideOffset >= halfExpandedAnchorPoint / 2) {
} else if (slideOffset >= halfExpandedHeight / 2) {
drawerState = DrawerState.HALF_EXPANDED;
}
}
setDrawerState(drawerState);
float slideOffset = getTargetSlideOffset();
int slideOffset = getTargetSlideOffset();
dragHelper.captureChildView(coverView, 0);
Log.w(TAG, String.format("setting cover at %d", computeCoverBottomPosition(slideOffset) - coverView.getHeight()));
dragHelper.settleCapturedViewAt(coverView.getLeft(), computeCoverBottomPosition(slideOffset) - coverView.getHeight());
dragHelper.settleCapturedViewAt(coverView.getLeft(), computeCoverTopPosition(slideOffset));
dragHelper.captureChildView(quickCamera, 0);
dragHelper.settleCapturedViewAt(quickCamera.getLeft(), computeCameraTopPosition(slideOffset));
ViewCompat.postInvalidateOnAnimation(QuickAttachmentDrawer.this);
@@ -394,7 +387,7 @@ public class QuickAttachmentDrawer extends ViewGroup {
@Override
public int getViewVerticalDragRange(View child) {
return slideRange;
return getMeasuredHeight();
}
@Override
@@ -465,28 +458,22 @@ public class QuickAttachmentDrawer extends ViewGroup {
screenY >= viewLocation[1] && screenY < viewLocation[1] + quickCamera.getHeight();
}
private int computeCameraTopPosition(float slideOffset) {
float clampedOffset = slideOffset - halfExpandedAnchorPoint;
if (clampedOffset < COLLAPSED_ANCHOR_POINT) {
clampedOffset = COLLAPSED_ANCHOR_POINT;
} else {
clampedOffset = clampedOffset / (FULL_EXPANDED_ANCHOR_POINT - halfExpandedAnchorPoint);
}
float slidePixelOffset = slideOffset * slideRange +
(quickCamera.getMeasuredHeight() - coverView.getKeyboardHeight()) / 2 *
(FULL_EXPANDED_ANCHOR_POINT - clampedOffset);
float marginPixelOffset = (getMeasuredHeight() - quickCamera.getMeasuredHeight()) / 2 * clampedOffset;
return (int) (getMeasuredHeight() - slidePixelOffset + marginPixelOffset);
private int computeCameraTopPosition(int slideOffset) {
final int baseCameraTop = (quickCamera.getMeasuredHeight() - halfExpandedHeight) / 2;
final int baseOffset = getMeasuredHeight() - slideOffset - baseCameraTop;
final float slop = Util.clamp((float)(slideOffset - halfExpandedHeight) / (getMeasuredHeight() - halfExpandedHeight),
0f,
1f);
return baseOffset + (int)(slop * baseCameraTop);
}
private int computeCoverBottomPosition(float slideOffset) {
int slidePixelOffset = (int) (slideOffset * slideRange);
return getMeasuredHeight() - getPaddingBottom() - slidePixelOffset;
private int computeCoverTopPosition(int slideOffset) {
return getMeasuredHeight() - getPaddingBottom() - slideOffset - getCoverView().getMeasuredHeight();
}
private void slideTo(float slideOffset) {
if (dragHelper != null && !halfModeUnsupported) {
dragHelper.smoothSlideViewTo(coverView, coverView.getLeft(), computeCoverBottomPosition(slideOffset) - coverView.getHeight());
private void slideTo(int slideOffset, boolean forceInstant) {
if (dragHelper != null && !halfModeUnsupported && !forceInstant) {
dragHelper.smoothSlideViewTo(coverView, coverView.getLeft(), computeCoverTopPosition(slideOffset));
dragHelper.smoothSlideViewTo(quickCamera, quickCamera.getLeft(), computeCameraTopPosition(slideOffset));
ViewCompat.postInvalidateOnAnimation(this);
} else {
@@ -497,11 +484,6 @@ public class QuickAttachmentDrawer extends ViewGroup {
}
}
private float computeSlideOffsetFromCoverBottom(int topPosition) {
final int topBoundCollapsed = computeCoverBottomPosition(0);
return (float) (topBoundCollapsed - topPosition) / slideRange;
}
public void onPause() {
paused = true;
quickCamera.onPause();
@@ -524,7 +506,7 @@ public class QuickAttachmentDrawer extends ViewGroup {
@Override
public void onClick(View v) {
boolean crop = drawerState != DrawerState.FULL_EXPANDED;
int imageHeight = crop ? coverView.getKeyboardHeight() : quickCamera.getMeasuredHeight();
int imageHeight = crop ? getContainer().getKeyboardHeight() : quickCamera.getMeasuredHeight();
Rect previewRect = new Rect(0, 0, quickCamera.getMeasuredWidth(), imageHeight);
quickCamera.takePicture(previewRect);
}
@@ -543,11 +525,11 @@ public class QuickAttachmentDrawer extends ViewGroup {
@Override
public void onClick(View v) {
if (drawerState != DrawerState.FULL_EXPANDED) {
setDrawerStateAndAnimate(DrawerState.FULL_EXPANDED);
setDrawerStateAndUpdate(DrawerState.FULL_EXPANDED);
} else if (isFullscreenOnly()) {
setDrawerStateAndAnimate(DrawerState.COLLAPSED);
setDrawerStateAndUpdate(DrawerState.COLLAPSED);
} else {
setDrawerStateAndAnimate(DrawerState.HALF_EXPANDED);
setDrawerStateAndUpdate(DrawerState.HALF_EXPANDED);
}
}
}

View File

@@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.components.emoji;
import android.content.Context;
import android.content.res.Configuration;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
@@ -18,7 +19,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.InputManager.InputView;
import org.thoughtcrime.securesms.components.RepeatableImageKey;
import org.thoughtcrime.securesms.components.RepeatableImageKey.KeyEventListener;
import org.thoughtcrime.securesms.components.emoji.EmojiPageView.EmojiSelectionListener;
@@ -27,7 +28,7 @@ import org.thoughtcrime.securesms.util.ResUtil;
import java.util.LinkedList;
import java.util.List;
public class EmojiDrawer extends LinearLayout {
public class EmojiDrawer extends LinearLayout implements InputView {
private static final KeyEvent DELETE_KEY_EVENT = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
private ViewPager pager;
@@ -35,6 +36,7 @@ public class EmojiDrawer extends LinearLayout {
private PagerSlidingTabStrip strip;
private RecentEmojiPageModel recentModel;
private EmojiEventListener listener;
private EmojiDrawerListener drawerListener;
public EmojiDrawer(Context context) {
this(context, null);
@@ -43,6 +45,9 @@ public class EmojiDrawer extends LinearLayout {
public EmojiDrawer(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(VERTICAL);
}
private void initView() {
final View v = LayoutInflater.from(getContext()).inflate(R.layout.emoji_drawer, this, true);
initializeResources(v);
initializePageModels();
@@ -53,6 +58,10 @@ public class EmojiDrawer extends LinearLayout {
this.listener = listener;
}
public void setDrawerListener(EmojiDrawerListener listener) {
this.drawerListener = listener;
}
private void initializeResources(View v) {
Log.w("EmojiDrawer", "initializeResources()");
this.pager = (ViewPager) v.findViewById(R.id.emoji_pager);
@@ -66,20 +75,27 @@ public class EmojiDrawer extends LinearLayout {
});
}
@Override
public boolean isShowing() {
return getVisibility() == VISIBLE;
}
public void show(KeyboardAwareLinearLayout container) {
@Override
public void show(int height, boolean immediate) {
if (this.pager == null) initView();
ViewGroup.LayoutParams params = getLayoutParams();
params.height = container.getKeyboardHeight();
params.height = height;
Log.w("EmojiDrawer", "showing emoji drawer with height " + params.height);
setLayoutParams(params);
setVisibility(VISIBLE);
if (drawerListener != null) drawerListener.onShown();
}
public void dismiss() {
@Override
public void hide(boolean immediate) {
setVisibility(GONE);
if (drawerListener != null) drawerListener.onHidden();
Log.w("EmojiDrawer", "hide()");
}
private void initializeEmojiGrid() {
@@ -161,4 +177,9 @@ public class EmojiDrawer extends LinearLayout {
public interface EmojiEventListener extends EmojiSelectionListener {
void onKeyEvent(KeyEvent keyEvent);
}
public interface EmojiDrawerListener {
void onShown();
void onHidden();
}
}

View File

@@ -8,8 +8,9 @@ import android.util.AttributeSet;
import android.widget.ImageButton;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer.EmojiDrawerListener;
public class EmojiToggle extends ImageButton {
public class EmojiToggle extends ImageButton implements EmojiDrawerListener {
private Drawable emojiToggle;
private Drawable imeToggle;
@@ -48,4 +49,16 @@ public class EmojiToggle extends ImageButton {
drawables.recycle();
setToEmoji();
}
public void attach(EmojiDrawer drawer) {
drawer.setDrawerListener(this);
}
@Override public void onShown() {
setToIme();
}
@Override public void onHidden() {
setToEmoji();
}
}