我正在实现一个UI,其中一个底部工作表将出现在键盘上方,并带有一个EditText,供用户输入一个值。问题是视图被键盘部分重叠,覆盖了底部的底部。
这是底部表,没有键盘。
这是底部表格,键盘显示。
确保显示整个底板的最佳方法是什么?
谢谢。
只是从这个问题Keyboard hides BottomSheetDialogFragment重新发布@jblejder,因为它对我有用,让其他人更容易找到:
我发现改变它的最方便的方法是创建样式:
<style name="DialogStyle" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowSoftInputMode">adjustResize</item>
</style>
并在BottomSheetDialogFragment的onCreate方法中设置它:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(DialogFragment.STYLE_NORMAL, R.style.DialogStyle)
}
这是它在我的设备上的外观:
dialog = new BottomSheetDialog(getContext(), R.style.BottomSheetDialog);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = d.findViewById(R.id.design_bottom_sheet);
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
},0);
}
});
这段代码在Fragment的onCreateView方法中运行正常(感谢ADM)
一个BottomSheetDialog
可以帮助这个。它将打开,软键盘打开,重点是编辑文本。但用户仍然可以关闭软键盘,对话框将重置为底部。再次聚焦将使对话框出现在Softkeyboard的顶部。
public void showDialog() {
final BottomSheetDialog dialog=new BottomSheetDialog(this);
dialog.setContentView(R.layout.item_dialog);
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
dialog.show();
}
您可以通过键盘扩展BottomSheetDialog。但为此你需要在SoftKeyboard Open之后调用它。扩展代码是。
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
我已经在DialogInterface.OnShowListener()
上测试了它,但它不起作用。测试1秒延迟其工作。但延迟不是解决方案。您需要确定应该在哪个操作上展开对话框。
final BottomSheetDialog dialog=new BottomSheetDialog(this);
dialog.setContentView(R.layout.item_dialog);
dialog.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE|
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
FrameLayout bottomSheet = (FrameLayout) dialog.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
}
},2000);
dialog.show();
为此,我发现AlertDialog
工作得最好。虽然它不会与屏幕的底部或侧面齐平,但它看起来仍然足够好。
首先,用你的视图创建AlertDialog
。
val view = LayoutInflater.from(context).inflate(R.layout.alert, null)
dialog = AlertDialog.Builder(context)
.setView(view)
.create()
接下来,设置重力。
dialog.window.attributes.gravity = Gravity.BOTTOM
最后,展示它。
dialog.show()
您还可以使用onDismissListener
绑定键盘以保持对话框。
显示AlertDialog
后,我强行键盘。
调用此方法,传入EditText
。
fun showKeyboard(view: View?) {
if (view == null) return;
val imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
并在onDismissListener
内解雇。
private fun hideKeyboard() {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
}
这可能是一个多余的答案。虽然只是指出了这个问题。如果您正在使用BottomSheetDialogFragment
,唯一的方法是启用属性android:windowIsFloating为true。这将使整个窗口位于试图占据其背后的空间的顶部。
<style name="BottomSheetDialogThemeNoFloating" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowSoftInputMode">adjustResize|stateVisible</item>
</style>
然后在对话框的onCreate()
中设置此样式。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// set the window no floating style
setStyle(DialogFragment.STYLE_NORMAL, R.style.AppRoundedBottomSheetDialogThemeNoFloating)
}
这对于那些经常使用底页并且可能想要处理互相重叠的EditText
和软键盘的人来说非常方便。
注意:mikepenz的类KeyboardUtil
存在一个问题,即在某些手机上,尽管为所提供的整个内容视图提供了底部填充,但带有输入字段的内容视图会自动推到键盘上方。
我的回答可能对仍在寻找解决方案的人有用。如果键盘覆盖了BottomSheetDialogFragment中的edittext,那么在setupDialog()
方法中创建一个类KeyboardUtil的实例并传递你的rootview。
@Override
public void setupDialog(final Dialog dialog, int style) {
super.setupDialog(dialog, style);
View view = View.inflate(getActivity(), R.layout.reopen_dialog_layout, null);
new KeyboardUtil(getActivity(), view);
}
public class KeyboardUtil {
private View decorView;
private View contentView;
//a small helper to allow showing the editText focus
ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
decorView.getWindowVisibleDisplayFrame(r);
//get screen height and calculate the difference with the useable area from the r
int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
int diff = height - r.bottom;
//if it could be a keyboard add the padding to the view
if (diff != 0) {
// if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
//check if the padding is 0 (if yes set the padding for the keyboard)
if (contentView.getPaddingBottom() != diff) {
//set the padding of the contentView for the keyboard
contentView.setPadding(0, 0, 0, diff);
}
} else {
//check if the padding is != 0 (if yes reset the padding)
if (contentView.getPaddingBottom() != 0) {
//reset the padding of the contentView
contentView.setPadding(0, 0, 0, 0);
}
}
}
};
public KeyboardUtil(Activity act, View contentView) {
this.decorView = act.getWindow().getDecorView();
this.contentView = contentView;
//only required on newer android versions. it was working on API level 19
if (Build.VERSION.SDK_INT >= 19) {
decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
/**
* Helper to hide the keyboard
*
* @param act
*/
public static void hideKeyboard(Activity act) {
if (act != null && act.getCurrentFocus() != null) {
InputMethodManager inputMethodManager = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), 0);
}
}
public void enable() {
if (Build.VERSION.SDK_INT >= 19) {
decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
public void disable() {
if (Build.VERSION.SDK_INT >= 19) {
decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
}