Держите нижний лист поверх любых страниц в masterDetailPage Xamarin - PullRequest
0 голосов
/ 11 июля 2020

Я новичок в разработке приложений с xamarin для android и ios в c#. Итак, я создал приложение для своей станции musi c, чтобы воспроизводить музыку c, и оно содержит MasterDetailPage. В левом верхнем углу находится меню для выбора различных типов страниц. Но я хочу, чтобы внизу была форма ползунка stati c bottom Sheet, где вы можете запускать или останавливать musi c, который должен отображаться все время и продолжать воспроизведение при переключении других страниц. Но я также хотел бы дать пользователю возможность сдвинуть эту конкретную форму вверх, чтобы увидеть, какая песня играет, и некоторую другую информацию. И musi c должен продолжать играть во время навигации по другим страницам. К настоящему времени мое приложение начинается с:

MainPage = new MainPage();

А в MainPage.xaml это:

<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:d="http://xamarin.com/schemas/2014/forms/design"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            mc:Ignorable="d"
            xmlns:views="clr-namespace:Test.Views"
            x:Class="Test.Views.MainPage">

    <MasterDetailPage.Master>
        <views:MenuPage />
    </MasterDetailPage.Master>

    <MasterDetailPage.Detail>
        <NavigationPage>
            <NavigationPage.Icon>
                <OnPlatform x:TypeArguments="FileImageSource">
                    <On Platform="iOS" Value="tab_feed.png"/>
                </OnPlatform>
            </NavigationPage.Icon>
            <x:Arguments>
                <views:ItemsPage />
            </x:Arguments>
        </NavigationPage>
    </MasterDetailPage.Detail>
    
</MasterDetailPage>

И затем оно вызывает MenuPage, который загружает меню и прочее.

Как лучше всего и как это сделать?

Пример

1 Ответ

0 голосов
/ 14 июля 2020

Для нижнего листа вы можете обратиться к приведенному ниже коду.

  <RelativeLayout>

    <StackLayout Padding="10,20,0,0">
        <Label Text="Page7" />
    </StackLayout>
    <Frame
        x:Name="bottomSheet"
        Padding="1,4,1,0"
        BackgroundColor="#faf9f8"
        CornerRadius="8"
        HasShadow="true"
        RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,
                                                               Property=Height,
                                                               Factor=1,
                                                               Constant=0}"
        RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,
                                                              Property=Width,
                                                              Factor=1,
                                                              Constant=0}"
        RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
                                                          Property=Height,
                                                          Factor=.9,
                                                          Constant=0}">
        <Frame.GestureRecognizers>
            <PanGestureRecognizer PanUpdated="OnPanUpdated" />
        </Frame.GestureRecognizers>
        <StackLayout Spacing="5">
            <BoxView
                BackgroundColor="Gray"
                CornerRadius="2"
                HeightRequest="5"
                HorizontalOptions="Center"
                WidthRequest="50" />
            <SearchBar
                x:Name="SearchBox"
                BackgroundColor="Transparent"
                Focused="SearchBar_Focused"
                Placeholder="Search by Ingredient"
                 />
            <StackLayout x:Name="GridFilter">
                <Button />
            </StackLayout>
        </StackLayout>
    </Frame>
</RelativeLayout>

Код позади:

public Page7()
    {
        InitializeComponent();
    }
    public double getProportionCoordinate(double proportion)
    {
        return proportion * Height;
    }

    private void SearchBar_Focused(object sender, FocusEventArgs e)
    {
        GridFilter.IsVisible = true;
        openBottomSheet();
    }
    void openBottomSheet()
    {
        var finalTranslation = Math.Max(Math.Min(0, -1000), -Math.Abs(getProportionCoordinate(.85)));
        bottomSheet.TranslateTo(bottomSheet.X, finalTranslation, 150, Easing.SpringIn);
    }
    // Important Code Lives Below
    double x, y;
    private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    {
        // Handle the pan
        switch (e.StatusType)
        {
            case GestureStatus.Running:
                // Translate and ensure we don't y + e.TotalY pan beyond the wrapped user interface element bounds.
                var translateY = Math.Max(Math.Min(0, y + e.TotalY), -Math.Abs((Height * .25) - Height));
                bottomSheet.TranslateTo(bottomSheet.X, translateY, 20);
                break;
            case GestureStatus.Completed:
                // Store the translation applied during the pan
                y = bottomSheet.TranslationY;

                //at the end of the event - snap to the closest location
                var finalTranslation = Math.Max(Math.Min(0, -1000), -Math.Abs(getClosestLockState(e.TotalY + y)));

                //depending on Swipe Up or Down - change the snapping animation
                if (isSwipeUp(e))
                {
                    bottomSheet.TranslateTo(bottomSheet.X, finalTranslation, 250, Easing.SpringIn);
                }
                else
                {
                    bottomSheet.TranslateTo(bottomSheet.X, finalTranslation, 250, Easing.SpringOut);
                }

                //dismiss the keyboard after a transition
                SearchBox.Unfocus();
                y = bottomSheet.TranslationY;

                break;

        }
    }

    public bool isSwipeUp(PanUpdatedEventArgs e)
    {
        if (e.TotalY < 0)
        {
            return true;
        }
        return false;
    }
    //TO-DO: Make this cleaner
    public double getClosestLockState(double TranslationY)
    {
        //Play with these values to adjust the locking motions - this will change depending on the amount of content ona  apge
        var lockStates = new double[] { 0, .5, .85 };

        //get the current proportion of the sheet in relation to the screen
        var distance = Math.Abs(TranslationY);
        var currentProportion = distance / Height;

        //calculate which lockstate it's the closest to
        var smallestDistance = 10000.0;
        var closestIndex = 0;
        for (var i = 0; i < lockStates.Length; i++)
        {
            var state = lockStates[i];
            var absoluteDistance = Math.Abs(state - currentProportion);
            if (absoluteDistance < smallestDistance)
            {
                smallestDistance = absoluteDistance;
                closestIndex = i;
            }
        }

        var selectedLockState = lockStates[closestIndex];
        var TranslateToLockState = getProportionCoordinate(selectedLockState);

        return TranslateToLockState;
    }

Снимок экрана:

введите описание изображения здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...