I am creating a Horizontal scroll in NS. When using below code it's working as expected.
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="onPageLoad" class="page">
<StackLayout>
<!-- This is where the magic happens -->
<ScrollView orientation="horizontal">
<StackLayout orientation="horizontal" class="scroll-menu">
<StackLayout class="scroll-pane">
<Button text="Button" />
</StackLayout>
<StackLayout class="scroll-pane">
<Button text="Button" />
</StackLayout>
<StackLayout class="scroll-pane">
<Button text="Button" />
</StackLayout>
<StackLayout class="scroll-pane">
<Button text="Button" />
</StackLayout>
</StackLayout>
</ScrollView>
</StackLayout>
Horizontal Scroll:
But, Once I am using the Repeater it's changing to orientation with Vertical and not scrolling.
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="onPageLoad" class="page">
<StackLayout>
<!-- This is where the magic happens -->
<ScrollView orientation="horizontal">
<StackLayout orientation="horizontal" class="scroll-menu">
<Repeater items="{{ categories }}" >
<Repeater.itemTemplate>
<StackLayout class="scroll-pane" >
<Label text="{{name}}" />
</StackLayout>
</Repeater.itemTemplate>
</Repeater>
</StackLayout>
</ScrollView>
</StackLayout>
Change to Vertical when use of Repeater:
What's wrong with the code?
Related
In Xamarin.Android it has a class named ViewPager to support "Gestural navigation allows the user to swipe left and right to step through pages of data." (https://learn.microsoft.com/en-us/xamarin/android/user-interface/controls/view-pager/)
But my task is write cross-platform codes for both Android & iOS (without rewrite new code for this gesture). With Xamarin.Form does any library support this ? I have read about Xamarin.Form carousel, but it seem used for slideshow, not appropriate for news list.
I think TabbedPage is more suitable for you. tabbedPage support the Gestural navigation allows the user to swipe left and right to step through pages of data, just set the different pages of data in different tabs.
Here is running GIF.
You can add this Tabbedpage like following code.
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TabbedPageDemo;assembly=TabbedPageDemo"
x:Class="TabbedPageDemo.TabbedPageDemoPage">
<TabbedPage.Resources>
<ResourceDictionary>
<local:NonNullToBooleanConverter x:Key="booleanConverter" />
</ResourceDictionary>
</TabbedPage.Resources>
<TabbedPage.ItemTemplate>
<DataTemplate>
<ContentPage Title="{Binding Name}" Icon="monkeyicon.png">
<StackLayout Padding="5, 25">
<Label Text="{Binding Name}"
Font="Bold,Large"
HorizontalOptions="Center" />
<Image Source="{Binding PhotoUrl}"
WidthRequest="200"
HeightRequest="200" />
<StackLayout Padding="50, 10">
<StackLayout Orientation="Horizontal">
<Label Text="Family:"
HorizontalOptions="FillAndExpand" />
<Label Text="{Binding Family}"
Font="Bold,Medium" />
</StackLayout>
<StackLayout Orientation="Horizontal"
IsVisible="{Binding Subfamily,
Converter={StaticResource booleanConverter}}">
<Label Text="Subfamily:"
HorizontalOptions="FillAndExpand" />
<Label Text="{Binding Subfamily}"
Font="Bold,Medium" />
</StackLayout>
<StackLayout Orientation="Horizontal"
IsVisible="{Binding Tribe,
Converter={StaticResource booleanConverter}}">
<Label Text="Tribe:"
HorizontalOptions="FillAndExpand" />
<Label Text="{Binding Tribe}"
Font="Bold,Medium" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Genus:"
HorizontalOptions="FillAndExpand" />
<Label Text="{Binding Genus}"
Font="Bold,Medium" />
</StackLayout>
</StackLayout>
</StackLayout>
</ContentPage>
</DataTemplate>
</TabbedPage.ItemTemplate>
</TabbedPage>
You can add different ItemTemplate in the Tabbedpage.
Here is a related link.
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/navigation/tabbed-page
Update: you can add the listview in the tabbpage like following GIF.
I have little difficult problem for me with ListView.
1) I have this graphics https://ibb.co/j6wdk71
2) I have done it but with *ngFor’s
<ActionBarLogo (myEvent)="onDrawerButtonTap($event)"></ActionBarLogo>
<RadSideDrawer #drawer showOverNavigation="false" gesturesEnabled="{{android}}" [drawerTransition]="sideDrawerTransition">
<StackLayout tkDrawerContent class="drawer">
<MyDrawer [selectedPage]="'Home'"></MyDrawer>
</StackLayout>
<GridLayout rows="*, auto" class="page page-content" tkMainContent>
<StackLayout class="fade-in" row="0" orientation="vertical" *ngIf="loading==false && network_error==false">
<StackLayout>
<PullToRefresh (refresh)="refreshList($event)">
<ScrollView orientation="vertical">
<StackLayout>
<StackLayout>
<ScrollView orientation="horizontal" scrollBarIndicatorVisible="false">
<StackLayout orientation="horizontal" class="games">
<StackLayout class="game" width="{{screen_width}}" *ngFor="let game of games">
<StackLayout class="game-inner">
<StackLayout class="game-date">
<Label text="{{game.league}}, {{game.round}}. kolo" class="game-round"></Label>
<Label text="{{ game.date | format_date }}" class="game-date-text"></Label>
</StackLayout>
<StackLayout class="game-data">
<FlexboxLayout flexDirection="row">
<StackLayout flexGrow="1" class="game-team">
<WebImage src="{{game.team_home.logo}}" height="40" class="game-team-logo"></WebImage>
<Label text="{{game.team_home.name}}" textWrap="true" class="game-team-name"></Label>
</StackLayout>
<StackLayout flexGrow="1" class="game-score">
<Label class="game-score-inner" text="-:-" textWrap="true" *ngIf="game.score==null"></Label>
<Label class="game-score-inner" text="{{game.score}}" textWrap="true" *ngIf="game.score!=null"></Label>
</StackLayout>
<StackLayout flexGrow="1" class="game-team">
<WebImage src="{{game.team_away.logo}}" height="40" class="game-team-logo"></WebImage>
<Label text="{{game.team_away.name}}" textWrap="true" class="game-team-name"></Label>
</StackLayout>
</FlexboxLayout>
</StackLayout>
<StackLayout class="game-button" orientation="horizontal" horizontalAlignment="center" [nsRouterLink]="['/game', game.id]"
pageTransition="flip">
<WebImage src="~/assets/menu_icons/matches.png" width="15"></WebImage>
<Label text="informácie o zápase" class="game-button-btn"></Label>
</StackLayout>
</StackLayout>
</StackLayout>
</StackLayout>
</ScrollView>
</StackLayout>
<StackLayout>
<StackLayout class="hp-partners">
<StackLayout class="hp-partners-heading">
<Label text="Partneri klubu"></Label>
</StackLayout>
<FlexboxLayout flexDirection="row">
<StackLayout class="partner" *ngFor="let partner of partners">
<WebImage src="{{partner.img_url}}" stretch="aspectFit" width="100%" class="partner-image" (tap)="open_url(partner.url)"></WebImage>
</StackLayout>
</FlexboxLayout>
</StackLayout>
<StackLayout class="articles-list">
<StackLayout class="article" [nsRouterLink]="['/article', article.id]" pageTransition="slideLeft" *ngFor="let article of articles, let i=index">
<StackLayout class="article-photo">
<WebImage src="{{article.photo}}" stretch="aspectFill" placeholder="~/assets/placeholder.png" class="article-photo-image"></WebImage>
</StackLayout>
<StackLayout class="article-body">
<StackLayout class="article-data">
<FlexboxLayout flexDirection="row">
<StackLayout class="article-date" orientation="horizontal">
<WebImage src="~/assets/menu_icons/date.png" class="article-date-ico"></WebImage>
<Label text="{{ article.date | format_date }}" class="article-date-text"></Label>
</StackLayout>
<StackLayout class="article-sticker" orientation="horizontal">
<WebImage src="~/assets/menu_icons/tag.png" class="article-sticker-ico"></WebImage>
<Label text="{{article.category}}" class="article-sticker-text"></Label>
</StackLayout>
<StackLayout class="article-stickers" flexGrow="1" orientation="horizontal">
<WebImage src="~/assets/article_stickers/text.png" class="article-stickers-image" *ngIf="article.sticker_text==true"></WebImage>
<WebImage src="~/assets/article_stickers/video.png" class="article-stickers-image" *ngIf="article.sticker_video==true"></WebImage>
<WebImage src="~/assets/article_stickers/photo.png" class="article-stickers-image" *ngIf="article.sticker_photogallery==true"></WebImage>
</StackLayout>
</FlexboxLayout>
</StackLayout>
<StackLayout class="article-heading">
<Label text="{{article.heading}}" class="article-heading-text" textWrap="true"></Label>
</StackLayout>
</StackLayout>
<StackLayout *ngIf="i==330">
<StackLayout class="banner" *ngFor="let banner of banners">
<WebImage src="{{banner.image}}" stretch="aspectFit" width="100%" class="banner-image" (tap)="open_url(banner.url)"></WebImage>
</StackLayout>
</StackLayout>
</StackLayout>
</StackLayout>
<StackLayout class="load-more-button">
<Button class="btn btn-primary" text="Načítať ďalšie" (tap)="load_more_articles()" *ngIf="loading_more_articles==false"></Button>
<LoadingSmall *ngIf="loading_more_articles==true"></LoadingSmall>
</StackLayout>
</StackLayout>
</StackLayout>
</ScrollView>
</PullToRefresh>
</StackLayout>
</StackLayout>
<Loading *ngIf="loading==true && network_error==false"></Loading>
<StackLayout height="100%" (tap)="check_connection()" *ngIf="network_error==true">
<NetworkError></NetworkError>
</StackLayout>
<Tabs></Tabs>
</GridLayout>
</RadSideDrawer>
3) This is how I want it. (uses *ngFor) https://www.youtube.com/watch?v=z5CY_R6OAmI&feature=youtu.be1
4) Performance is very bad on android and app is crashing (iOS is great as usual)
5) I need everything transform to ListView
6) I really don’t know how. I read doc, google for done examples and I can’t find solution which would solve my problem.
7)I made simple template in playground https://play.nativescript.org/?template=play-ng&id=Rhw4HJ&v=21
Is possible to give me some advice or edit playground example to show how to do it?
Could someone help me find solution? I will really appreciate it. :frowning:
Thank you so much
It seems that there is a confirmed Bug in Xamarin.Forms in iOS, when you have a content/label with a text too large that needs 2 lines to display it in a StackLayout (lets say layoutA), the others siblings and parent elements takes the width of the layoutA.
Kent Boogaart filled a Bug with the following example to reproduce the error.
<StackLayout Margin="0,20,0,0">
<!-- works (by virtue of no wrapping) -->
<StackLayout Orientation="Horizontal">
<Switch/>
<Label Text="Some text"/>
<Button Text="A Button" HorizontalOptions="EndAndExpand"/>
</StackLayout>
<!-- works (by virtue of no switch) -->
<StackLayout Orientation="Horizontal">
<Label Text="Some longer text that wraps over two lines"/>
<Button Text="A Button" HorizontalOptions="EndAndExpand"/>
</StackLayout>
<!-- does not work -->
<StackLayout Orientation="Horizontal">
<Switch/>
<Label Text="Some longer text that wraps over two lines"/>
<Button Text="A Button" HorizontalOptions="EndAndExpand"/>
</StackLayout>
</StackLayout>
Is there a solution/fix/workaround for this problem?
EDIT
Here is the code used:
<ListView HasUnevenRows="True" SeparatorVisibility="None" HorizontalOptions="StartAndExpand" CachingStrategy="RecycleElement">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="#eee" Padding="5" Margin="5" >
<ffimageloading:CachedImage HorizontalOptions="Start" VerticalOptions="Start" HeightRequest="75" Source="{Binding ID, StringFormat='https://example/api/{0}'}" CacheDuration="15">
<ffimageloading:CachedImage.Transformations>
<fftransformations:CircleTransformation/>
</ffimageloading:CachedImage.Transformations>
</ffimageloading:CachedImage>
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
<Label Text="{Binding Name}" TextColor="#f35e20" HorizontalOptions="FillAndExpand"/>
<Label Text="{Binding Description}" HorizontalOptions="FillAndExpand" TextColor="#503026" />
<Label Text="{Binding ID}" x:Name="ID" IsVisible="False"></Label>
<Button Text="Ver productos" TextColor="#FF5F6D" HorizontalOptions="End" BackgroundColor="Transparent"></Button>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
These are actual screenshots of the app in iOS, in Android it just work great.
As you can see, in the Image1 the first card is OK, the button ("Agregar al carrito" or "Ver Productos") is at the end.
But in the second card as the text is too large, the button gets down out of the card.
And in the second image, the text in the middle needs 2 lines, and the StackLayout that wraps the content (the 2 labels and the button) gets just as wide as the label with the large text.
I draw a red square in the large text, and a red line so you can see that because of that large text, the StackLayout gets narrow.
This is a known issue that when setting the padding on stacklayout inside Cell , the row height displays incorrectly.
Solution: Use StackLayout to wrap the content under the Cell.
<ViewCell>
<StackLayout > //add this
<StackLayout Orientation="Horizontal" Padding="5" Margin="5" >
</ffimageloading:CachedImage>
<StackLayout BackgroundColor="Brown" Orientation="Vertical">
<Label TextColor="#f35e20" HorizontalOptions="FillAndExpand"/>
<Label/>
<Label Text="fff" x:Name="ID" IsVisible="False"></Label>
<Button Text="Ver productos" TextColor="#FF5F6D" BackgroundColor="Yellow"></Button>
</StackLayout>
</StackLayout>
</StackLayout>
</ViewCell>
I have a StackLayout and a label, the spacing between the two is very large, I want to decrease so that the two are as close together as possible, in what way I do this
<ScrollView BackgroundColor="#ffffff" Padding="15">
<StackLayout HorizontalOptions="Fill" VerticalOptions="FillAndExpand">
<Image Source="{Binding Image}" HeightRequest="200" x:Name="image">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="OnTapped" />
</Image.GestureRecognizers>
</Image>
<StackLayout Orientation="Horizontal" Spacing="0">
<Button x:Name="Amais" Text="A+" />
<Button x:Name="Amenos" Text="A-" />
</StackLayout>
<Label x:Name="webView" VerticalOptions="FillAndExpand" FontSize="18"/>
</StackLayout>
</ScrollView>
*Edit: Lets try this again, set Spacing to 0 on the parent StackLayout and removed the VerticalOptions on the Label and on the parent StackLayout. Does that get you the results your after?
<ScrollView BackgroundColor="#ffffff" Padding="15">
<StackLayout HorizontalOptions="Fill" Spacing="0">
<Image Source="{Binding Image}" HeightRequest="200" x:Name="image">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="OnTapped" />
</Image.GestureRecognizers>
</Image>
<StackLayout Orientation="Horizontal">
<Button x:Name="Amais" Text="A+" />
<Button x:Name="Amenos" Text="A-" />
</StackLayout>
<Label x:Name="webView" FontSize="18"/>
</StackLayout>
</ScrollView>
# I am using listview inside the Scrollview but listview is not scrollable inside the scrollview as top parent view
component.html
<ScrollView>
<StackLayout class="zindex">
<!--<AutoComplete [items]="ArrayVillage" (itemTap)="itemTapped($event)"> </AutoComplete>-->
<SearchBar row="0" #sb hint="Search for a country and press enter" (clear)="onClear()" [text]="searchPhrase" (submit)="onSubmit(sb.text)"></SearchBar>
<ListView row="1" [items]="myItems" class="list-group">
<template let-item="item">
<GridLayout class="item" class="list-group-item">
<Label [text]="item.name" class="list-group-item-heading"></Label>
</GridLayout>
</template>
</ListView>
</StackLayout>
<ScrollView>
Try Using Repeater instead of ListView as mentioned in https://docs.nativescript.org/cookbook/ui/repeater. Following is an example of how you can include Repeater inside a ScrollView and can obtain whole layout as scrollable.
<ScrollView>
<StackLayout class="margin">
<Label text="{{ description }}"></Label>
<Repeater items="{{ options }}" row="1">
<Repeater.itemTemplate>
<StackLayout>
<Label text="{{ description }}"></Label>
</StackLayout>
</Repeater.itemTemplate>
</Repeater>
</StackLayout>
</ScrollView>
Trying it by wrapping the scrollview into a AbsoluteLayout
<AbsoluteLayout>
<ScrollView>
<StackLayout class="zindex">
//Rest of stuff
</StackLayout>
<ScrollView>
</AbsoluteLayout>
Having a scrollview inside other one is not a good practice. It doesn't work beacuse scrollview tries to calculate the infinite view and do it with a scrollable inside could work just in some cases having control of the parent view, but don't go that painfull way.
In your code I have a question, why would you want to scroll the SearchBar? Try this structure I think is what you want.
<StackLayout>
<SearchBar></SearchBar>
<ListView>
<template>
<GridLayout >
<Label ></Label>
</GridLayout>
</template>
</ListView>
The SearchBar is fixed and the List scrolllable
Look at the video, play with the emulator and you will see that at the beggining it seems to work but is the "computer mouse scroll" when you use click trying to scroll it doesn't work anymore and is because the screen doesn't know which scrollable element has to scroll.
To do 2 scrollable parts can be a solution, as shown in the end of the video (I implemented in Nativescript with Javascript because I'm working in a project but is almost the same)
<StackLayout>
<Label fontSize="20" color="blue" text="You can do two scrollable parts" textWrap="true" />
<Button text="to" />
<ListView items="{{ items }}" height="300" loaded="onLoaded" itemLoading="onItemLoading" itemTap="onItemTap">
<ListView.itemTemplate>
<Label text="{{ name }}" textWrap="true" />
</ListView.itemTemplate>
</ListView>
<ScrollView>
<StackLayout>
<Button text="1" />
<Button text="2" />
<Button text="3" />
<Button text="4" />
<Button text="5" />
<Button text="6" />
<Button text="3" />
<Button text="4" />
<Button text="5" />
<Button text="6" />
</StackLayout>
</ScrollView>
</StackLayout>