listviewxamarinxamarin.formsstacklayout

Slide stacklayout according to listview scroll.- Xamarin.forms


In my Xamarin.Forms app, I have a StackLayout and ListView.

I want to hide/show this StackLayout depending on the ListView scrolling direction:

If the user scrolls down -> slide up the StackLayout and hide.

If the user scrolls up -> slide down the StackLayout and show.

What I have done is subscribe to OnAppearing event of ListView.

ObservableCollection<DistrictData> DistrictDatas = new ObservableCollection<DistrictData>();
int lastItemIndex;
int currentItemIndex;
private void FirstListview_ItemAppearing(object sender, ItemVisibilityEventArgs e)
{
    DistrictData item = e.Item as DistrictData;

    currentItemIndex = DistrictDatas.IndexOf(item);
    if (currentItemIndex > lastItemIndex)
    {
        SelectAllLayout.TranslationY -= 30;
        SelectAllLayout.IsVisible = false;
    }
    else
    {
        SelectAllLayout.TranslationY = 0;
        SelectAllLayout.IsVisible = true;
    }
    lastItemIndex = currentItemIndex;
}

My Xmal

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage  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"
             xmlns:touch="clr-namespace:TouchEffect;assembly=TouchEffect"
             xmlns:controls="clr-namespace:SampleApp.CustomRender"
             mc:Ignorable="d"             
             x:Class="SampleApp.Views.Notification_Center.Add_New_Notification.Districts">
    <ContentPage.Content>
        <Grid>

            <Grid BackgroundColor="#076c9c">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>                  
                </Grid.RowDefinitions>
                <Grid x:Name="SelectAllLayout" Grid.Row="0" Margin="10,10,10,0">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>

                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>

                        <BoxView Grid.Row="0" Grid.Column="0" VerticalOptions="Center" HorizontalOptions="FillAndExpand" BackgroundColor="LightBlue" HeightRequest="0.1"></BoxView>

                        <Frame Grid.Row="0" HasShadow="False" BackgroundColor="White" Padding="7" CornerRadius="20" Grid.Column="1">
                            <Label Text="Step 1" FontSize="Micro" TextColor="Black" HorizontalOptions="Center" VerticalOptions="Center" Margin="10,0,10,0">
                                <Label.FontFamily>
                                    <OnPlatform x:TypeArguments="x:String">
                                        <On Platform="iOS" Value="Montserrat-Regular" />
                                        <On Platform="Android" Value="Montserrat-Regular.ttf#Montserrat-Regular" />
                                    </OnPlatform>
                                </Label.FontFamily>
                            </Label>
                        </Frame>
                        <BoxView Grid.Row="0" VerticalOptions="Center" Grid.Column="2" HorizontalOptions="FillAndExpand" BackgroundColor="LightBlue" HeightRequest="0.1"></BoxView>
                        <StackLayout  Grid.Row="1" HorizontalOptions="StartAndExpand" Orientation="Horizontal" Margin="12,0,0,0">
                            <CheckBox IsChecked="False" HorizontalOptions="Start" VerticalOptions="Center" Color="LightGreen"></CheckBox>
                            <Label Text="Select All" FontSize="Small" TextColor="White" HorizontalOptions="Start" VerticalOptions="Center" Margin="10,0,0,0">
                                <Label.FontFamily>
                                    <OnPlatform x:TypeArguments="x:String">
                                        <On Platform="iOS" Value="Montserrat-Regular" />
                                        <On Platform="Android" Value="Montserrat-Regular.ttf#Montserrat-Regular" />
                                    </OnPlatform>
                                </Label.FontFamily>
                            </Label>
                        </StackLayout>
                    </Grid>                      
                <StackLayout  VerticalOptions="Center" Grid.Row="1"   x:Name="ListLayout"  BackgroundColor="Transparent" 
                         RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
                         RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}">

            <ListView 
             x:Name="FirstListview"
             HasUnevenRows="True"                 
             HeightRequest="{Binding Path=Height, Source={x:Reference ListLayout}}"  
             CachingStrategy="RecycleElement"
             HorizontalOptions="FillAndExpand"                 
             BackgroundColor="Transparent"      
             ItemAppearing="FirstListview_ItemAppearing"
             ItemTapped="DistrictList_ItemTapped"
             VerticalOptions="FillAndExpand"  
             Margin="7,7,7,0"       
             SeparatorVisibility="None">
                        <ListView.ItemTemplate >
                            <DataTemplate >
                                <ViewCell >
                                    <ViewCell.View>
                                        <Frame HorizontalOptions="FillAndExpand"                                                                                 
                                           BorderColor="#4088CCF1" BackgroundColor="#4088CCF1"
                                                       Padding="10"
                                           Margin="3"
                                           CornerRadius="6">
                                            <Frame.HasShadow>
                                                <OnPlatform x:TypeArguments="x:Boolean" iOS="false" Android="true"/>
                                            </Frame.HasShadow>
                                            <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
                                                <CheckBox HorizontalOptions="Start" IsChecked="{Binding Selected}" Color="LightBlue" Margin="2,-6,0,0" VerticalOptions="Start"></CheckBox>
                                                <StackLayout Orientation="Vertical" VerticalOptions="StartAndExpand" >
                                                    <Label Text="District Name" FontSize="Micro" TextColor="LightBlue" Margin="10,0,0,0"></Label>
                                                    <Label Text="{Binding Heading}" VerticalOptions="Center" FontSize="12" HorizontalTextAlignment="Start" TextColor="White" Margin="10,5,5,5">
                                                        <Label.FontFamily>
                                                            <OnPlatform x:TypeArguments="x:String">
                                                                <On Platform="iOS" Value="Montserrat-Regular" />
                                                                <On Platform="Android" Value="Montserrat-Regular.ttf#Montserrat-Regular" />
                                                            </OnPlatform>
                                                        </Label.FontFamily>
                                                    </Label>
                                                </StackLayout>
                                                <Image Source="NC_rightarrow.png" HorizontalOptions="EndAndExpand" HeightRequest="15"  Margin="0,0,7,0" VerticalOptions="Center"></Image>
                                            </StackLayout>
                                        </Frame>
                                    </ViewCell.View>
                                </ViewCell>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </StackLayout>
            </Grid>        
        </Grid>
    </ContentPage.Content>  
</ContentPage>

But it doesn't work as I intended.When We scroll, the layout shows and hide randomly. How to solve this? I referred this question Link. But no luck.


Solution

  • Well I must say that there is nothing wrong with your code except that you are constantly hitting visual element with updated values, and this in my opinion causes flickering. I was able to remove flickering by implementing viewmodel and reducing hits on grid. This was partial success because grid height binding was fired properly all the time, but grid itself seems to have problems with updating height when scrolling listview. In your case (in my opinion) the best solution is to use absolute layout as additional user menu. It works fine without causing described problems. You can find working basic example here.