Forum Xamarin.Forms

Customize ListView

FlorianKrieglFlorianKriegl ATMember ✭✭✭

Hey,

I want to create a custom cell which should describe a transaction (like a banking app). The transactions should be group by there date.
The cell should look like the one in the attached photo.

My question is, is this possible with Xamarin.Forms?

I could create a cell with space between them using the DataTemplate for the ListView but there are two other major problems:
- How can I customize the grouping header (Label and Background) from the ListView?
- How can I change the selected background to only apply on my custom frame (not the entire cell, because I use space between them by "actual" cell
is a view inside the cell with margins around them)?

Is it better to use a Scroll view with custom views like cards for this? What is the performance of a ScrollView is like when there are many cells/views in there?

I have searched a lot but don't find anyone who is using such cells...

Thanks for your help!!

Flo

Best Answer

Answers

  • FlorianKrieglFlorianKriegl ATMember ✭✭✭

    Thanks for your Answer!

    LIstView already scrolls. Try to not wrap it in a ScrollView or the gestures get confused as to where to target.

    I meant to use a Scroll View instead of a ListView. So I would create a view representing a cell and then use it with a ScrollView.

    How should this tutorial help me?

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    ScrollView isn't bindable to a collection. well... If you're in XF 3.6 or later you can add a bindablelayout to about anything.
    I prefer the FlexLayout because that has wrap features.

    I just did an example of that on this thread.
    https://forums.xamarin.com/discussion/comment/375536#Comment_375536

    The tutorial series does a lot with binding to ListVIew and making ItemTemplates

  • FlorianKrieglFlorianKriegl ATMember ✭✭✭
    edited May 2019

    Hey,

    I have just a few questions about the custom list view cells you helped me recently. I have implemented a grid in the XAML file and the layout itself looks ok but something with the selected Background and the shadow does not work, maybe you could help me again.

    As you can see in the attached image the selected background is the "complete" cell and not the content within the border. How do I achieve that the only the view inside the border would be selected?

    The second problem is the one with the shadow. I just want the drop shadow to be on the outside of the border and not on every element within the cell.

    Here is my code for this View:

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
                 x:Class="PowerShare.Views.DashboardScreen"
                 xmlns:controls="clr-namespace:PowerShare.Controls"
                 xmlns:microcharts="clr-namespace:Microcharts.Forms;assembly=Microcharts.Forms"
                 xmlns:mvvm="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
                 mvvm:ViewModelLocator.AutowireViewModel="True"
                 NavigationPage.HasNavigationBar="false"
                 Title="Dashboard">
    
        <ContentPage.Resources>
            <Color x:Key="Green">#6FCF97</Color>
            <Color x:Key="DeeperGreen">#58A578</Color>
        </ContentPage.Resources>
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <StackLayout x:Name="stacker" VerticalOptions="Start" 
                                   HorizontalOptions="FillAndExpand" 
                                   Orientation="Vertical"          
                                   Padding="20,40,20,15" BackgroundColor="{StaticResource Green}"
                                   Grid.Row="0">
                <StackLayout Orientation="Horizontal">
                    <ImageButton HorizontalOptions="Center" VerticalOptions="Center" 
                                 HeightRequest="34" WidthRequest="34" 
                                 CornerRadius="17">
                    <Image.Source>
                            <OnPlatform x:TypeArguments="ImageSource"
                                        iOS ="Images/me.png"
                                        Android="SoftwareShareBackground"/>
                        </Image.Source>
                    </ImageButton>
    
                    <Label Text="Dashboard"
                       FontSize="38" FontAttributes="Bold" TextColor="White" 
                       VerticalOptions="Center"
                       HorizontalOptions="StartAndExpand"/>
                </StackLayout>
    
    
            </StackLayout>
    
            <controls:StatControl x:Name="stat" Grid.Row="1"
                                      VerticalOptions="Center" HorizontalOptions="Center"
                                      Margin="0,10,0,0"
                                      Value="{Binding Value}"
                                      Date="{Binding Date}"
                                      ValueType="{Binding ValueType, Mode=OneWay}"/>
    
    
            <ListView x:Name="listView" CachingStrategy="RecycleElement"
                      ItemsSource="{Binding Transactions}"
                      Grid.Row="2"
                      HasUnevenRows="true"
                      SeparatorVisibility="None">
                      <ListView.ItemTemplate>
                          <DataTemplate>
                            <ViewCell>
                            <Frame BorderColor="Gray" Margin="10">
                                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="20"></RowDefinition>
                        <RowDefinition Height="20"></RowDefinition>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                        <ColumnDefinition Width="40"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
    
                    <Label Grid.Row="0" Grid.Column="0" Text="{Binding Group}" LineBreakMode="TailTruncation"></Label>
                    <Label Grid.Row="1" Grid.Column="0" Text="test" Font="Small"  TextColor="Gray" LineBreakMode="TailTruncation"></Label>
                    <Image Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Source="Images/family.png" Aspect="AspectFill"/>
                </Grid>
                                </Frame>
                            </ViewCell>
                          </DataTemplate>
                      </ListView.ItemTemplate>
            </ListView>
    
        </Grid>
    </ContentPage>
    

    I have just found an example of how it exactly should look like:

    The example above is written for XF but it costs about 300$ per App...

    Do have some hints for me. Or even know the solution to these problems?

    THANKS!

    Flo

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Are you able to edit your post? The site tried to render your markup so a lot of your XAML is lost.
    You need to tag it with markdown syntax.
    https://redpillxamarin.com/2016/12/13/faq-frequently-asked-questions/

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Looks like your content is all within a Frame. So... you should be able to change the backgroundcolor of the frame based on whether or not the element IsSelected. Probably through a DataTrigger. When IsSelected becomes true the frame changes its BackgroundColor to PaleBlue or whatever.

  • FlorianKrieglFlorianKriegl ATMember ✭✭✭

    Do you maybe have an example of such a trigger?

    Would you rather do it with native implementations (the cell itself)

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    I don't go native if I don't have to. For this, no reason. That way all the work is in one place at the agnostic layer. Why do 3 times the work?
    This is a Grid binding IsVisible based on IsAdminLoggedIn.
    You'd have a Frame binding BackgroundColor based on IsSelected
    Same only different.

    <Grid>
    ...
                <Grid.Triggers>
                    <DataTrigger Binding="{Binding IsAdminLoggedIn}"
                                 TargetType="{x:Type Grid}"
                                 Value="True">
                        <Setter Property="IsVisible" Value="True" />
                    </DataTrigger>
                </Grid.Triggers>
    ...
    </Grid>
    
  • FlorianKrieglFlorianKriegl ATMember ✭✭✭

    Thanks for your example know I know what you are meaning.

    I have now tried it the following way:

    <ListView x:Name="listView" CachingStrategy="RecycleElement"
                      ItemsSource="{Binding Transactions}"
                      Grid.Row="2"
                      HasUnevenRows="true"
                      SeparatorVisibility="None">
                <ListView.Behaviors>
                    <b:EventToCommandBehavior EventName="ItemTapped"
                                              Command="{Binding OnItemTappedCommand}"
                                              EventArgsConverter="{converters:ItemTappedEventArgsConverter}"/>
                </ListView.Behaviors>
                      <ListView.ItemTemplate>
                          <DataTemplate>
                            <ViewCell>
                                <Frame BorderColor="White" Margin="10">
                                    <Frame.Triggers>
                                        <DataTrigger Binding="{Binding IsSelected}" TargetType="{x:Type Frame}" Value="True">
                                            <Setter Property="BackgroundColor" Value="Green"/>
                                        </DataTrigger>
                                    </Frame.Triggers>
                                    <Grid>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="20"></RowDefinition>
                                            <RowDefinition Height="20"></RowDefinition>
                                        </Grid.RowDefinitions>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*"></ColumnDefinition>
                                            <ColumnDefinition Width="40"></ColumnDefinition>
                                        </Grid.ColumnDefinitions>
    
                                        <Label Grid.Row="0" Grid.Column="0" Text="{Binding Group}" LineBreakMode="TailTruncation"></Label>
                                        <Label Grid.Row="1" Grid.Column="0" Text="test" Font="Small"  TextColor="Gray" LineBreakMode="TailTruncation"></Label>
                                        <Image Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Source="Images/family.png" Aspect="AspectFill"/>
                                    </Grid>
                                </Frame>
                            </ViewCell>
                          </DataTemplate>
                      </ListView.ItemTemplate>
            </ListView>
    

    And in the tapped command from the view model I do the following:

    public void Tapped(object e)
            {
                if (!((Transaction)e).IsSelected)
                {
                    ((Transaction)e).IsSelected = true;
                }
                else
                {
                    ((Transaction)e).IsSelected = false;
                }
            }
    

    But when I now tap on a cell nothing happens..
    And if I'm honest even if I understand how it should change the background color of the frame I don't understand how it should prevent from selecting the entire cell...

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    You can change the selection mode of your listview to None.

    That prevents having the normal selection, letting you use Clint's approach to the frame background.

  • FlorianKrieglFlorianKriegl ATMember ✭✭✭

    You can change the selection mode of your listview to None.

    This doesn't solve the problem, the cell does not stay selected but the complete cell flickers and you can see the selection for a short time.

    At the moment I think there is no way to create a ListView in XF with such card elements that I posted above.

  • princess2wilsonprincess2wilson Member

    @FlorianKriegl said:
    Hey,

    I want to create a custom cell which should describe a transaction (like a banking app). The transactions should be group by there date.
    The cell should look like the one in the attached photo.

    Does anyone have code for this exact design or something similar ? the way the date is displayed is what I'm really looking for!
    Any help is greatly appreciated!

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @princess2wilson said:

    Does anyone have code for this exact design or something similar ? the way the date is displayed is what I'm really looking for!
    Any help is greatly appreciated!

    HELP we are all happy to give. But nobody is going to just do your layout for you. We'll help you to become a developer but won't help you be too lazy to do your own work.

    If you want to make use of the advice above. The code techniques above. Make an effort to at least get something working using your own skills... Then post if you have specific problems you need help with.

  • @ClintStLaurent said:

    @princess2wilson said:

    Does anyone have code for this exact design or something similar ? the way the date is displayed is what I'm really looking for!
    Any help is greatly appreciated!

    HELP we are all happy to give. But nobody is going to just do your layout for you. We'll help you to become a developer but won't help you be too lazy to do your own work.

    If you want to make use of the advice above. The code techniques above. Make an effort to at least get something working using your own skills... Then post if you have specific problems you need help with.

    Can you give an example?

Sign In or Register to comment.