Nativescript Vue: How to change frame height to account for space from other content? - nativescript

I have in my main App.vue a component, called BottomNavigationBar that is always on screen. Above that, I have a separate Frame that loads up CountryListComponent, which navigates to different parts of that component. The only issue is that some of the content being loaded in the separate Frame is being hidden behind the persistent BottomNavigationBar. I assume I have to adjust the height of the new Frame to lower the height to account for the BottomNavigationBar. I added an #loaded event that called adjustFrameHeight to the Frame but not sure what to run inside of it to adjust the height. What's the best way to do this?
<template>
<Page actionBarHidden="true">
<DockLayout height="100%">
<Frame #loaded="adjustFrameHeight" id="main-frame" height="90%" v-show="this.selectedTab =='1'">
<CountryListComponent dock="top" #handleItemTap="handleItemTap" :movies="this.movies"/>
</Frame>
<BottomNavigationBar
dock="bottom"
activeColor="red"
inactiveColor="yellow"
backgroundColor="blue"
#tabSelected="this.changeTab"
verticalAlignment="bottom"
row="1">
<BottomNavigationTab title="First" icon="icon-29.png" />
<BottomNavigationTab title="Second" icon="icon-29.png" />
<BottomNavigationTab title="Third" icon="icon-29.png" />
</BottomNavigationBar>
</DockLayout>
</Page>
</template>

You can try to use a GridLayout instead of the DockLayout.
* will take up the available space on the screen and auto will take up the maximum height of the child component in that row.
<template>
<Page actionBarHidden="true">
<GridLayout rows="*, auto" height="100%">
<Frame row="0" #loaded="adjustFrameHeight" id="main-frame" height="100%" v-show="this.selectedTab =='1'">
<CountryListComponent #handleItemTap="handleItemTap" :movies="this.movies"/>
</Frame>
<BottomNavigationBar
row="1"
activeColor="red"
inactiveColor="yellow"
backgroundColor="blue"
#tabSelected="this.changeTab"
verticalAlignment="bottom">
<BottomNavigationTab title="First" icon="icon-29.png" />
<BottomNavigationTab title="Second" icon="icon-29.png" />
<BottomNavigationTab title="Third" icon="icon-29.png" />
</BottomNavigationBar>
</GridLayout>
</Page>
</template>

So, it seems like Frame takes 100% of the height of its direct parent.
Just add StackLayout as the parent of the frame
<Page actionBarHidden="true">
<GridLayout rows="*, auto" height="100%">
<StackLayout>
<Frame row="0" #loaded="adjustFrameHeight" id="main-frame" height="100%" v-show="this.selectedTab =='1'">
<CountryListComponent #handleItemTap="handleItemTap" :movies="this.movies"/>
</Frame>
</StackLayout>
<BottomNavigationBar
row="1"
activeColor="red"
inactiveColor="yellow"
backgroundColor="blue"
#tabSelected="this.changeTab"
verticalAlignment="bottom">
<BottomNavigationTab title="First" icon="icon-29.png" />
<BottomNavigationTab title="Second" icon="icon-29.png" />
<BottomNavigationTab title="Third" icon="icon-29.png" />
</BottomNavigationBar>
</GridLayout>
</Page>
</template>

Related

How to vertically fill space between elements in ScrollView while preserving scrolling

I am trying to achieve the following:
I tried achieving this with a GridLayout and only get one of the following two things working:
The space between the Label and the StackLayout is filled (label is
stretched), but scrolling will not work when adding more labels into
the StackLayout
Scrolling will work when more labels are added into
the StackLayout, but when only one label is showed for example, the
label before the StackLayout will not stretch
Is there any way to achieve such a thing? GridLayout is not necessarily needed, but I tried several ways and could not find any way of doing this.
example code of (1)
<Page class="page dark">
<ScrollView backgroundColor="red">
<GridLayout rows="*, auto" height="100%" backgroundColor="blue">
<Label backgroundColor="green">Top Label</Label>
<StackLayout row="1" backgroundColor="green">
<Label backgroundColor="purple">Label A</Label>
<Label backgroundColor="purple">Label B</Label>
</StackLayout>
</GridLayout>
</ScrollView>
</Page>
example code of (2):
<Page class="page dark">
<ScrollView backgroundColor="red">
<GridLayout rows="*, auto" backgroundColor="blue">
<Label backgroundColor="green">Top Label</Label>
<StackLayout row="1" backgroundColor="green">
<Label backgroundColor="purple">Label A</Label>
<Label backgroundColor="purple">Label B</Label>
</StackLayout>
</GridLayout>
</ScrollView>
</Page>
I wanted to achieve this for months and I finally found a working solution, for iOS and Android.
The solution is to use FlexboxLayout instead of GridLayout. When placed in a ScrollView, FlexboxLayout will take the whole available height if it is not tall enough. If it is taller than the ScrollView, it will be scrollable.
Here is the solution for your example:
<Page class="page dark">
<ScrollView backgroundColor="red">
<FlexboxLayout
flexDirection="column"
justifyContent="space-between"
alignItems="stretch"
backgroundColor="blue"
>
<Label backgroundColor="green">Top Label</Label>
<StackLayout backgroundColor="green">
<Label backgroundColor="purple">Label A</Label>
<Label backgroundColor="purple">Label B</Label>
</StackLayout>
</FlexboxLayout>
</ScrollView>
</Page>

Nativescript inner StackLayout

Hello everyone I'm trying to make inner StackLayouts but the second one comes to top of first one so that I can't see the second StackLayout should I handle with css if it is how or is there an other way
Here is my code
<StackLayout orientation="horizontal">
<StackLayout width="500">
<GridLayout columns="50, *" rows="*" width="500" height="50"
verticalAlignment="top">
<Label text="Name" row="0" col="0" backgroundColor="red">
</Label>
<Label text="Fol" row="0" col="1" class="alignRight"
backgroundColor="blue"></Label>
</GridLayout>
</StackLayout>
<StackLayout orientation="horizontal" width="500" height="180">
<Image src="http://lorempixel.com/400/200" width="500" left="10"
top="30">
</Image>
</StackLayout>
</StackLayout>
Thank you
At first I would delete the widths to see how the page is displayed. 500 is a very big value. Only large tablets can support that.
As an example at first I would try this :
<GridLayout columns="auto, auto">
<GridLayout col="0" columns="50, *" rows="*" verticalAlignment="top">
<Label text="Name" row="0" col="0" backgroundColor="red">
</Label>
<Label text="Fol" row="0" col="1" class="alignRight"
backgroundColor="blue"></Label>
</GridLayout>
<Image col="1" src="http://lorempixel.com/400/200" left="10" op="30">
</Image>
</GridLayout>
After you see the two parts align horizontally you can start tweaking the widths

why Listview is not scroll-able inside scrollview in nativescrit angular2

# 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>

Get a TextView to scroll

I've got a TextView inside a GridLayout and have it set to take maximum available height. That works.
But If the user presses new-line to the bottom of the TextView and more - the TextView cursor goes off the bottom of the screen instead of scrolling the TextView.
How can I get the TextView to scroll.
In iOS the TextView should be scrollable by default if you set large text in it.
However for Android you could use ScrollView and to use StackLayout for main container inside it. For further help you could review the below attached example:
main-page.xml
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo">
<GridLayout columns="*" rows="auto,*">
<GridLayout row="0" col="0" columns="auto,*" rows="auto">
<Label text="header" row="0" col="0" />
</GridLayout>
<GridLayout row="1" col="0" columns="auto,*" rows="auto">
<Label text="Note" row="0" col="0" />
<ScrollView orientation="vertical" row="1" col="0" height="300" width="300" backgroundColor="green">
<StackLayout orientation="vertical" class="scroll-menu" backgroundColor="red">
<TextView text="" hint="Enter text..." />
</StackLayout>
</ScrollView>
</GridLayout>
</GridLayout>
</Page>

NativeScript zIndex set in XML not working?

Consider the next xml:
<Page xmlns="http://schemas.nativescript.org/tns.xsd" >
<!-- UI Decalration -->
<AbsoluteLayout>
<GridLayout zIndex="99" height="100" width="100" backgroundColor="red"></GridLayout>
<GridLayout zIndex="1" height="200" width="200" backgroundColor="green"></GridLayout>
</AbsoluteLayout>
</Page>
In my understanding the red square should be visible, but it's hidden behind the green one. Am I doing something wrong?
Declare z-index as CSS property so all elements should be rendered as espected.
For example :
page.css
.lower-grid {
z-index: 1;
}
.upper-grid {
z-index: 99;
}
page.xml
<AbsoluteLayout>
<GridLayout class="upper-grid" height="100" width="100" backgroundColor="red" />
<GridLayout class="lower-grid" height="200" width="200" backgroundColor="green" />
</AbsoluteLayout>
This solution worked out for me - keep in mind that z-index is supported for Android API 21 and above.
I got it working by using gridlayout and then repeating the same row number. The order of the items then determines the z-index playground demo:
<GridLayout rows="*, *, *" columns="*">
<GridLayout row="0" col="0" height="300" backgroundColor="black" />
<GridLayout row="1" col="0" height="300" backgroundColor="red" />
<GridLayout row="2" col="0" height="300" backgroundColor="green" />
<GridLayout row="0" col="0" height="100" backgroundColor="blue" margin="100" /> <!-- displays on top of the first row 0 -->
</GridLayout>

Resources