私のAndroidアプリケーションにチャットアクティビティがあります。このコードは Android-chat-starter から使用します
問題はエミュレータにあり、すべてが正常に機能します。多くの種類のエミュレータ(api> 18、api = 18、api <18)でテストしましたが、実際のデバイスでテストすると、この画像のように動作します
絵文字ビューはキーボードの上に表示されます
これが絵文字ビューを表示するために使用するコードです
private void showEmojiPopup(boolean show) {
showingEmoji = show;
if (show) {
if (emojiView == null) {
if (getActivity() == null) {
return;
}
emojiView = new EmojiView(getActivity());
emojiView.setListener(new EmojiView.Listener() {
public void onBackspace() {
chatEditText1.dispatchKeyEvent(new KeyEvent(0, 67));
}
public void onEmojiSelected(String symbol) {
int i = chatEditText1.getSelectionEnd();
if (i < 0) {
i = 0;
}
try {
CharSequence localCharSequence = Emoji.replaceEmoji(symbol, chatEditText1.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20));
chatEditText1.setText(chatEditText1.getText().insert(i, localCharSequence));
int j = i + localCharSequence.length();
chatEditText1.setSelection(j, j);
} catch (Exception e) {
Log.e(Constants.TAG, "Error showing emoji");
}
}
});
windowLayoutParams = new WindowManager.LayoutParams();
windowLayoutParams.gravity = Gravity.BOTTOM | Gravity.LEFT;
Log.d(TAG ,Build.VERSION.SDK_INT + " ");
if (Build.VERSION.SDK_INT >= 21) {
windowLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
} else {
windowLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
windowLayoutParams.token = getActivity().getWindow().getDecorView().getWindowToken();
}
windowLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
Log.d("emoj",WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + "");
}
final int currentHeight;
if (keyboardHeight <= 0)
keyboardHeight = App.getInstance().getSharedPreferences("emoji", 0).getInt("kbd_height", AndroidUtilities.dp(200));
currentHeight = keyboardHeight;
WindowManager wm = (WindowManager) App.getInstance().getSystemService(Activity.WINDOW_SERVICE);
windowLayoutParams.height = currentHeight;
windowLayoutParams.width = AndroidUtilities.displaySize.x;
try {
if (emojiView.getParent() != null) {
wm.removeViewImmediate(emojiView);
}
} catch (Exception e) {
Log.e(Constants.TAG, e.getMessage());
}
try {
wm.addView(emojiView, windowLayoutParams);
} catch (Exception e) {
Log.e(Constants.TAG, e.getMessage());
return;
}
if (!keyboardVisible) {
if (sizeNotifierRelativeLayout != null) {
sizeNotifierRelativeLayout.setPadding(0, 0, 0, currentHeight);
}
return;
}
} else {
removeEmojiWindow();
if (sizeNotifierRelativeLayout != null) {
sizeNotifierRelativeLayout.post(new Runnable() {
public void run() {
if (sizeNotifierRelativeLayout != null) {
sizeNotifierRelativeLayout.setPadding(0, 0, 0, 0);
}
}
});
}
}
}
@Override
public void onSizeChanged(int height) {
Rect localRect = new Rect();
getActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(localRect);
WindowManager wm = (WindowManager) App.getInstance().getSystemService(Activity.WINDOW_SERVICE);
if (wm == null || wm.getDefaultDisplay() == null) {
return;
}
if (height > AndroidUtilities.dp(50) && keyboardVisible) {
keyboardHeight = height;
App.getInstance().getSharedPreferences("emoji", 0).edit().putInt("kbd_height", keyboardHeight).commit();
}
if (showingEmoji) {
int newHeight = 0;
newHeight = keyboardHeight;
if (windowLayoutParams.width != AndroidUtilities.displaySize.x || windowLayoutParams.height != newHeight) {
windowLayoutParams.width = AndroidUtilities.displaySize.x;
windowLayoutParams.height = newHeight;
wm.updateViewLayout(emojiView, windowLayoutParams);
if (!keyboardVisible) {
sizeNotifierRelativeLayout.post(new Runnable() {
@Override
public void run() {
if (sizeNotifierRelativeLayout != null) {
sizeNotifierRelativeLayout.setPadding(0, 0, 0, windowLayoutParams.height);
sizeNotifierRelativeLayout.requestLayout();
}
}
});
}
}
}
私のandroidmanifest.xmlには
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW" />
<activity
Android:name=".ConversationShowActivity"
Android:screenOrientation="portrait"
Android:label="@string/title_activity_conversation_show"
Android:launchMode="singleTask"
Android:parentActivityName=".MainActivity"
Android:theme="@style/AppTheme"
Android:windowSoftInputMode="adjustResize" >
<meta-data
Android:name="Android.support.PARENT_ACTIVITY"
Android:value="com.exampel.myapp.MainActivity" />
</activity>
ここに私の会話ショーのxmlがあります
<com.example.myapp.widgets.SizeNotifierRelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:id="@+id/chat_layout"
Android:layout_height="match_parent"
Android:background="@color/white"
xmlns:fontawesometext="http://schemas.Android.com/apk/res-auto"
xmlns:bootstrap="http://schemas.Android.com/apk/res-auto"
tools:context="com.example.myapp.ConversationShowActivity">
<LinearLayout
Android:orientation="horizontal"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/errorLayout"
Android:layout_gravity="center"
Android:layout_centerVertical="true"
Android:visibility="invisible"
tools:visibilty="invisible"
Android:layout_alignParentLeft="true"
Android:layout_alignParentStart="true">
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:gravity="center"
Android:padding="5dp"
Android:text="Error loading conversation messages, Click here to try again"
Android:id="@+id/textView3"
Android:textColor="#ffff4314"
Android:textSize="20sp"
Android:textStyle="bold"/>
</LinearLayout>
<ProgressBar
style="?android:attr/progressBarStyleLarge"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:id="@+id/convProgressBar"
Android:layout_centerVertical="true"
Android:layout_centerHorizontal="true"/>
<RelativeLayout
Android:orientation="horizontal"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_alignParentTop="true"
Android:background="@drawable/border_bottom"
Android:layout_alignParentLeft="true"
Android:layout_alignParentStart="true"
Android:id="@+id/conv_header"
Android:paddingTop="10dp"
Android:paddingBottom="10dp"
Android:paddingRight="10dp"
Android:paddingLeft="10dp"
Android:padding="10dp">
<ImageView
Android:layout_width="50dp"
Android:layout_height="50dp"
Android:id="@+id/conv_avatar"
Android:src="@drawable/blank_avatar4"
Android:scaleType="fitXY"
Android:layout_marginRight="10dp"/>
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Aboudi"
Android:id="@+id/conv_user_name"
Android:textColor="#000000"
Android:textSize="18sp"
Android:layout_alignTop="@+id/conv_avatar"
Android:layout_alignLeft="@+id/conv_online"
Android:layout_alignStart="@+id/conv_online"/>
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="conv_online"
Android:id="@+id/conv_online"
Android:layout_below="@+id/conv_user_name"
Android:layout_toRightOf="@+id/conv_avatar"
Android:layout_toEndOf="@+id/conv_avatar"
Android:layout_marginTop="5dp"/>
<LinearLayout
Android:id="@+id/profileFavBtn"
Android:layout_width="30dp"
Android:background="@drawable/heart_bg"
Android:layout_height="30dp"
Android:gravity="center"
Android:layout_marginRight="5dp"
Android:layout_marginLeft="5dp"
Android:layout_alignParentRight="false"
Android:layout_toLeftOf="@+id/profilegiftBtn"
Android:layout_centerVertical="true">
<com.beardedhen.androidbootstrap.FontAwesomeText
Android:id="@+id/profileFavText"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
fontawesometext:fa_icon="fa-heart-o"
Android:textColor="#B94309"
Android:textSize="20sp"
/>
</LinearLayout>
<LinearLayout
Android:id="@+id/profilegiftBtn"
Android:layout_width="30dp"
Android:background="@drawable/accept_btn_bg"
Android:layout_height="30dp"
Android:gravity="center"
Android:layout_marginRight="5dp"
Android:layout_marginLeft="5dp"
Android:layout_alignParentRight="false"
Android:layout_toLeftOf="@+id/profileReportBtn"
Android:layout_centerVertical="true">
<com.beardedhen.androidbootstrap.FontAwesomeText
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
fontawesometext:fa_icon="fa-gift"
Android:textColor="@color/white"
Android:textSize="20sp"
/>
</LinearLayout>
<LinearLayout
Android:id="@+id/profileReportBtn"
Android:layout_width="30dp"
Android:background="@drawable/report_btn_bg"
Android:layout_height="30dp"
Android:gravity="center"
Android:layout_marginRight="5dp"
Android:layout_marginLeft="5dp"
Android:layout_alignParentRight="false"
Android:layout_toLeftOf="@+id/profileBlockBtn"
Android:layout_centerVertical="true">
<com.beardedhen.androidbootstrap.FontAwesomeText
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
fontawesometext:fa_icon="fa-info"
Android:textColor="@color/white"
Android:textSize="20sp"
/>
</LinearLayout>
<LinearLayout
Android:id="@+id/profileBlockBtn"
Android:layout_width="30dp"
Android:background="@drawable/refuse_btn_bg"
Android:layout_height="30dp"
Android:gravity="center"
Android:layout_marginRight="5dp"
Android:layout_marginLeft="5dp"
Android:layout_alignParentRight="true"
Android:layout_centerVertical="true">
<com.beardedhen.androidbootstrap.FontAwesomeText
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
fontawesometext:fa_icon="fa-remove"
Android:textColor="@color/white"
Android:textSize="20sp"
/>
</LinearLayout>
</RelativeLayout>
<ListView
Android:id="@+id/chat_list_view"
Android:paddingRight="@dimen/activity_horizontal_margin"
Android:paddingLeft="@dimen/activity_horizontal_margin"
Android:divider="@drawable/chat_divider"
Android:layout_width="match_parent"
Android:scrollbarStyle="outsideOverlay"
Android:layout_below="@id/conv_header"
Android:layout_above="@+id/bottomlayout"
Android:layout_height="match_parent"></ListView>
<LinearLayout
Android:id="@+id/bottomlayout"
Android:background="@drawable/profile_footer_border_top"
Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_alignParentBottom="true"
Android:layout_height="wrap_content">
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<TextView
Android:id="@+id/cant_send_text"
Android:layout_width="match_parent"
Android:text="You cant contact this member right now"
Android:layout_height="wrap_content"
Android:layout_alignParentTop="true"
Android:layout_alignParentBottom="false"
Android:layout_alignTop="@+id/chat_edit_text1"
Android:layout_alignBottom="@+id/chat_edit_text1"
Android:background="#ff4409"
Android:gravity="center"
Android:textColor="#ffffff"
Android:textSize="15sp"
Android:textStyle="bold"/>
<ImageView Android:src="@drawable/ic_msg_panel_smiles" Android:layout_alignParentLeft="true" Android:layout_alignParentStart="true" Android:layout_marginLeft="8dp" Android:layout_marginRight="8dp"
Android:layout_width="wrap_content" Android:id="@+id/emojiButton" Android:layout_alignBottom="@+id/chat_edit_text1" Android:layout_marginBottom="8dp"
Android:layout_height="wrap_content" />
<EditText
Android:layout_marginTop="8dp"
Android:layout_marginBottom="8dp"
Android:id="@+id/chat_edit_text1"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:scrollHorizontally="false"
Android:layout_toLeftOf="@+id/enter_chat1"
Android:layout_toRightOf="@id/emojiButton"
Android:layout_toEndOf="@id/emojiButton"
Android:layout_toStartOf="@+id/enter_chat1"
Android:hint="Type your message here .."
Android:singleLine="false"
Android:inputType="textCapSentences"
Android:textSize="18sp"
Android:paddingLeft="4dp" />
<ImageView Android:layout_alignParentRight="true"
Android:layout_alignParentEnd="true"
Android:id="@+id/enter_chat1"
Android:layout_width="wrap_content"
Android:layout_marginBottom="8dp"
Android:layout_height="wrap_content"
Android:layout_alignBottom="@id/chat_edit_text1"
Android:paddingLeft="13dp"
Android:paddingStart="13dp"
Android:paddingRight="17dp"
Android:paddingEnd="17dp"
Android:src="@drawable/ic_chat_send" />
</RelativeLayout>
</LinearLayout>
</com.example.myapp.widgets.SizeNotifierRelativeLayout >
これが私の絵文字ビューです
public class EmojiView extends LinearLayout {
private ArrayList<EmojiGridAdapter> adapters = new ArrayList<EmojiGridAdapter>();
private int[] icons = {
R.drawable.ic_emoji_recent,
R.drawable.ic_emoji_smile,
R.drawable.ic_emoji_flower,
R.drawable.ic_emoji_bell,
R.drawable.ic_emoji_car,
R.drawable.ic_emoji_symbol };
private Listener listener;
private ViewPager pager;
private FrameLayout recentsWrap;
private ArrayList<GridView> views = new ArrayList<GridView>();
public EmojiView(Context paramContext) {
super(paramContext);
init();
}
public EmojiView(Context paramContext, AttributeSet paramAttributeSet) {
super(paramContext, paramAttributeSet);
init();
}
public EmojiView(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {
super(paramContext, paramAttributeSet, paramInt);
init();
}
private void addToRecent(long paramLong) {
if (this.pager.getCurrentItem() == 0) {
return;
}
ArrayList<Long> localArrayList = new ArrayList<Long>();
long[] currentRecent = Emoji.data[0];
boolean was = false;
for (long aCurrentRecent : currentRecent) {
if (paramLong == aCurrentRecent) {
localArrayList.add(0, paramLong);
was = true;
} else {
localArrayList.add(aCurrentRecent);
}
}
if (!was) {
localArrayList.add(0, paramLong);
}
Emoji.data[0] = new long[Math.min(localArrayList.size(), 50)];
for (int q = 0; q < Emoji.data[0].length; q++) {
Emoji.data[0][q] = localArrayList.get(q);
}
adapters.get(0).data = Emoji.data[0];
adapters.get(0).notifyDataSetChanged();
saveRecents();
}
private String convert(long paramLong) {
String str = "";
for (int i = 0; ; i++) {
if (i >= 4) {
return str;
}
int j = (int)(0xFFFF & paramLong >> 16 * (3 - i));
if (j != 0) {
str = str + (char)j;
}
}
}
private void init() {
setOrientation(LinearLayout.VERTICAL);
for (int i = 0; i < Emoji.data.length; i++) {
GridView gridView = new GridView(getContext());
// if (AndroidUtilities.isTablet()) {
// gridView.setColumnWidth(AndroidUtilities.dp(60));
// } else {
gridView.setColumnWidth(AndroidUtilities.dp(45));
// }
gridView.setNumColumns(-1);
views.add(gridView);
EmojiGridAdapter localEmojiGridAdapter = new EmojiGridAdapter(Emoji.data[i]);
gridView.setAdapter(localEmojiGridAdapter);
// AndroidUtilities.setListViewEdgeEffectColor(gridView, 0xff999999);
adapters.add(localEmojiGridAdapter);
}
setBackgroundColor(0xff222222);
pager = new ViewPager(getContext());
pager.setAdapter(new EmojiPagesAdapter());
PagerSlidingTabStrip tabs = new PagerSlidingTabStrip(getContext());
tabs.setViewPager(pager);
tabs.setShouldExpand(true);
tabs.setIndicatorColor(0xff33b5e5);
tabs.setIndicatorHeight(AndroidUtilities.dp(2.0f));
tabs.setUnderlineHeight(AndroidUtilities.dp(2.0f));
tabs.setUnderlineColor(0x66000000);
tabs.setTabBackground(0);
LinearLayout localLinearLayout = new LinearLayout(getContext());
localLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
localLinearLayout.addView(tabs, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1.0f));
ImageView localImageView = new ImageView(getContext());
localImageView.setImageResource(R.drawable.ic_emoji_backspace);
localImageView.setScaleType(ImageView.ScaleType.CENTER);
localImageView.setBackgroundResource(R.drawable.bg_emoji_bs);
localImageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (EmojiView.this.listener != null) {
EmojiView.this.listener.onBackspace();
}
}
});
localLinearLayout.addView(localImageView, new LinearLayout.LayoutParams(AndroidUtilities.dp(61), LayoutParams.MATCH_PARENT));
recentsWrap = new FrameLayout(getContext());
recentsWrap.addView(views.get(0));
TextView localTextView = new TextView(getContext());
localTextView.setText(getContext().getString(R.string.NoRecent));
localTextView.setTextSize(18.0f);
localTextView.setTextColor(-7829368);
localTextView.setGravity(17);
recentsWrap.addView(localTextView);
views.get(0).setEmptyView(localTextView);
addView(localLinearLayout, new LinearLayout.LayoutParams(-1, AndroidUtilities.dp(48.0f)));
addView(pager);
loadRecents();
if (Emoji.data[0] == null || Emoji.data[0].length == 0) {
pager.setCurrentItem(1);
}
}
private void saveRecents() {
ArrayList<Long> localArrayList = new ArrayList<Long>();
long[] arrayOfLong = Emoji.data[0];
int i = arrayOfLong.length;
for (int j = 0; ; j++) {
if (j >= i) {
getContext().getSharedPreferences("emoji", 0).edit().putString("recents", TextUtils.join(",", localArrayList)).commit();
return;
}
localArrayList.add(arrayOfLong[j]);
}
}
public void loadRecents() {
String str = getContext().getSharedPreferences("emoji", 0).getString("recents", "");
String[] arrayOfString = null;
if ((str != null) && (str.length() > 0)) {
arrayOfString = str.split(",");
Emoji.data[0] = new long[arrayOfString.length];
}
if (arrayOfString != null) {
for (int i = 0; i < arrayOfString.length; i++) {
Emoji.data[0][i] = Long.parseLong(arrayOfString[i]);
}
adapters.get(0).data = Emoji.data[0];
adapters.get(0).notifyDataSetChanged();
}
}
public void onMeasure(int paramInt1, int paramInt2) {
super.onMeasure(View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.getSize(paramInt1), MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.getSize(paramInt2), MeasureSpec.EXACTLY));
}
public void setListener(Listener paramListener) {
this.listener = paramListener;
}
public void invalidateViews() {
for (GridView gridView : views) {
if (gridView != null) {
gridView.invalidateViews();
}
}
}
private class EmojiGridAdapter extends BaseAdapter {
long[] data;
public EmojiGridAdapter(long[] arg2) {
this.data = arg2;
}
public int getCount() {
return data.length;
}
public Object getItem(int i) {
return null;
}
public long getItemId(int i) {
return data[i];
}
public View getView(int i, View view, ViewGroup paramViewGroup) {
ImageView imageView = (ImageView)view;
if (imageView == null) {
imageView = new ImageView(EmojiView.this.getContext()) {
public void onMeasure(int paramAnonymousInt1, int paramAnonymousInt2) {
setMeasuredDimension(View.MeasureSpec.getSize(paramAnonymousInt1), View.MeasureSpec.getSize(paramAnonymousInt1));
}
};
imageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (EmojiView.this.listener != null) {
EmojiView.this.listener.onEmojiSelected(EmojiView.this.convert((Long)view.getTag()));
}
EmojiView.this.addToRecent((Long)view.getTag());
}
});
imageView.setBackgroundResource(R.drawable.list_selector);
imageView.setScaleType(ImageView.ScaleType.CENTER);
}
imageView.setImageDrawable(Emoji.getEmojiBigDrawable(data[i]));
imageView.setTag(data[i]);
return imageView;
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
if (observer != null) {
super.unregisterDataSetObserver(observer);
}
}
}
private class EmojiPagesAdapter extends PagerAdapter implements PagerSlidingTabStrip.IconTabProvider {
public void destroyItem(ViewGroup paramViewGroup, int paramInt, Object paramObject) {
View localObject;
if (paramInt == 0) {
localObject = recentsWrap;
} else {
localObject = views.get(paramInt);
}
paramViewGroup.removeView(localObject);
}
public int getCount() {
return views.size();
}
public int getPageIconResId(int paramInt) {
return icons[paramInt];
}
public Object instantiateItem(ViewGroup paramViewGroup, int paramInt) {
View localObject;
if (paramInt == 0) {
localObject = recentsWrap;
} else {
localObject = views.get(paramInt);
}
paramViewGroup.addView(localObject);
return localObject;
}
public boolean isViewFromObject(View paramView, Object paramObject) {
return paramView == paramObject;
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
if (observer != null) {
super.unregisterDataSetObserver(observer);
}
}
}
public static abstract interface Listener {
public abstract void onBackspace();
public abstract void onEmojiSelected(String paramString);
}
}
キーボードが表示されているときに問題が発生しますが、表示されていない場合は絵文字ビューが正常に機能します
残念ながら、Android 5.0(これ以降はわかりません))については、キーボードの高さを取得する方法がないため、この値を使用してビューを配置することはできません。
ただし、softKeyboardリレーアウトを使用して必要なことを実行できます。「resize」の値を指定してsoftKeyboard(アクティビティマニフェストで)を使用すると、ルートレイアウトビューが残りの画面スペースのサイズにサイズ変更されます。ビューを下部に配置すると、キーボードの上に正確に表示されます。
PS:また、ルートビューでは、高さの値を他の何よりもmatch_parentにする必要があります(または、他のハードな方法で処理する必要があります)。
多分あなたはあなたが「その上」(NORTH?)ではなくキーボードの場所を置き換えることを望んでいるのかもしれません、この場合、あなたはあなたのためにキーボードを開くEditTextを使わずにビューを拡張するCustomViewを使うべきです
絵文字のウィンドウを表示している間は、キーボードを非表示にする必要があります。
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(edText.getWindowToken(), 0);
edTextは、現在フォーカスしているedittextです。
編集:これはあなたにマージされた私のコードです。あなたはそれを試すことができます.
private void showEmojiPopup(boolean show) {
showingEmoji = show;
if (show) {
if (emojiView == null) {
if (getActivity() == null) {
return;
}
emojiView = new EmojiView(getActivity());
emojiView.setListener(new EmojiView.Listener() {
public void onBackspace() {
chatEditText1.dispatchKeyEvent(new KeyEvent(0, 67));
}
public void onEmojiSelected(String symbol) {
int i = chatEditText1.getSelectionEnd();
if (i < 0) {
i = 0;
}
try {
CharSequence localCharSequence = Emoji.replaceEmoji(symbol, chatEditText1.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20));
chatEditText1.setText(chatEditText1.getText().insert(i, localCharSequence));
int j = i + localCharSequence.length();
chatEditText1.setSelection(j, j);
} catch (Exception e) {
Log.e(Constants.TAG, "Error showing emoji");
}
}
});
windowLayoutParams = new WindowManager.LayoutParams();
windowLayoutParams.gravity = Gravity.BOTTOM | Gravity.LEFT;
Log.d(TAG ,Build.VERSION.SDK_INT + " ");
if (Build.VERSION.SDK_INT >= 21) {
windowLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
} else {
windowLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
windowLayoutParams.token = getActivity().getWindow().getDecorView().getWindowToken();
}
windowLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
Log.d("emoj",WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + "");
}
final int currentHeight;
if (keyboardHeight <= 0)
keyboardHeight = App.getInstance().getSharedPreferences("emoji", 0).getInt("kbd_height", AndroidUtilities.dp(200));
currentHeight = keyboardHeight;
WindowManager wm = (WindowManager) App.getInstance().getSystemService(Activity.WINDOW_SERVICE);
windowLayoutParams.height = currentHeight;
windowLayoutParams.width = AndroidUtilities.displaySize.x;
try {
if (emojiView.getParent() != null) {
wm.removeViewImmediate(emojiView);
}
} catch (Exception e) {
Log.e(Constants.TAG, e.getMessage());
}
try {
wm.addView(emojiView, windowLayoutParams);
} catch (Exception e) {
Log.e(Constants.TAG, e.getMessage());
return;
}
if (!keyboardVisible) {
if (sizeNotifierRelativeLayout != null) {
sizeNotifierRelativeLayout.setPadding(0, 0, 0, currentHeight);
}
return;
}
} else {
removeEmojiWindow();
if (sizeNotifierRelativeLayout != null) {
sizeNotifierRelativeLayout.post(new Runnable() {
public void run() {
if (sizeNotifierRelativeLayout != null) {
sizeNotifierRelativeLayout.setPadding(0, 0, 0, 0);
}
}
});
}
}
}
@Override
public void onSizeChanged(int height) {
Rect localRect = new Rect();
getActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(localRect);
WindowManager wm = (WindowManager) App.getInstance().getSystemService(Activity.WINDOW_SERVICE);
if (wm == null || wm.getDefaultDisplay() == null) {
return;
}
if (height > AndroidUtilities.dp(50) && keyboardVisible) {
keyboardHeight = height;
App.getInstance().getSharedPreferences("emoji", 0).edit().putInt("kbd_height", keyboardHeight).commit();
}
if (showingEmoji) {
//code to hide keyboard
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(edText.getWindowToken(), 0);
//end
int newHeight = 0;
newHeight = keyboardHeight;
if (windowLayoutParams.width != AndroidUtilities.displaySize.x || windowLayoutParams.height != newHeight) {
windowLayoutParams.width = AndroidUtilities.displaySize.x;
windowLayoutParams.height = newHeight;
wm.updateViewLayout(emojiView, windowLayoutParams);
if (!keyboardVisible) {
sizeNotifierRelativeLayout.post(new Runnable() {
@Override
public void run() {
if (sizeNotifierRelativeLayout != null) {
sizeNotifierRelativeLayout.setPadding(0, 0, 0, windowLayoutParams.height);
sizeNotifierRelativeLayout.requestLayout();
}
}
});
}
}
}
SoftKeyboard上にビューを作成するには、このようなことを行うことができます。
_<LinearLayout Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<FrameLayout Android:id="@+id/my_content"
Android:layout_width="match_parent"
Android:layout_height="0dip"
Android:layout_weight="1">
<!-- Your content here If edittext here then change the layout_height="wrap_content" on your EditText to layout_height="0dip" and let the weight handle it. --> // like your edittext or something.
</FrameLayout>
<LinearLayout Android:id="@+id/yourkeyboardlayout"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<!-- Your yourkeyboardlayout items here -->
</LinearLayout>
</LinearLayout>
_
注意 :
この行を使用している場合は、コードから削除してください。 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
あなたのマニフェストで:
_<activity Android:name="YourActivity"
Android:theme="@Android:style/Theme.NoTitleBar"
Android:windowSoftInputMode="adjustResize">
</activity>
_
SoftInputModeをAdjustResizeに調整したことを確認してください。
SoftInputmodeの詳細については、これを参照してください link 。
キーボードが押されているときにレイアウトを表示したくない場合は、そのレイアウトを非表示にします。
それがあなたを助けることを願っています。
カスタムEditTextを作成し、オーバーライドonCheckIsTextEditorによってキーボードの表示を無効にすることができます。以下のコードを参照してください:
public class NoKeyBoardEditText extends EditText {
@Override
public boolean onCheckIsTextEditor() {
return false;
}
}
私は自分のアプリケーションでこれを使用しています。ライブラリから抽出しました https://github.com/chathudan/KitKatEmoji ライブラリの使用は非常に完全で実装が簡単であることをお勧めします。ライブラリの例では、簡単に使用できます。そうでない場合は、次のようにプルします。
private void showKeyboard(View view) {
InputMethodManager keyboard = (InputMethodManager) mActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.showSoftInput(view, 0);
}
。
private void hideKeyboard() {
InputMethodManager inputMethodManager = (InputMethodManager) mActivity
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(mActivity.getCurrentFocus()
.getWindowToken(), 0);
}
。
protected void changeEmojiLayout() {
final InputMethodManager keyboard =
(InputMethodManager)mActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
// keyboard.showSoftInput(message, 0);
if (isEmojiVisible && !isKeyBoardVisible) {
btnEmoji
.setImageResource(R.drawable.ic_insert_emoticon_black_24dp);
btnCamara.setVisibility(View.VISIBLE);
btnGaleria.setVisibility(View.VISIBLE);
emojiIconsCover
.setVisibility(LinearLayout.GONE);
isEmojiVisible = false;
mShowEmojiHandler.postDelayed(new Runnable() {
@Override
public void run() {
inputMsg.requestFocus();
keyboard.showSoftInput(inputMsg, 0);
checkKeyboardHeight(parentLayout);
}
}, 100);
} else if (isEmojiVisible && isKeyBoardVisible) {
} else if (!isEmojiVisible && isKeyBoardVisible) {
hideKeyboard();
mShowEmojiHandler.postDelayed(new Runnable() {
@Override
public void run() {
btnEmoji
.setImageResource(R.drawable.ic_vp_keypad);
btnCamara.setVisibility(View.INVISIBLE);
btnGaleria.setVisibility(View.GONE);
emojiIconsCover
.setVisibility(LinearLayout.VISIBLE);
isEmojiVisible = true;
}
}, 100);
} else if (!isEmojiVisible && !isKeyBoardVisible) {
btnEmoji
.setImageResource(R.drawable.ic_vp_keypad);
btnCamara.setVisibility(View.INVISIBLE);
btnGaleria.setVisibility(View.GONE);
emojiIconsCover
.setVisibility(LinearLayout.VISIBLE);
isEmojiVisible = true;
}
}
。
private void checkKeyboardHeight(final View parentLayout) {
parentLayout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
parentLayout.getWindowVisibleDisplayFrame(r);
int screenHeight = parentLayout.getRootView()
.getHeight();
int heightDifference = screenHeight - (r.bottom);
if (previousHeightDiffrence - heightDifference > 50) {
// popupWindow.dismiss(); TODO
//
btnEmoji.setImageResource(R.drawable.ic_vp_smileys);
emojiIconsCover.setVisibility(LinearLayout.GONE);
}
previousHeightDiffrence = heightDifference;
if (heightDifference > 100) {
isKeyBoardVisible = true;
// changeKeyboardHeight(heightDifference);
} else {
isKeyBoardVisible = false;
}
}
});
}
アプリに絵文字を追加すると、同様の問題が発生しました。 PopUpWindowを使用して、ソフトキーボードの上に絵文字を表示する方法を見つけました。
EmojiOverKeyboard
public class EmojiOverKeyboard extends PopupWindow {
private int keyBoardHeight = 0;
private Boolean pendingOpen = false;
private Boolean isOpened = false;
OnSoftKeyboardOpenCloseListener onSoftKeyboardOpenCloseListener;
View rootView;
Context mContext;
/**
* Constructor
* @param rootView The top most layout in your view hierarchy. The difference of this view and the screen height will be used to calculate the keyboard height.
* @param mContext The context of current activity.
*/
public EmojiOverKeyboard(View rootView, Context mContext){
super(mContext);
this.mContext = mContext;
this.rootView = rootView;
View customView = createCustomView();
setContentView(customView);
setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//default size
setSize((int) mContext.getResources().getDimension(R.dimen.keyboard_height), LayoutParams.MATCH_PARENT);
}
/**
* Set the listener for the event of keyboard opening or closing.
*/
public void setOnSoftKeyboardOpenCloseListener(OnSoftKeyboardOpenCloseListener listener){
this.onSoftKeyboardOpenCloseListener = listener;
}
/**
* Use this function to show the emoji popup.
* NOTE: Since, the soft keyboard sizes are variable on different Android devices, the
* library needs you to open the soft keyboard atleast once before calling this function.
* If that is not possible see showAtBottomPending() function.
*
*/
public void showAtBottom(){
showAtLocation(rootView, Gravity.BOTTOM, 0, 0);
}
/**
* Use this function when the soft keyboard has not been opened yet. This
* will show the emoji popup after the keyboard is up next time.
* Generally, you will be calling InputMethodManager.showSoftInput function after
* calling this function.
*/
public void showAtBottomPending(){
if(isKeyBoardOpen())
showAtBottom();
else
pendingOpen = true;
}
/**
*
* @return Returns true if the soft keyboard is open, false otherwise.
*/
public Boolean isKeyBoardOpen(){
return isOpened;
}
/**
* Dismiss the popup
*/
@Override
public void dismiss() {
super.dismiss();
}
/**
* Call this function to resize the emoji popup according to your soft keyboard size
*/
public void setSizeForSoftKeyboard(){
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int screenHeight = getUsableScreenHeight();
int heightDifference = screenHeight
- (r.bottom - r.top);
int resourceId = mContext.getResources()
.getIdentifier("status_bar_height",
"dimen", "Android");
if (resourceId > 0) {
heightDifference -= mContext.getResources()
.getDimensionPixelSize(resourceId);
}
if (heightDifference > 100) {
keyBoardHeight = heightDifference;
setSize(LayoutParams.MATCH_PARENT, keyBoardHeight);
if(isOpened == false){
if(onSoftKeyboardOpenCloseListener!=null)
onSoftKeyboardOpenCloseListener.onKeyboardOpen(keyBoardHeight);
}
isOpened = true;
if(pendingOpen){
showAtBottom();
pendingOpen = false;
}
}
else{
isOpened = false;
if(onSoftKeyboardOpenCloseListener!=null)
onSoftKeyboardOpenCloseListener.onKeyboardClose();
}
}
});
}
private int getUsableScreenHeight() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
DisplayMetrics metrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(metrics);
return metrics.heightPixels;
} else {
return rootView.getRootView().getHeight();
}
}
/**
* Manually set the popup window size
* @param width Width of the popup
* @param height Height of the popup
*/
public void setSize(int width, int height){
setWidth(width);
setHeight(height);
}
private View createCustomView() {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.view_over_keyboard, null, false);
return view;
}
public interface OnSoftKeyboardOpenCloseListener{
void onKeyboardOpen(int keyBoardHeight);
void onKeyboardClose();
}
}
主な活動
public class MainActivity extends AppCompatActivity {
private RelativeLayout rootView;
private ImageButton showPopUp;
private EditText inputText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
rootView = (RelativeLayout) findViewById(R.id.rootview);
showPopUp = (ImageButton) findViewById(R.id.showPopUp);
inputText = (EditText) findViewById(R.id.inputText);
// Give the topmost view of your activity layout hierarchy. This will be used to measure soft keyboard height
final EmojiOverKeyboard popup = new EmojiOverKeyboard(rootView, this);
popup.setBackgroundDrawable(ContextCompat.getDrawable(this, R.drawable.keyboard_background));
popup.setAnimationStyle(R.style.EmojiPopupAnimation);
//Will automatically set size according to the soft keyboard size
popup.setSizeForSoftKeyboard();
//If the emoji popup is dismissed, change emojiButton to smiley icon
popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
changeEmojiKeyboardIcon(showPopUp, R.drawable.emoticon_upload_drawable);
}
});
//If the text keyboard closes, also dismiss the emoji popup
popup.setOnSoftKeyboardOpenCloseListener(new EmojiOverKeyboard.OnSoftKeyboardOpenCloseListener() {
@Override
public void onKeyboardOpen(int keyBoardHeight) {
}
@Override
public void onKeyboardClose() {
if (popup.isShowing())
popup.dismiss();
}
});
// To toggle between text keyboard and emoji keyboard keyboard(Popup)
showPopUp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//If popup is not showing => emoji keyboard is not visible, we need to show it
if (!popup.isShowing()) {
//If keyboard is visible, simply show the emoji popup
if (popup.isKeyBoardOpen()) {
popup.showAtBottom();
changeEmojiKeyboardIcon(showPopUp, R.drawable.keyboard_variant);
}
//else, open the text keyboard first and immediately after that show the emoji popup
else {
inputText.setFocusableInTouchMode(true);
inputText.requestFocus();
popup.showAtBottomPending();
final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(inputText, InputMethodManager.SHOW_IMPLICIT);
changeEmojiKeyboardIcon(showPopUp, R.drawable.keyboard_variant);
}
}
//If popup is showing, simply dismiss it to show the undelying text keyboard
else {
popup.dismiss();
}
}
});
}
private void changeEmojiKeyboardIcon(ImageView iconToBeChanged, int drawableResourceId){
iconToBeChanged.setImageResource(drawableResourceId);
}
}
ContentLayout
<?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:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="#eceff1">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="40dp"
Android:background="#e4e7e9"
></LinearLayout>
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginTop="24dp"
Android:padding="24dp"
Android:textSize="18sp"
Android:textColor="#545e60"
Android:text="Show your Emoji's here"
Android:layout_gravity="center_horizontal"
/>
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
>
<Android.support.design.widget.FloatingActionButton
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:fabSize="mini"
app:backgroundTint="#4db6ac"
Android:src="@drawable/emoticon_happy"
Android:layout_alignParentBottom="true"
Android:layout_alignParentRight="true"
Android:layout_margin="8dp"
app:elevation="0dp"
/>
</RelativeLayout>
参考としてmy sample github project を使用してください。