J'essaie d'afficher un BottomSheetDialogFragment
avec quelques champs EditText
pour que l'utilisateur entre des informations. Je veux le montrer directement au-dessus du clavier, mais il continue de couvrir le contenu.
C'est ce qui se passe lorsque j'affiche le BottomSheetDialogFragment
, vous pouvez voir qu'il sélectionne Card Number
EditText
, mais couvrant l'autre contenu.
Idéalement, c'est ce que je recherche, vous pouvez voir à la fois EditTexts
et le remplissage de la vue.
J'ai essayé beaucoup de solutions autour de windowSoftInputMode
, mais rien ne semble fonctionner. Je l'ai défini sur adjustResize
pour le parent Activity
et le réel BottomSheetDialogFragment
via
dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
Et j'ai également essayé de modifier ma mise en page, en la changeant de FrameLayout
, en ScrollView
en CoordinatorLayout
pour voir si cela a eu un effet sur la position de la mise en page , mais rien ne semble fonctionner.
Si quelqu'un sait comment y parvenir, ce serait grandement apprécié, merci.
Peut-être une réponse tardive mais aiderait probablement.
Rien d'autre n'a fonctionné pour moi. Mais cette solution fonctionne
Styles intérieurs:
<style> // main theme
<item name="bottomSheetDialogTheme">@style/BottomSheetDialogTheme</item>
........ // rest of the code
</style>
<style name="BottomSheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
<item name="bottomSheetStyle">@style/AppModalStyle</item>
<item name="Android:windowIsFloating">false</item>
<item name="Android:windowSoftInputMode">adjustResize</item>
<item name="Android:statusBarColor">@Android:color/transparent</item>
</style>
Ici Android:windowIsFloating
devrait être faux & Android:windowSoftInputMode
doit être adjustResize
<style name="AppModalStyle" parent="Widget.Design.BottomSheet.Modal">
<item name="Android:background">@drawable/rounded_corner_dialog</item>
</style>
Envelopper la mise en page dans NestedScrollView
<androidx.core.widget.NestedScrollView
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<--Rest of the layout-->
</androidx.core.widget.NestedScrollView>
Sur certains appareils, cette solution n'était pas suffisante. L'ajout de cela au code a résolu mon problème complètement.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dialog?.setOnShowListener {
val dialog = it as BottomSheetDialog
val bottomSheet = dialog.findViewById<View>(R.id.design_bottom_sheet)
bottomSheet?.let { sheet ->
dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
sheet.parent.parent.requestLayout()
}
}
}
Essayez ce BottomSheetDialogFragment:
import Android.graphics.Rect;
import Android.os.Bundle;
import Android.support.annotation.NonNull;
import Android.support.annotation.Nullable;
import Android.support.design.widget.BottomSheetBehavior;
import Android.support.design.widget.BottomSheetDialog;
import Android.support.design.widget.BottomSheetDialogFragment;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.view.WindowManager;
public class TestBottomSheetDialog extends BottomSheetDialogFragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View fragmentView = LayoutInflater.from(getContext()).inflate(R.layout.fragment_bottom_sheet, container, false);
if (getDialog().getWindow() != null) {
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
}
if (getActivity() != null) {
View decorView = getActivity().getWindow().getDecorView();
decorView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
Rect displayFrame = new Rect();
decorView.getWindowVisibleDisplayFrame(displayFrame);
int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
int heightDifference = height - displayFrame.bottom;
if (heightDifference != 0) {
if (fragmentView.getPaddingBottom() != heightDifference) {
fragmentView.setPadding(0, 0, 0, heightDifference);
}
} else {
if (fragmentView.getPaddingBottom() != 0) {
fragmentView.setPadding(0, 0, 0, 0);
}
}
});
}
getDialog().setOnShowListener(dialog -> {
BottomSheetDialog d = (BottomSheetDialog) dialog;
View bottomSheetInternal = d.findViewById(Android.support.design.R.id.design_bottom_sheet);
if (bottomSheetInternal == null) return;
BottomSheetBehavior.from(bottomSheetInternal).setState(BottomSheetBehavior.STATE_EXPANDED);
});
return fragmentView;
}
}
Cette étape suivante peut être utile pour résoudre vos problèmes.
Ajoutez d'abord la ligne suivante sur votre EditText dans un fichier xml
Android:imeOptions="actionSend|flagNoEnterAction"
Par exemple:
<EditText
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:inputType="number"
Android:hint="Card number"
Android:imeOptions="actionSend|flagNoEnterAction"/>
Ajoutez ensuite la ligne suivante sur la balise d'activité dans le fichier AndroidManifest.xml
Android:windowSoftInputMode="stateVisible|adjustResize"
Par exemple:
<activity Android:name=".stack.MainActivity"
Android:windowSoftInputMode="stateVisible|adjustResize">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
vous pouvez trouver plus de détails sur la méthode de saisie à l'écran dans ici .
J'ai finalement changé la hauteur de la boîte de dialogue lorsque le clavier est ouvert et je l'ai redimensionné à la normale lorsqu'il se ferme.
Bibliothèque KeyboardVisibilityEvent: https://Android-arsenal.com/details/1/2519
KeyboardVisibilityEvent.setEventListener(activity) { isOpen ->
setDialogHeight(isOpen)
}
La version minimale du SDK est 14 pour 2.0.0
Et définissez la hauteur de la boîte de dialogue à 80% lorsque le clavier s'ouvre:
/**
* Changes size of dialog based on keyboard visibility state
*/
private fun setDialogHeight(expanded: Boolean) {
val dialog = dialog as BottomSheetDialog?
val bottomSheet =
dialog!!.findViewById<View>(com.google.Android.material.R.id.design_bottom_sheet) as FrameLayout?
val behavior = BottomSheetBehavior.from(bottomSheet!!)
val displayMetrics = activity!!.resources.displayMetrics
val width = displayMetrics.widthPixels
val height = displayMetrics.heightPixels
val maxHeight = (height * 0.88).toInt()
behavior.peekHeight = if (expanded) maxHeight else -1
}
J'ai dû agrandir une hauteur de mise en page. Une méthode de programmation de Comment changer la hauteur par défaut du fragment de dialogue de feuille de fond? n'a pas aidé, j'ai donc simplement changé la disposition.
<Android.support.constraint.ConstraintLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
>
<View
Android:id="@+id/top_space"
Android:layout_width="match_parent"
Android:layout_height="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<!-- Other views -->
<View
Android:id="@+id/bottom_space"
Android:layout_width="match_parent"
Android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button"
app:layout_constraintVertical_weight="1"
/>
</Android.support.constraint.ConstraintLayout>
L'ajout de rembourrage au clavier virtuel n'est pas pris en charge par le système d'exploitation Android lui-même, mais il existe des moyens hacky de l'avoir.
Une façon serait d'écouter le focus de l'edittext et de faire défiler le ScrollView un peu plus comme ceci:
edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
scrollView.scrollBy(0, 100);
});
Comme je l'ai dit, cette méthode est hacky et déconseillée.
Une autre façon (qui dépend de votre mise en page et est préférable si vous le faites fonctionner) serait de définir windowSoftInputMode
sur adjustPan
ou adjustResize
(selon votre mise en page) pour votre activité dans AndroidManifest.xml.