mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 18:15:22 +00:00
Resolve emoji keyboard layout issues
1) orientation changes are now properly handled 2) emoji panel will not overrun the actionbar and composition area in space-contentious situations (quick reply popup) Closes #3553 fixes #3501 fixes #3485 fixes #3199 // FREEBIE
This commit is contained in:
parent
c4524ebbd1
commit
bc787f20e3
@ -3,6 +3,7 @@
|
||||
<dimen name="emoji_drawer_size">32sp</dimen>
|
||||
<dimen name="min_keyboard_size">50dp</dimen>
|
||||
<dimen name="min_emoji_drawer_height">200dp</dimen>
|
||||
<dimen name="min_emoji_drawer_top_margin">170dp</dimen>
|
||||
<dimen name="emoji_drawer_item_padding">5dp</dimen>
|
||||
<dimen name="emoji_drawer_indicator_height">1.5dp</dimen>
|
||||
<dimen name="emoji_drawer_left_right_padding">5dp</dimen>
|
||||
|
@ -23,6 +23,7 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
@ -113,6 +114,7 @@ import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||
@ -264,8 +266,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
@Override public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
Log.w(TAG, String.format("onConfigurationChanged(%d -> %d)", getResources().getConfiguration().orientation, newConfig.orientation));
|
||||
quickAttachmentDrawer.onConfigurationChanged();
|
||||
hideEmojiPopup(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -274,6 +276,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
if (recipients != null) recipients.removeListener(this);
|
||||
if (securityUpdateReceiver != null) unregisterReceiver(securityUpdateReceiver);
|
||||
if (groupUpdateReceiver != null) unregisterReceiver(groupUpdateReceiver);
|
||||
hideEmojiPopup(false);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@ -858,13 +861,14 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
private EmojiPopup getEmojiPopup() {
|
||||
if (!emojiPopup.isPresent()) {
|
||||
EmojiPopup emojiPopup = new EmojiPopup(getWindow().getDecorView());
|
||||
EmojiPopup emojiPopup = new EmojiPopup(container);
|
||||
emojiPopup.setEmojiEventListener(new EmojiEventListener() {
|
||||
@Override public void onKeyEvent(KeyEvent keyEvent) {
|
||||
composeText.dispatchKeyEvent(keyEvent);
|
||||
}
|
||||
|
||||
@Override public void onEmojiSelected(String emoji) {
|
||||
Log.w(TAG, "onEmojiSelected()");
|
||||
composeText.insertEmoji(emoji);
|
||||
}
|
||||
});
|
||||
@ -874,17 +878,14 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
|
||||
private void showEmojiPopup() {
|
||||
int height = Math.max(getResources().getDimensionPixelSize(R.dimen.min_emoji_drawer_height),
|
||||
container.getKeyboardHeight());
|
||||
container.padForCustomKeyboard(height);
|
||||
getEmojiPopup().show(height);
|
||||
getEmojiPopup().show();
|
||||
emojiToggle.setToIme();
|
||||
}
|
||||
|
||||
private void hideEmojiPopup(boolean expectingKeyboard) {
|
||||
protected void hideEmojiPopup(boolean expectingKeyboard) {
|
||||
if (isEmojiDrawerOpen()) {
|
||||
getEmojiPopup().dismiss();
|
||||
if (!expectingKeyboard) {
|
||||
if (!expectingKeyboard || container.isLandscape()) {
|
||||
container.unpadForCustomKeyboard();
|
||||
}
|
||||
}
|
||||
@ -1330,22 +1331,34 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
}
|
||||
|
||||
private void openKeyboardForComposition() {
|
||||
composeText.post(new Runnable() {
|
||||
@Override public void run() {
|
||||
composeText.requestFocus();
|
||||
ServiceUtil.getInputMethodManager(ConversationActivity.this).showSoftInput(composeText, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void hideKeyboard() {
|
||||
ServiceUtil.getInputMethodManager(this).hideSoftInputFromWindow(composeText.getWindowToken(), 0);
|
||||
}
|
||||
|
||||
private class EmojiToggleListener implements OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
InputMethodManager input = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
Log.w(TAG, "EmojiToggleListener onClick()");
|
||||
if (isEmojiDrawerOpen()) {
|
||||
hideEmojiPopup(true);
|
||||
input.showSoftInput(composeText, 0);
|
||||
openKeyboardForComposition();
|
||||
} else {
|
||||
container.postOnKeyboardClose(new Runnable() {
|
||||
@Override public void run() {
|
||||
showEmojiPopup();
|
||||
}
|
||||
});
|
||||
input.hideSoftInputFromWindow(composeText.getWindowToken(), 0);
|
||||
quickAttachmentDrawer.setDrawerStateAndAnimate(DrawerState.COLLAPSED);
|
||||
quickAttachmentDrawer.close();
|
||||
hideKeyboard();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +112,11 @@ public class ConversationPopupActivity extends ConversationActivity {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hideEmojiPopup(boolean expectingKeyboard) {
|
||||
super.hideEmojiPopup(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendComplete(long threadId) {
|
||||
super.sendComplete(threadId);
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
package org.thoughtcrime.securesms.components;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
@ -27,9 +26,9 @@ import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashSet;
|
||||
@ -46,9 +45,10 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
||||
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 minKeyboardSize;
|
||||
|
||||
private boolean keyboardOpen;
|
||||
private boolean keyboardOpen = false;
|
||||
private int rotation = -1;
|
||||
|
||||
public KeyboardAwareLinearLayout(Context context) {
|
||||
this(context, null);
|
||||
@ -64,16 +64,29 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
||||
}
|
||||
|
||||
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
updateRotation();
|
||||
updateKeyboardState();
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
int res = getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
private void updateRotation() {
|
||||
int oldRotation = rotation;
|
||||
rotation = getDeviceRotation();
|
||||
if (oldRotation != rotation) {
|
||||
onKeyboardClose();
|
||||
oldRect.setEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
getWindowVisibleDisplayFrame(newRect);
|
||||
|
||||
final int oldKeyboardHeight = availableHeight - (oldRect.bottom - oldRect.top);
|
||||
final int keyboardHeight = availableHeight - (newRect.bottom - newRect.top);
|
||||
final int keyboardHeight = availableHeight - (newRect.bottom - newRect.top);
|
||||
|
||||
if (keyboardHeight - oldKeyboardHeight > minKeyboardSize && !keyboardOpen) {
|
||||
onKeyboardOpen(keyboardHeight);
|
||||
@ -84,7 +97,7 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
||||
oldRect.set(newRect);
|
||||
}
|
||||
|
||||
public void padForCustomKeyboard(int height) {
|
||||
public void padForCustomKeyboard(final int height) {
|
||||
setPadding(0, 0, 0, height);
|
||||
}
|
||||
|
||||
@ -117,22 +130,9 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
||||
|
||||
protected void onKeyboardOpen(int keyboardHeight) {
|
||||
keyboardOpen = true;
|
||||
Log.w(TAG, "onKeyboardOpen(" + keyboardHeight + ")");
|
||||
|
||||
WindowManager wm = (WindowManager) getContext().getSystemService(Activity.WINDOW_SERVICE);
|
||||
if (wm == null || wm.getDefaultDisplay() == null) {
|
||||
return;
|
||||
}
|
||||
int rotation = wm.getDefaultDisplay().getRotation();
|
||||
|
||||
switch (rotation) {
|
||||
case Surface.ROTATION_270:
|
||||
case Surface.ROTATION_90:
|
||||
setKeyboardLandscapeHeight(keyboardHeight);
|
||||
break;
|
||||
case Surface.ROTATION_0:
|
||||
case Surface.ROTATION_180:
|
||||
setKeyboardPortraitHeight(keyboardHeight);
|
||||
if (!isLandscape()) {
|
||||
setKeyboardPortraitHeight(keyboardHeight);
|
||||
}
|
||||
notifyShownListeners();
|
||||
unpadForCustomKeyboard();
|
||||
@ -140,7 +140,6 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
||||
|
||||
protected void onKeyboardClose() {
|
||||
keyboardOpen = false;
|
||||
Log.w(TAG, "onKeyboardClose()");
|
||||
notifyHiddenListeners();
|
||||
}
|
||||
|
||||
@ -149,39 +148,26 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
||||
}
|
||||
|
||||
public int getKeyboardHeight() {
|
||||
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
|
||||
if (wm == null || wm.getDefaultDisplay() == null) {
|
||||
throw new AssertionError("WindowManager was null or there is no default display");
|
||||
}
|
||||
return isLandscape() ? getKeyboardLandscapeHeight() : getKeyboardPortraitHeight();
|
||||
}
|
||||
|
||||
int rotation = wm.getDefaultDisplay().getRotation();
|
||||
|
||||
switch (rotation) {
|
||||
case Surface.ROTATION_270:
|
||||
case Surface.ROTATION_90:
|
||||
return getKeyboardLandscapeHeight();
|
||||
case Surface.ROTATION_0:
|
||||
case Surface.ROTATION_180:
|
||||
default:
|
||||
return getKeyboardPortraitHeight();
|
||||
}
|
||||
public boolean isLandscape() {
|
||||
int rotation = getDeviceRotation();
|
||||
return rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270;
|
||||
}
|
||||
private int getDeviceRotation() {
|
||||
return ServiceUtil.getWindowManager(getContext()).getDefaultDisplay().getRotation();
|
||||
}
|
||||
|
||||
private int getKeyboardLandscapeHeight() {
|
||||
return PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.getInt("keyboard_height_landscape",
|
||||
getResources().getDimensionPixelSize(R.dimen.min_emoji_drawer_height));
|
||||
return Math.max(getHeight(), getRootView().getHeight()) / 2;
|
||||
}
|
||||
|
||||
private int getKeyboardPortraitHeight() {
|
||||
return PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.getInt("keyboard_height_portrait",
|
||||
getResources().getDimensionPixelSize(R.dimen.min_emoji_drawer_height));
|
||||
}
|
||||
|
||||
private void setKeyboardLandscapeHeight(int height) {
|
||||
PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.edit().putInt("keyboard_height_landscape", height).apply();
|
||||
int keyboardHeight = PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.getInt("keyboard_height_portrait",
|
||||
getResources().getDimensionPixelSize(R.dimen.min_emoji_drawer_height));
|
||||
return Math.min(keyboardHeight, getRootView().getHeight() - getResources().getDimensionPixelSize(R.dimen.min_emoji_drawer_top_margin));
|
||||
}
|
||||
|
||||
private void setKeyboardPortraitHeight(int height) {
|
||||
|
@ -80,6 +80,7 @@ public class EmojiDrawer extends LinearLayoutCompat {
|
||||
models,
|
||||
new EmojiSelectionListener() {
|
||||
@Override public void onEmojiSelected(String emoji) {
|
||||
Log.w("EmojiDrawer", "onEmojiSelected()");
|
||||
recentModel.onCodePointSelected(emoji);
|
||||
if (listener != null) listener.onEmojiSelected(emoji);
|
||||
}
|
||||
|
@ -1,16 +1,12 @@
|
||||
package org.thoughtcrime.securesms.components.emoji;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.GridView;
|
||||
@ -25,24 +21,27 @@ public class EmojiPageView extends FrameLayout {
|
||||
private GridView grid;
|
||||
|
||||
public EmojiPageView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public EmojiPageView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public EmojiPageView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
@TargetApi(VERSION_CODES.LOLLIPOP)
|
||||
public EmojiPageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
init();
|
||||
final View view = LayoutInflater.from(getContext()).inflate(R.layout.emoji_grid_layout, this, true);
|
||||
grid = (GridView) view.findViewById(R.id.emoji);
|
||||
grid.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.emoji_drawer_size) + 2 * getResources().getDimensionPixelSize(R.dimen.emoji_drawer_item_padding));
|
||||
grid.setOnTouchListener(new OnTouchListener() {
|
||||
@Override public boolean onTouch(View v, MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
EmojiView emojiView = (EmojiView)grid.getChildAt(grid.pointToPosition((int)event.getX(), (int)event.getY()));
|
||||
if (listener != null && emojiView != null) listener.onEmojiSelected(emojiView.getEmoji());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onSelected() {
|
||||
@ -51,17 +50,6 @@ public class EmojiPageView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
final View view = LayoutInflater.from(getContext()).inflate(R.layout.emoji_grid_layout, this, true);
|
||||
grid = (GridView) view.findViewById(R.id.emoji);
|
||||
grid.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.emoji_drawer_size) + 2 * getResources().getDimensionPixelSize(R.dimen.emoji_drawer_item_padding));
|
||||
grid.setOnItemClickListener(new OnItemClickListener() {
|
||||
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (listener != null) listener.onEmojiSelected((String)view.getTag());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setModel(EmojiPageModel model) {
|
||||
this.model = model;
|
||||
grid.setAdapter(new EmojiGridAdapter(getContext(), model));
|
||||
@ -73,9 +61,9 @@ public class EmojiPageView extends FrameLayout {
|
||||
|
||||
private static class EmojiGridAdapter extends BaseAdapter {
|
||||
|
||||
protected final Context context;
|
||||
private final int emojiSize;
|
||||
private final EmojiPageModel model;
|
||||
protected final Context context;
|
||||
private final int emojiSize;
|
||||
private final EmojiPageModel model;
|
||||
|
||||
public EmojiGridAdapter(Context context, EmojiPageModel model) {
|
||||
this.context = context;
|
||||
@ -104,14 +92,13 @@ public class EmojiPageView extends FrameLayout {
|
||||
if (convertView != null && convertView instanceof EmojiView) {
|
||||
view = (EmojiView)convertView;
|
||||
} else {
|
||||
EmojiView emojiView = new EmojiView(context);
|
||||
final EmojiView emojiView = new EmojiView(context);
|
||||
emojiView.setPadding(pad, pad, pad, pad);
|
||||
emojiView.setLayoutParams(new AbsListView.LayoutParams(emojiSize + 2 * pad, emojiSize + 2 * pad));
|
||||
view = emojiView;
|
||||
}
|
||||
|
||||
view.setEmoji(model.getEmoji()[position]);
|
||||
view.setTag(model.getEmoji()[position]);
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,45 @@
|
||||
package org.thoughtcrime.securesms.components.emoji;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
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 View parent;
|
||||
private static final String TAG = EmojiPopup.class.getSimpleName();
|
||||
private KeyboardAwareLinearLayout parent;
|
||||
|
||||
public EmojiPopup(View parent) {
|
||||
public EmojiPopup(KeyboardAwareLinearLayout parent) {
|
||||
super(new EmojiDrawer(parent.getContext()),
|
||||
parent.getWidth(),
|
||||
parent.getResources().getDimensionPixelSize(R.dimen.min_emoji_drawer_height));
|
||||
this.parent = parent;
|
||||
Log.w("EmojiPopup", "popup initialized with width " + parent.getWidth());
|
||||
}
|
||||
|
||||
public void setEmojiEventListener(EmojiEventListener listener) {
|
||||
((EmojiDrawer)getContentView()).setEmojiEventListener(listener);
|
||||
}
|
||||
|
||||
public void show(int height) {
|
||||
setHeight(height);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -23,22 +23,17 @@ public class EmojiView extends View implements Drawable.Callback {
|
||||
private final Rect textBounds = new Rect();
|
||||
|
||||
public EmojiView(Context context) {
|
||||
super(context);
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public EmojiView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public EmojiView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@TargetApi(VERSION_CODES.LOLLIPOP)
|
||||
public EmojiView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
public void setEmoji(String emoji) {
|
||||
this.emoji = emoji;
|
||||
this.drawable = EmojiProvider.getInstance(getContext())
|
||||
@ -47,6 +42,10 @@ public class EmojiView extends View implements Drawable.Callback {
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
public String getEmoji() {
|
||||
return emoji;
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
if (drawable != null) {
|
||||
drawable.setBounds(getPaddingLeft(),
|
||||
|
16
src/org/thoughtcrime/securesms/util/ServiceUtil.java
Normal file
16
src/org/thoughtcrime/securesms/util/ServiceUtil.java
Normal file
@ -0,0 +1,16 @@
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
public class ServiceUtil {
|
||||
public static InputMethodManager getInputMethodManager(Context context) {
|
||||
return (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
}
|
||||
|
||||
public static WindowManager getWindowManager(Context context) {
|
||||
return (WindowManager) context.getSystemService(Activity.WINDOW_SERVICE);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user