Nativescript: Disable swipe left/right in TabView on Android

Created on 13 Jul 2016  路  17Comments  路  Source: NativeScript/NativeScript

Hi,

i need to disable the native swipe ability in TabViews on Android. The solution mentioned here is not working anymore - the swipe event seems to be already in motion when onTouch is called, so it moves a few pixels and gets stuck then.

The proper native solution seems to be, to override the ViewPage class like discussed here.

Is it possible to achieve this with nativescript some other way?
Would it be possbile to add a TabView Attribute swipeEnabled="true/false"?

android

Most helpful comment

We still need that feature. I don't want to use segmented bar instead of tab view because I want a bottom navigation on ios which isn't provided by segmented bar. It would be better to have an attribute to disable swipe on tab view.

All 17 comments

Hello @einicher

Indeed the solutions provided in the thread are no longer applicable .
We will take your suggestion about adding TabView attribute into consideration.

Meanwhile, have you considered using SegmentedBar instead of TabView?

I will try, but shouldn't it be possible for child elements to take over gestures overruling those of their parents? What for example if you need swipe gestures on a listview inside a tabview? Thats very common.

With segmentedBar suddenly all getViewById of elements inside SegmentedBarItem are not found anymore.

@einicher the concept behind SegmentedBar is a bit different from TabView.

Here is a basic example how to implement SegmentedBar with changing the content on selectedIndex.

_page.xml_

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo">
<StackLayout>
  <SegmentedBar id="seg-bar" selectedIndex="{{ segBaritemSelectedIndex }}">
    <SegmentedBar.items>
      <SegmentedBarItem title="Item 1" />
      <SegmentedBarItem title="Item 2" />
      <SegmentedBarItem title="Item 3" />
    </SegmentedBar.items>
  </SegmentedBar>
  <AbsoluteLayout>
      <GridLayout width="400" height="400" visibility="{{ isItemOneVisible ? 'visible' : 'collapse' }}" backgroundColor="red"></GridLayout>
      <GridLayout width="400" height="400" visibility="{{ isItemTwoVisible ? 'visible' : 'collapse' }}"  backgroundColor="green"></GridLayout>
      <GridLayout width="400" height="400" visibility="{{ isItemThreeVisible ? 'visible' : 'collapse' }}"  backgroundColor="yellow"></GridLayout>
  </AbsoluteLayout>
</StackLayout>
</Page>

_page.js_

"use strict";
var observable_1 = require("data/observable");
var vm = new observable_1.Observable();
vm.set("segBaritemSelectedIndex", 0);
vm.set("isItemOneVisible", true);
vm.set("isItemTwoVisible", false);
vm.set("isItemThreeVisible", false);

function navigatingTo(args) {

    var page = args.object;
    var segbar = page.getViewById("seg-bar");
    vm.addEventListener(observable_1.Observable.propertyChangeEvent, function (propertyChangeData) {
        if (propertyChangeData.propertyName.toString() == 'segBaritemSelectedIndex') {
            switch (propertyChangeData.value) {
                case 0:
                    vm.set("isItemOneVisible", true);
                    vm.set("isItemTwoVisible", false);
                    vm.set("isItemThreeVisible", false);
                    break;
                case 1:
                    vm.set("isItemOneVisible", false);
                    vm.set("isItemTwoVisible", true);
                    vm.set("isItemThreeVisible", false);
                    break;
                case 2:
                    vm.set("isItemOneVisible", false);
                    vm.set("isItemTwoVisible", false);
                    vm.set("isItemThreeVisible", true);
                    break;
                default:
                    break;
            }
        }
    });
    page.bindingContext = vm;
}
exports.navigatingTo = navigatingTo;

And from this point instead of GridLayouts, you can insert your pages via custom components.

how do I set platform specific xml?
home.android.xml does not work.
On iOS segmented bar ist ugly and has no icons.

Hey @einicher

You can use platform specific tags to have a different XML layouts for Android and iOS.
For example:

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo">
  <android>
     <GridLayout width="200" height="100" backgroundColor="green">
        <Label text="Android" textWrap="true" />
     </GridLayout>
  </android>
  <ios>
     <GridLayout width="100" height="200" backgroundColor="red">
        <Label text="iOS" textWrap="true" />
     </GridLayout>
  </ios>
</Page>

You can still have your platform specific CSS and code-behind files but you should work with one XML file.

As for your segmentedBar question, you can always customize its appearance with CSS styles and add Icon Fonts for creating your icons inside the segmentedBarItem

Thank you.
Sure this should work that way: vm.addEventListener(observable_1.Observable.propertyChangeEvent, function (propertyChangeData) { ?
Its not connected to the segbar somehow, when i try it, the event never gets triggered.

changed it to segbar.addEventListener get args.selectedIndex now.

We still need that feature. I don't want to use segmented bar instead of tab view because I want a bottom navigation on ios which isn't provided by segmented bar. It would be better to have an attribute to disable swipe on tab view.

Indeed, this is not a proper solution.

Any update on this feature? because on my project I really need to disable the swipe functionality.

Also need this feature. Swiping ListView items on Android just won't work otherwise. Agree that Segmented Bar is not a real solution.

This seems like an easy implementation.
See:

https://github.com/NativeScript/NativeScript/blob/f14a246103a395a2b333af11ef3c43d3be17af8d/tns-core-modules/ui/tab-view/tab-view.android.ts#L402

If I move this outside the if statement and just set it to false then this works. Why isn't there a property to allow us to set this manually if we desire vs the core devs forcing us into a setting that's obviously there? OR is this method going to be removed in the future and would cause more harm than good? Just curious. Any thoughts @NickIliev ?

I submitted a PR for this but I don't know whether or not it'll get added. At the very least I tried. In the meantime, I'm just going to use my own repo of the core modules and manually keep it up to date with the upstream.

https://github.com/NativeScript/NativeScript/pull/6258

Is there anyone still monitoring this thread?

Any updates on this issue?

Was this page helpful?
0 / 5 - 0 ratings