Enable swipe in TabView - nativescript

I am using NativeScript Angular and have a TabView that is set to the bottom position. I would like to allow the user to swipe between tabs on both iOS and Android but in the TabView docs it says that swiping has been disabled when the position is set to bottom.
How do I enable swiping on the TabView?

After reading about the gesture API I ended up doing it by adding a swipe event listener to the TabView:
HTML:
<TabView #tabview (swipe)="onSwipe($event)" androidTabsPosition="bottom">
<page-router-outlet
*tabItem="{title: 'Start', iconSource: getIconSource('play')}"
name="startTab">
</page-router-outlet>
<page-router-outlet
*tabItem="{title: 'Settings', iconSource: getIconSource('settings')}"
name="settingsTab">
</page-router-outlet>
</TabView>
TypeScript:
#ViewChild("tabview") tabview!: ElementRef<TabView>;
...
onSwipe(event: SwipeGestureEventData) {
if (this.tabview.nativeElement.selectedIndex === 0 && event.direction === SwipeDirection.left){
this.tabview.nativeElement.selectedIndex = 1;
} else if(this.tabview.nativeElement.selectedIndex === 1 && event.direction === SwipeDirection.right){
this.tabview.nativeElement.selectedIndex = 0;
}
}
...

Related

Nativescript Vue: SearchBar on Android in focus with keyboard visible when page loads

In Android, the page loads with the keyboard expanded and the focus is on the search bar.
I am trying to keep the focus from not being there on page load. The relevant code is :
<StackLayout height="100%"
class="main-container"
>
<SearchBar ref="searchBars"
class="search-bar"
#loaded="onSearchLoaded($event)"
#textChange="onTextChanged($event)"/>
I have tried adding:
mounted() {
this.$refs.searchBars.nativeView.dismissSoftInput();
}
but this has not worked. I also tried adding this.$refs.searchBars.nativeView.dismissSoftInput()
to the #loaded event function of the searchBar.
Try this
<SearchBar #loaded="onSearchBarLoaded($event)" />
And add a method:
onSearchBarLoaded: function(event) {
if (event.object.android) {
setTimeout(() => {
event.object.dismissSoftInput();
event.object.android.clearFocus();
}, 0);
}
}
I have also tried the above method and failed. So I've did a small trick to tackle the situation.
I've added a dummy search bar and set the visibility to hidden. So the focus will shift to the dummy search bar! Here is my code.
<SearchBar
v-model="searchPhrase"
#textChange="onSearch"
#submit="onSearch"
backgroundColor="white"
#clear="clearSearch" />
<!--Dummy searchbar -->
<SearchBar v-show="false" />
You can use a method to focus on what ever you want.
searchBars() {
this.$refs.searchBars.nativeView.focus();
},

Xamarin views are overlapped by the UINavigationBar when set to be translucent

I have a Xamarin.Forms app and want to set the NavigationBar to be translucent. But when I do, I get a strange behavior with the Xamarin views:
ListViews or TableViews behave correctly. But when I wrap them in a RefreshView, they are overlapped by the UINavigationBar.
-- TRANSLUCENCY WITHOUT REFRESHVIEW: OKAY
<ContentPage>
<ListView>
...
</ListView>
</ContentPage>
-- TRANSLUCENCY WITHOUT REFRESHVIEW: BUGGY
<ContentPage>
<RefreshView> <----
<ListView>
...
</ListView>
</RefreshView>
</ContentPage>
Am I missing something?
Repro on GitHub: https://github.com/awaescher/xamarin-repro
How to make a translucent NavigationBar: https://xamgirl.com/transparent-navigation-bar-in-xamarin-forms/
We can use navigationPage.BarBackgroundColor = Color.Transparent to achieve that .
NavigateFromMenu method modified as follow :
case (int)MenuItemType.TranslucentWithoutRefreshView:
MenuPages.Add(id, CreateTranslucentNavigationPage(new TranslucentWithRefreshPage(),false));
break;
case (int)MenuItemType.TranslucentWithRefreshView:
MenuPages.Add(id, CreateTranslucentNavigationPage(new TranslucentWithRefreshPage(),true));
break;
Then in CreateTranslucentNavigationPage method :
private Xamarin.Forms.NavigationPage CreateTranslucentNavigationPage(Xamarin.Forms.Page page, bool value)
{
var navigationPage = new Xamarin.Forms.NavigationPage(page);
if (value)
{
navigationPage.BarBackgroundColor = Color.Transparent;
navigationPage.BarTextColor = Color.Black;
}
//Xamarin.Forms.PlatformConfiguration.iOSSpecific.NavigationPage.SetIsNavigationBarTranslucent(navigationPage, true);
return navigationPage;
}
The effect :

Xamarin forms breadcrumbs with horizontal scroll layout

I have a xamarin.forms app in which I am trying achieve a specific UI.Please find the attched image.
.
As you can see It is a list view and have a breadcrumbs below it. What I am trying to achieve is when user click any of the other items such as "stores" or "users" in breadcrumbs, then the upper layout horizontally slide and show another list view.Where I am stuck is I want to fix the breadcrumbs at the bottom and the change only needs the upper layout i.e.; the list view layout. How can I achieve this. Any ideas will be much helpfull.
What I am thinking is putting four listview inside horizontal scroll view.But is it the better approach?
This could be achieved by simple Translate animation.
A simple implementation of the idea of using translation. Change as per need.
XAML layout:
<StackLayout>
<Grid x:Name="rotatingView">
<ListView
...../>
<ListView
TranslationX="{Binding Width, Source={x:Reference rotatingView}}"
...../>
<ListView
TranslationX="{Binding Width, Source={x:Reference rotatingView}}"
...../>
<ListView
TranslationX="{Binding Width, Source={x:Reference rotatingView}}"
...../>
</Grid>
<Button
Text="0"
Clicked="Button_Clicked"/>
<Button
Text="1"
Clicked="Button_Clicked"/>
<Button
Text="2"
Clicked="Button_Clicked"/>
<Button
Text="3"
Clicked="Button_Clicked"/>
</StackLayout>
Xaml.cs clicked:
int previousSelectedIndex = 0;
private async void Button_Clicked(System.Object sender, System.EventArgs e)
{
Button selectedtab = (sender as Button);
int selectedViewIndex = int.Parse(selectedtab.Text);
VisualElement previousView = rotatingView.Children[previousSelectedIndex];
VisualElement selectedView = rotatingView.Children[selectedViewIndex];
bool isMovingForward = true;
if (previousSelectedIndex < selectedViewIndex)
{
isMovingForward = true;
}
else if(previousSelectedIndex > selectedViewIndex)
{
isMovingForward = false;
}
if (selectedViewIndex != previousSelectedIndex)
{
selectedView.TranslationX = rotatingView.Width * (isMovingForward ? 1 : -1);
await Task.WhenAll(
selectedView.TranslateTo(0, 0),
previousView.TranslateTo(rotatingView.Width * (isMovingForward ? -1 : 1), 0));
}
this.previousSelectedIndex = selectedViewIndex;
}
Here I have used the text of buttons to select index of the view. Hope this could help.
if you are looking for a breadcrumb navigation control.
I have created a control that will generate one automatically, and it's highly customisable.
https://github.com/IeuanWalker/Xamarin.Forms.Breadcrumb

Hide tab buttons on Nativescript-Angular TabView

I'm trying to find a way to remove the tab buttons on a element with an Angular 6 app but with no avail so far. Basically, I only want to keep the Tab contents and their swipe functionality.
Apparently there are specific android and iOS methods you can use but I'm unsure how to do that.
<TabView [(ngModel)]="tabSelectedIndex" (selectedIndexChanged)="onSelectedIndexChanged($event)" (loaded)="tabViewLoaded($event)">
<ng-container *ngFor="let article of articles" #tabView>
<StackLayout *tabItem="{title: article.id}">
<StackLayout>
<NewsDetails></NewsDetails>
</StackLayout>
</StackLayout>
</ng-container>
</TabView>
On my .ts file I can find a reference to the element like this:
#ViewChild("tabView") tabView: ElementRef;
ngAfterViewInit() {
console.dir(this.tabView.nativeElement);
}
But I have no idea what to do from now on. Any ideas? All previous questions regarding this have not worked.
Here is a sample playground link: https://play.nativescript.org/?template=play-ng&id=iK9ZTM
Use the code below with the loaded event of TabView.
onTabViewLoaded(event: EventData) {
const tabView = <TabView>event.object;
if (isIOS) {
tabView.viewController.tabBar.hidden = true;
}
if (isAndroid) {
const tabLayout = tabView.nativeViewProtected.tabLayout;
tabLayout.getLayoutParams().height = 0;
tabLayout.requestLayout();
}
}
I recently did that for a sample work I posted in Uplabs

NativeScript Angular 2 Get more data when Scroll to Bottom (endless scrolling)

HI for example below is my view
<ScrollView>
<StackLayout>
<StackLayout *ngFor="let kid of kids" id="kidList">
<StackLayout orientation="horizontal" class="some-class">
<Lable text="{{ kid.fname }} {{ kid.lname }}"></Lable>
<Lable text="{{ kid.age }} years ago"></Lable>
</StackLayout>
</StackLayout>
</StackLayout>
</ScrollView>
I want to append the more data getting from server to 'kidList' when scroll reaches to bottom of screen in {N} aAngular2.
It's very hard to me build the layouts and adding childs in 'js' like below(KidInformation has more data).
let stackLayout = new StackLayout();
stackLayout.addChild('something newly constructed with JS')
Is there a way we can do in My Component just by adding child as view by passing local parameters to view , I mean like in below way
let kidListStacklayout = view.getViewById(this.page, 'kidList');
kidListStacklayout.addChild('views/kid/kid-item.html')
and kid-item.html will look like
<StackLayout orientation="horizontal" class="some-class">
<Lable text="{{ kid.fname }} {{ kid.lname }}"></Lable>
<Lable text="{{ kid.age }} years ago"></Lable>
</StackLayout>
The stock list view supports what you want. Don't use a scrollview and adding more layouts to the screen. This will cause lag and other issues. A listview recycles UI view components to reduce overhead of the layout growing in size. You want to use the loadMore event on the list view. https://docs.nativescript.org/cookbook/ui/list-view
Of course as the comment above ^^^ the free UI suite from telerik provides the RadListView which also supports infinite scrolling with a loadMore event.
Find out how to do it ( using Angular & TypeScript) :
import { ScrollView, ScrollEventData } from "ui/scroll-view";
#Component({...})
class ComponentClass implements OnInit, AfterViewInit {
#ViewChild("scrollid") scrollView: ElementRef;
ngOnInit(){
let scrollv : ScrollView = <ScrollView>this.scrollView.nativeElement;
scrollv.on(ScrollView.scrollEvent, function (args: ScrollEventData) {
if(scrollv.scrollableHeight === args.scrollY){
console.log("load more items here !!! ");
}
});
}
}
The scrollv.scrollableHeight gets updated by itself.
Tested on android emulator only. Must work on both Plateforms.

Resources