在键盘上添加视图android

在我的Android应用程序中,我有一个聊天活动,我使用这个代码从android-chat-starter

问题是在模拟器一切工作正常,我testing了许多types的模拟器(api> 18,api = 18,api <18),但在实际设备的testing中,它的行为就像在这个图像

在这里输入图像说明

在键盘上方显示表情符号视图

这里是我用来显示表情符号视图的代码

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 > 

这是我的emojiview

 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(不知道后)theres没有办法得到键盘的高度。 所以你不能使用这个值来定位你的视图。

但是,您可以使用softKeyboard重新布局,通过使用具有“resize”值的softKeyboard(在Activity清单中)将您的根布局View调整为剩余屏幕空间的大小。 通过将视图定位在底部将使其完全位于键盘之上。

PS:另外,你的根视图需要它的高度值是match_parent,而不是其他任何东西(或者你需要以其他方式处理)

也许你的意思是你想要replace键盘的位置,而不是“顶部”(NORTH?),在这种情况下,你应该使用一个扩展视图的自定义视图,而不是使用为你打开键盘的EditText

在显示表情符号的窗口时,您必须隐藏键盘:

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(edText.getWindowToken(), 0);

edText是您目前所关注的编辑文本。

编辑:这是我的代码合并到你的。你可以试试看。

  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(); } } }); } } } 

您可以创build自定义的EditText,并通过覆盖onCheckIsTextEditor来禁用显示键盘。 请参阅以下代码:

  public class NoKeyBoardEditText extends EditText { @Override public boolean onCheckIsTextEditor() { return false; } } 

你可以做这样的事情来创buildView over 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的更多信息,请参阅此链接 。

如果你不想在键盘closures时显示你的布局,那么就隐藏这个布局。

希望它会帮助你。

我正在使用这个在我的应用程序,我已经从图书馆提取https://github.com/chathudan/KitKatEmoji我build议你使用这个库是非常完整和容易实现。; 在图书馆的例子是它的易用性。 如果没有,拉这样的事情:

  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; } } }); } 

当我将表情符号添加到我的应用程序时遇到了类似的问题。 我find了一种使用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> 

使用我的示例github项目作为参考。

有效 :)。 在列表视图中添加以下两行

  <ListView android:id="@+id/chat_list_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/bottomlayout" android:divider="@drawable/chat_divider" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:scrollbarStyle="outsideOverlay" android:stackFromBottom="true" android:transcriptMode="alwaysScroll" > </ListView> 

你可以在这里查看它