Для нижнего листа вы можете обратиться к приведенному ниже коду.
<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;
}
Снимок экрана:
введите описание изображения здесь