Как определить, когда BottomSheetDialogFragment развернут для заполнения экрана? - PullRequest
0 голосов
/ 05 июля 2019

Я пытаюсь следовать спецификации Material Design , чтобы добавить панель инструментов с ограниченным доступом к модальному нижнему листу с помощью библиотеки поддержки Android Design.

В полноэкранном режиме нижние листы можно прокручивать изнутри, чтобы показать дополнительный контент. Панель инструментов должна использоваться, чтобы обеспечить развал или закрытие для выхода из этого представления .

Я пошел с BottomSheetBehavior.BottomSheetCallback, чтобы переключить видимость панели инструментов на основе развернутого / свернутого состояния BottomSheetBehavior. Проблема в том, что панель инструментов появляется, когда я пытаюсь перетащить вверх, даже если содержимое BottomSheetDialogFragment не может заполнить весь экран. Как узнать, когда нижний лист полноэкранный, а нижний лист расширяется?

public class BottomSheetToolbarToggleCallback : BottomSheetBehavior.BottomSheetCallback
{
    public BottomSheetToolbarToggleCallback(BottomSheetDialogFragment bottomSheetDialogFragment)
    {
        this.bottomSheetDialogFragment = bottomSheetDialogFragment ?? throw new System.ArgumentNullException(nameof(bottomSheetDialogFragment));
    }

    public override void OnSlide(View bottomSheet, float slideOffset)
    {
    }

    public override void OnStateChanged(View bottomSheet, int newState)
    {
        switch (newState)
        {
            case BottomSheetBehavior.StateCollapsed:
                ShowToolbar(bottomSheet, ViewStates.Gone);
                break;
            case BottomSheetBehavior.StateExpanded:
                ShowToolbar(bottomSheet, ViewStates.Visible);
                break;
            case BottomSheetBehavior.StateHidden:
                bottomSheetDialogFragment.Dismiss();
                break;
        }
    }

    private void ShowToolbar(View bottomSheet, ViewStates viewState)
    {
        var toolbar = bottomSheet.FindViewById<Toolbar>(Resource.Id.toolbar);
        if (toolbar != null)
        {
            toolbar.Visibility = viewState;
        }
    }

    private readonly BottomSheetDialogFragment bottomSheetDialogFragment;
}
public abstract class BaseBottomSheetDialogFragment<TViewModel> : MvxBottomSheetDialogFragment<TViewModel> where TViewModel : BaseViewModel
{
    protected BaseBottomSheetDialogFragment()
    {
    }

    protected BaseBottomSheetDialogFragment(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
    {
    }

    public override void SetupDialog(Dialog dialog, int style)
    {
        base.SetupDialog(dialog, style);

        this.EnsureBindingContextIsSet(); // This is required to use this.BindingInflate()
        var view = this.BindingInflate(LayoutResourceId, null);
        dialog.SetContentView(view);

        // Add support to handle material design specification to dynamically show a toolbar with an 'X' button.
        var layoutParams = (CoordinatorLayout.LayoutParams)((View)view.Parent).LayoutParameters;
        var behavior = layoutParams.Behavior;
        if (behavior != null && behavior is BottomSheetBehavior)
        {
            var toolbar = view.FindViewById<Toolbar>(Droid.Resource.Id.toolbar);
            if (toolbar != null)
            {
                toolbar.SetNavigationIcon(Droid.Resource.Drawable.clear);
                ((BottomSheetBehavior)behavior).SetBottomSheetCallback(new BottomSheetToolbarToggleCallback(this));
                if (CloseCommand != null)
                {
                    toolbar.SetNavigationOnClickListener(new MvxAsyncCommandOnClickListener(CloseCommand));
                }
            }
        }
    }

    /// <summary>
    /// The Android layout resource id of the layout to show in the modal bottom sheet.
    /// </summary>
    protected abstract int LayoutResourceId { get; }

    /// <summary>
    /// Optional <see cref="MvxAsyncCommand"/> to call when the optional toolbar navigation button is clicked.
    /// </summary>
    protected abstract IMvxAsyncCommand CloseCommand { get; }
}

Ответы [ 2 ]

1 голос
/ 10 июля 2019

Поскольку я не знаю ваш конкретный код, вот фрагмент простого примера, который я пробовал:

public View mView;

public override void SetupDialog(Dialog dialog, int style)
{
    base.SetupDialog(dialog, style);

    this.EnsureBindingContextIsSet(); // This is required to use this.BindingInflate()
    mView = this.BindingInflate(LayoutResourceId, null);
    dialog.SetContentView(view);
        ...        
}

в BottomSheetCallback:

public override void OnStateChanged(View bottomSheet, int newState)
        {
            switch (newState)
            {          
                case BottomSheetBehavior.StateExpanded:
                   var height = bottomSheetDialogFragment.mView.Height;//need you convert to your BottomSheetDialogFragment
                    break;              
            }
        }
0 голосов
/ 16 июля 2019

Это решение, которое я использовал в итоге.Это только покажет близкую доступность, если BottomSheetDialogFragment займет всю высоту окна.Он был протестирован с многооконным режимом, вырезами / вставками, альбомной и портретной ориентацией.

public class BottomSheetDialogFragmentCloseAffordanceCallback : BottomSheetBehavior.BottomSheetCallback
{
    public BottomSheetDialogFragmentCloseAffordanceCallback(BottomSheetDialogFragment bottomSheetDialogFragment)
    {
        this.bottomSheetDialogFragment = bottomSheetDialogFragment ?? throw new System.ArgumentNullException(nameof(bottomSheetDialogFragment));
    }

    public override void OnSlide(View bottomSheet, float slideOffset)
    {
    }

    public override void OnStateChanged(View bottomSheet, int newState)
    {
        switch (newState)
        {
            case BottomSheetBehavior.StateCollapsed:
                ShowToolbar(bottomSheet, ViewStates.Gone);
                break;
            case BottomSheetBehavior.StateExpanded:
                if (IsViewSameHeightAsWindow(bottomSheet))
                {
                    ShowToolbar(bottomSheet, ViewStates.Visible);
                }
                break;
            case BottomSheetBehavior.StateHalfExpanded:
                break;
            case BottomSheetBehavior.StateHidden:
                bottomSheetDialogFragment.Dismiss();
                break;
        }
    }

    private void ShowToolbar(View bottomSheet, ViewStates viewState)
    {
        var toolbar = bottomSheet.FindViewById<Toolbar>(Resource.Id.toolbar);
        if (toolbar != null)
        {
            toolbar.Visibility = viewState;
        }
    }

    private bool IsViewSameHeightAsWindow(View view)
    {
        int[] locationInWindow = new int[2];
        view.GetLocationInWindow(locationInWindow);
        return locationInWindow[1] == view.RootWindowInsets.StableInsetTop;
    }

    private readonly BottomSheetDialogFragment bottomSheetDialogFragment;
}
...