bottomsheetdialogfragment - bottom fragment android
Prevenir BottomSheetDialogFragment que cubre la barra de navegaciĆ³n (6)
En BottomSheetDialogFragment
, lo único que debe hacerse es establecer el contenedor de CoordinatorLayout
fitSystemWindows
en false
.
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
(view!!.parent.parent.parent as View).fitsSystemWindows = false
}
-
view
es su diseño -
view.parent
es un FrameLayout que contiene su vista -
view.parent.parent
es elCoordinatorLayout
-
view.parent.parent.parent
es el contenedor paraCoordinatorLayout
que tiene sufitsSystemWindow
establecido entrue
de forma predeterminada.
Esto asegura que todo BottomSheetDialogFragment
se dibuja debajo de la barra de navegación. A continuación, puede configurar el fitsSystemWindows
de fitsSystemWindows
a sus propios contenedores en consecuencia.
Lo que no necesitas de las otras respuestas en particular es:
- hacky findViewById con referencia a los identificadores del sistema, que están sujetos a cambios,
- referencia a
getWindow()
ogetDialog()
, - No se puede dibujar en el lugar de la barra de navegación.
Esta solución funciona con BottomSheetDialogFragment
creado con onCreateView
, no verifiqué onCreateDialog
.
Estoy usando código realmente ingenuo para mostrar un fragmento de diálogo de la hoja inferior:
class LogoutBottomSheetFragment : BottomSheetDialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.view_image_source_chooser, container, false)
return view
}
}
Así es como llamé a este diálogo:
LogoutBottomSheetFragment().show(supportFragmentManager, "logout")
Pero me sale esto horrible que se muestra en la imagen de abajo. ¿Cómo puedo mantener en blanco la barra de navegación (la barra inferior donde se encuentran los botones de software de inicio / inicio)?
Tema de la aplicación que estoy usando:
<!-- Base application theme. -->
<style name="BaseAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
</style
<style name="AppTheme" parent="BaseAppTheme">
<item name="android:windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<!-- Main theme colors -->
<!-- your app branding color for the app bar -->
<item name="android:colorPrimary">@color/colorPrimary</item>
<!-- darker variant for the status bar and contextual app bars -->
<item name="android:colorPrimaryDark">@android:color/white</item>
<!-- theme UI controls like checkboxes and text fields -->
<item name="android:colorAccent">@color/charcoal_grey</item>
<item name="colorControlNormal">@color/charcoal_grey</item>
<item name="colorControlActivated">@color/charcoal_grey</item>
<item name="colorControlHighlight">@color/charcoal_grey</item>
<item name="android:textColorPrimary">@color/charcoal_grey</item>
<item name="android:textColor">@color/charcoal_grey</item>
<item name="android:windowBackground">@color/white</item>
</style>
También he intentado anular el setupDialog en lugar de onCreateView, pero aún sucede:
@SuppressLint("RestrictedApi")
override fun setupDialog(dialog: Dialog, style: Int) {
super.setupDialog(dialog, style)
val view = View.inflate(context, R.layout. view_image_source_chooser,null)
dialog.setContentView(view)
}
No use BottomSheetDialogFragment
. Preferiría agregar la hoja de abajo envolviendo el diseño en el diseño del coordinador y adjuntando BottomSheetBehaiviour a ese diseño
Puedes seguir this como ejemplo.
Respuesta de j2esu funciona bastante bien. Sin embargo, si insiste en la barra de navegación ''completamente blanca'', debe omitir parte de ella.
Tenga en cuenta que esta solución es aplicable desde Android O (API 26) desde que se introdujeron los iconos de la barra de navegación oscura en esta versión. En versiones anteriores obtendrías iconos blancos sobre fondo blanco.
Necesitas:
- Agregue
android:fitsSystemWindows="true"
a la raíz del diseño de su diálogo. - Modificar la
Window
de suDialog
correctamente.
Coloque este código en onStart
de su hijo de BottomSheetDialogFragment
. Si está utilizando una biblioteca de diseño en lugar de una biblioteca de materiales, use android.support.design.R.id.container
.
@Override
public void onStart() {
super.onStart();
if (getDialog() != null && getDialog().getWindow() != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Window window = getDialog().getWindow();
window.findViewById(com.google.android.material.R.id.container).setFitsSystemWindows(false);
// dark navigation bar icons
View decorView = window.getDecorView();
decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
}
}
El resultado podría verse así:
Tuve el mismo problem y finalmente encontré una solución que no es hacky o que necesita una cantidad de código orbitante.
Este método reemplazó el fondo de la ventana con un LayerDrawable que consta de dos elementos: el fondo atenuado y el fondo de la barra de navegación.
@RequiresApi(api = Build.VERSION_CODES.M)
private void setWhiteNavigationBar(@NonNull Dialog dialog) {
Window window = dialog.getWindow();
if (window != null) {
DisplayMetrics metrics = new DisplayMetrics();
window.getWindowManager().getDefaultDisplay().getMetrics(metrics);
GradientDrawable dimDrawable = new GradientDrawable();
// ...customize your dim effect here
GradientDrawable navigationBarDrawable = new GradientDrawable();
navigationBarDrawable.setShape(GradientDrawable.RECTANGLE);
navigationBarDrawable.setColor(Color.WHITE);
Drawable[] layers = {dimDrawable, navigationBarDrawable};
LayerDrawable windowBackground = new LayerDrawable(layers);
windowBackground.setLayerInsetTop(1, metrics.heightPixels);
window.setBackgroundDrawable(windowBackground);
}
}
El método "setLayerInsetTop" requiere la API 23, pero eso está bien porque los iconos oscuros de la barra de navegación se introdujeron en Android O (API 26).
Así que la última parte de la solución es llamar a este método desde sus hojas de abajo en Crear un método como este.
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setWhiteNavigationBar(dialog);
}
return dialog;
}
Espero que sea útil y, por favor, avíseme si encuentra un dispositivo o un caso en el que esta solución no funciona.
Yo tuve el mismo problema. Después de buscar en las sources , encontré una solución alternativa (un poco intrincada, pero no encontré alternativas).
public class YourDialog extends BottomSheetDialogFragment {
//your code
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new FitSystemWindowsBottomSheetDialog(getContext());
}
}
public class FitSystemWindowsBottomSheetDialog extends BottomSheetDialog {
public FitSystemWindowsBottomSheetDialog(Context context) {
super(context);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getWindow() != null && Build.VERSION.SDK_INT >= 21) {
findViewById(android.support.design.R.id.coordinator).setFitsSystemWindows(false);
findViewById(android.support.design.R.id.container).setFitsSystemWindows(false);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS |
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
}
}
Y, finalmente, no olvide agregar android: fitsSystemWindows = "true" en la raíz de la estructura de su diálogo.
Espero eso ayude.
BottomSheetDialogFragment
extiende DialogFragment
. Dentro de BottomSheetDialog está creando un diálogo dentro de onCreateDialog
public class BottomSheetDialogFragment extends AppCompatDialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new BottomSheetDialog(getContext(), getTheme());
}
}
La capa oscura es una propiedad del diálogo que se aplica a toda la ventana. Entonces solo cubrirá la barra de estado. Si necesita una capa tenue sin botones inferiores, debe hacerlo manualmente mostrando una capa dentro del diseño y cambiando el color de la barra de estado en consecuencia.
Aplicar el tema para el fragmento de diálogo como se indica a continuación
class LogoutBottomSheetFragment : BottomSheetDialogFragment() {
init {
setStyle(DialogFragment.STYLE_NORMAL,R.style.dialog);
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.view_image_source_chooser, container, false)
return view
}
}
Con estilos como
<style name="dialog" parent="Base.Theme.AppCompat.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:backgroundDimEnabled">false</item>
</style>