Java 存在键盘时隐藏“底部导航栏” - Android
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43115510/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hiding ‘Bottom Navigation Bar’ whilst keyboard is present - Android
提问by Calco
I have a small demo chat UI application. This application has a bottom navigation bar. I need the bottom navigation bar to hide when the keyboard appears.
我有一个小的演示聊天 UI 应用程序。此应用程序有一个底部导航栏。我需要在键盘出现时隐藏底部导航栏。
Here is an example of the chat UI
As you can see when you click in the EditText element, the keyboard appears but the bottom navigation bar stays visible. I have tried methods such as this measurement method, but the UI elements flicker like this.
正如您在单击 EditText 元素时所看到的,键盘出现,但底部导航栏保持可见。我尝试过这种测量方法,但 UI 元素会像这样闪烁。
Is there a proper way to hide the bottom navigation bar when the keyboard is visible?
当键盘可见时,是否有适当的方法来隐藏底部导航栏?
EDIT:In the below activity you can see where I set the keyboard listener to adjust the position of UI elements when the keyboard is determined as being visible.
编辑:在下面的活动中,您可以看到我在哪里设置键盘侦听器以在确定键盘可见时调整 UI 元素的位置。
This is my activity code, uses setKeyboardListener method from the above link and set it in onCreateView:
这是我的活动代码,使用上述链接中的 setKeyboardListener 方法并将其设置在 onCreateView 中:
package uk.cal.codename.projectnedry.TeamChatFragment;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Layout;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.roughike.bottombar.BottomBar;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import uk.cal.codename.projectnedry.R;
import uk.cal.codename.projectnedry.TeamChatFragment.ListAdapter.TeamChatListAdapter;
import uk.demo.cal.genericmodelviewpresenter.GenericMvp.GenericMvpFragment;
import static android.view.View.GONE;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link TeamChatView.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link TeamChatView#newInstance} factory method to
* create an instance of this fragment.
*/
public class TeamChatView extends GenericMvpFragment implements TeamChatContract.RequiredViewOps {
private OnFragmentInteractionListener mListener;
@BindView(R.id.teamChatList)
RecyclerView mTeamChatRecyclerView;
@BindView(R.id.teamChatSendButton)
ImageButton mTeamChatSendButton;
@BindView(R.id.messageTextInput)
EditText mMessageTextInput;
TeamChatListAdapter mTeamChatListAdapter;
TeamChatListAdapter.ClickListener mTeamChatListClickListener;
private ArrayList<String> mTestMessageList;
public interface OnKeyboardVisibilityListener {
void onVisibilityChanged(boolean visible);
}
public final void setKeyboardListener(final OnKeyboardVisibilityListener listener) {
final View activityRootView = ((ViewGroup) getActivity().findViewById(android.R.id.content)).getChildAt(0);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
private boolean wasOpened;
private final int DefaultKeyboardDP = 100;
// From @nathanielwolf answer... Lollipop includes button bar in the root. Add height of button bar (48dp) to maxDiff
private final int EstimatedKeyboardDP = DefaultKeyboardDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 48 : 0);
private final Rect r = new Rect();
@Override
public void onGlobalLayout() {
// Convert the dp to pixels.
int estimatedKeyboardHeight = (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, activityRootView.getResources().getDisplayMetrics());
// Conclude whether the keyboard is shown or not.
activityRootView.getWindowVisibleDisplayFrame(r);
int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
boolean isShown = heightDiff >= estimatedKeyboardHeight;
if (isShown == wasOpened) {
Log.d("Keyboard state", "Ignoring global layout change...");
return;
}
wasOpened = isShown;
listener.onVisibilityChanged(isShown);
}
});
}
public TeamChatView() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @return A new instance of fragment TeamChatView.
*/
public static TeamChatView newInstance() {
TeamChatView fragment = new TeamChatView();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@SuppressLint("MissingSuperCall")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(TeamChatPresenter.class, TeamChatModel.class, savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_team_chat_view, container, false);
this.mUnbinder = ButterKnife.bind(this, view);
mTestMessageList = new ArrayList<>();
this.mTeamChatListAdapter = new TeamChatListAdapter(mTestMessageList);
this.mTeamChatRecyclerView.setAdapter(this.mTeamChatListAdapter);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
this.mTeamChatRecyclerView.setLayoutManager(linearLayoutManager);
this.mTeamChatSendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(!String.valueOf(mMessageTextInput.getText()).equals("")) {
getSpecificImpOfGenericPresenter().sendMessage(String.valueOf(mMessageTextInput.getText()));
mMessageTextInput.setText("");
mTeamChatRecyclerView.smoothScrollToPosition(mTestMessageList.size());
}
}
});
setKeyboardListener(new OnKeyboardVisibilityListener(){
@Override
public void onVisibilityChanged(boolean visible) {
RelativeLayout contentFrame = (RelativeLayout) getActivity().findViewById(R.id.content_company_navigation);
BottomBar lowerNavigationBar = (BottomBar) getActivity().findViewById(R.id.bottomBar);
if (visible) { // if more than 100 pixels, its probably a keyboard...
lowerNavigationBar.setVisibility(GONE);
contentFrame.setPadding(0, 0, 0, 0);
mTeamChatRecyclerView.smoothScrollToPosition(mTestMessageList.size());
} else {
contentFrame.setPadding(0, 0, 0, convertDpToPixel(60, getContext()));
mTeamChatRecyclerView.smoothScrollToPosition(mTestMessageList.size());
lowerNavigationBar.setVisibility(View.VISIBLE);
}
}
});
return view;
}
/**
* This method converts dp unit to equivalent pixels, depending on device density.
*
* @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
* @param context Context to get resources and device specific display metrics
* @return A float value to represent px equivalent to dp depending on device density
*/
public static int convertDpToPixel(float dp, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
int px = (int) (dp * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
public void addToTestMessageList(String str){
this.mTestMessageList.add(str);
this.mTeamChatListAdapter.notifyDataSetChanged();
}
@Override
public void onDestroyView() {
super.onDestroyView();
// getView().getViewTreeObserver().removeGlobalOnLayoutListener(test);
}
@Override
public TeamChatPresenter getSpecificImpOfGenericPresenter() {
return (TeamChatPresenter) this.mPresenter;
}
}
This is my XML layout:
这是我的 XML 布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="uk.cal.codename.projectnedry.TeamChatFragment.TeamChatView">
<android.support.v7.widget.RecyclerView
android:layout_above="@+id/chatViewMessageEntryLayout"
android:id="@+id/teamChatList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:isScrollContainer="false"
android:paddingTop="10dp"
android:scrollbars="vertical" />
<RelativeLayout
android:id="@+id/chatViewMessageEntryLayout"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<View
android:id="@+id/chatViewMessageEntrySeperator"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#e3e3e8" />
<EditText
android:id="@+id/messageTextInput"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_below="@+id/chatViewMessageEntrySeperator"
android:layout_toLeftOf="@+id/teamChatSendButton"
android:background="@android:color/transparent"
android:hint="Enter message"
android:inputType="textCapSentences|textMultiLine"
android:maxLength="1000"
android:maxLines="4"
android:paddingLeft="10dp" />
<ImageButton
android:id="@+id/teamChatSendButton"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_gravity="center"
android:background="#00B9EF"
android:src="@drawable/ic_send_white_24dp" />
</RelativeLayout>
</RelativeLayout>
采纳答案by Calco
I ended up using the height measuring method that seems to be the standard way of soft keyboard detection which is described in this answer. However, I used this library'simplementation of it, as it is still the same ViewTreeObserver.OnGlobalLayoutListener
method, implemented well, and allowed me to abstract the code out of my applications main codebase.
我最终使用了高度测量方法,该方法似乎是此答案中描述的软键盘检测的标准方法。但是,我使用了这个库的实现,因为它仍然是相同的ViewTreeObserver.OnGlobalLayoutListener
方法,实现得很好,并允许我从我的应用程序主代码库中提取代码。
When this keyboard visibility listener is triggered, I then hide/show the bottom navigation bar (which I have explained here).
当触发此键盘可见性侦听器时,我将隐藏/显示底部导航栏(我已在此处解释)。
回答by tahsinRupam
Add the attribute : android:windowSoftInputMode="adjustResize""
in your manifest inside activity
tag:
添加属性 :android:windowSoftInputMode="adjustResize""
在您的清单内activity
标签中:
<activity
android:name=".YourActivity"
android:windowSoftInputMode="adjustResize"/>
NB:I suggest, You should use NestedScrollView as the parent layout.
注意:我建议,您应该使用 NestedScrollView 作为父布局。
Hope this helps.
希望这可以帮助。
回答by Praveen Kumar Verma
The easiest implementation, Add AndroidManifest.xml in
最简单的实现,在AndroidManifest.xml中添加
<activity android:windowSoftInputMode="adjustPan"/>
hopefully this helps someone out. Enjoy !
希望这可以帮助某人。享受 !
回答by ajay singh
In my case, I am using DrawerLayout as a parent view with some layout content and A Navigation Bottom Bar. In Manifest file add "android:windowSoftInputMode="adjustPan" this TAG with Activity and this working fine.
就我而言,我使用 DrawerLayout 作为具有一些布局内容和导航底部栏的父视图。在清单文件中添加 "android:windowSoftInputMode="adjustPan" 这个带有 Activity 的 TAG 并且这个工作正常。
回答by Maksudul Hasan Raju
you just add this code in your manifest like this way..
您只需像这样在清单中添加此代码..
<activity android:name=".MainActivity"
android:windowSoftInputMode="adjustPan">
this works for me.. happy coding
这对我有用......快乐编码
回答by mahesh kumar
Add this line in onResume()
of your Activity
or Fragment
.
将此行添加onResume()
到您的Activity
或Fragment
.
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
It is worked for me. Just try it once.
它对我有用。只需尝试一次。
回答by Yo-sure
Just add the attribute below to every activity in your AndroidManifest.xml file.
只需将以下属性添加到 AndroidManifest.xml 文件中的每个活动。
<activity
android:name=".MainActivity"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan" />
回答by Rajnish Sharma
Add this onResume() in your fragment
在你的片段中添加这个 onResume()
@Override
public void onResume() {
Objects.requireNonNull(getActivity()).getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
super.onResume();
}
Hope this helps someone!
希望这可以帮助某人!
回答by Anushree
private boolean keyboardListenersAttached = false;
private ViewGroup rootLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_settings, container, false);
rootLayout = (ViewGroup) view.findViewById(R.id.settings_layout);
attachKeyboardListeners();
return view;
}
private ViewTreeObserver.OnGlobalLayoutListener keyboardLayoutListener = new
ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightDiff = rootLayout.getRootView().getHeight() -
rootLayout.getHeight();
if (getActivity() != null) {
int contentViewTop =
getActivity().getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
LocalBroadcastManager broadcastManager =
LocalBroadcastManager.getInstance(getContext());
Rect r = new Rect();
rootLayout.getWindowVisibleDisplayFrame(r);
int screenHeight = rootLayout.getRootView().getHeight();
// r.bottom is the position above soft keypad or device button.
// if keypad is shown, the r.bottom is smaller than that before.
int keypadHeight = screenHeight - r.bottom;
if (keypadHeight > screenHeight * 0.15) {
onHideKeyboard();
Intent intent = new Intent("KeyboardWillHide");
broadcastManager.sendBroadcast(intent);
} else {
int keyboardHeight = heightDiff - contentViewTop;
onShowKeyboard(keyboardHeight);
Intent intent = new Intent("KeyboardWillShow");
intent.putExtra("KeyboardHeight", keyboardHeight);
broadcastManager.sendBroadcast(intent);
}
}else {
}
}
};
protected void onShowKeyboard(int keyboardHeight) {
System.out.println("keyboard is shown");
dashboardActivity.bottomNavigationView.setVisibility(View.VISIBLE);
dashboardActivity.fab.setVisibility(View.VISIBLE);
}
protected void onHideKeyboard() {
System.out.println("keyboard is hide");
dashboardActivity.bottomNavigationView.setVisibility(View.INVISIBLE);
dashboardActivity.fab.setVisibility(View.INVISIBLE);
}
protected void attachKeyboardListeners() {
if (keyboardListenersAttached) {
return;
}
rootLayout.getViewTreeObserver().addOnGlobalLayoutListener(keyboardLayoutListener);
keyboardListenersAttached = true;
}
in Manifest.xml file add
在 Manifest.xml 文件中添加
<activity
android:name=".Activity.DashboardActivity"
android:windowSoftInputMode="adjustResize"
/>