Nativescript: Hiding keyboard from searchBar in TabView

Created on 7 Aug 2018  路  13Comments  路  Source: NativeScript/NativeScript

Did you verify this is a real problem by searching the NativeScript Forum and the other open issues in this repo? Yes

Tell us about the problem

This is only on Android.
I have a page with a TabView with 4 tabs. The first tab does Not have the SearchBar component on it, it's just regular labels and textfields. The 2nd tab has a ListView, with SearchBar above it, 3rd tab is the same, and 4th tab is again regular textfields and labels.
When I navigate to this tab page it's the first tab obvs, but the keyboard shows up, although there's no SearchBar on this tab. It's in the 2nd tab. I'm not sure why this is happening.
I looked up several related issues in the forums, etc. but nothing exactly matched this issue.
They suggested putting a "loaded" event on the SearchBar, which dismisses or sets the focus to somewhere else. But that event does not get fired on navigating to the tab page cause it's loading the first tab, which has no SearchBar.
Similar issue: https://github.com/NativeScript/NativeScript/issues/3702

Which platform(s) does your issue occur on?

Android only

Please provide the following version numbers that your issue occurs with:

  • CLI: 4.2.0
  • Cross-platform modules: 4.2.0
  • Runtime(s): tns-android 4.2.0

Please tell us how to recreate the issue in as much detail as possible.

create a page with tabs, in which the first tab has no SearchBar, but 2nd one does. Navigate to this tab page.

Is there code involved? If so, please share the minimal amount of code needed to recreate the problem.


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

backlog bug help wanted android medium tab-view

Most helpful comment

That solves it!

Thank you!

All 13 comments

Hi @glennsyang,
This seems to be expected. The TabView in Android will load the component in the currently selected tab and will preload the content in the one next to it. To solve your case you can use some of the two below described options.
Option 1:
You can use TabView's androidOffscreenTabLimit and to set up its value to 0. This will specify that only one item of the TabView should be preload. More info can be found here.

Option 2:
Dismissing the keyboard with dismissSoftInput method. Which can be used on the component's loaded event. In your case on the SearchBar loaded. An example can be found here.

Hi @tsonevn,

Yes, that's exactly what I already have done, set TabView's androidOffscreenTabLimit to 0.
Here's my code:

<GridLayout id="layout" rows="*, 20">
<TabView row="0" id="tabViewContainer" class="tab-view" androidOffscreenTabLimit="0" androidTabsPosition="bottom">
            <TabViewItem title="EVENT" xmlns:EventTab="views/event-detail/event-tab">
                <EventTab:event-tab/>
            </TabViewItem>
            <TabViewItem title="STAFF" xmlns:StaffTab="views/event-detail/staff-tab">
                <StaffTab:staff-tab/>
            </TabViewItem>
            <TabViewItem title="LOCATION" xmlns:LocationsTab="views/event-detail/locations-tab">
                <LocationsTab:locations-tab/>
            </TabViewItem>
            <TabViewItem title="REPORT" xmlns:ReportTab="views/event-detail/report-tab">
                <ReportTab:report-tab/>
            </TabViewItem>
        </TabView> </GridLayout>
</Page>

I've also already tried to attach "loaded" to SearchBar in 2nd tab, but that event doesn't fire since it's on the 2nd tab, and my androidOffScreenTabLimit is set to "0".
Or should I try setting the androidOffScreenTabLimit to "1", and then see if the loaded event of the SearchBar fires on the 2nd tab?

Hi @glennsyang,
I tested your case again and was able to recreate the issue on my side. I will mark this as a bug, and we will investigate it further.
Archive.zip

Meanwhile, I would suggest dismissing the keyboard on the SearchBar loaded event while setting up an delay of 150 milliseconds. For example:
XML

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
    <!--
    The ActionBar is the NativeScript common abstraction over the Android ActionBar and iOS NavigationBar.
    http://docs.nativescript.org/ui/action-bar
    -->
    <Page.actionBar>
        <ActionBar title="My App" icon="" class="action-bar">
        </ActionBar>
    </Page.actionBar>

    <GridLayout rows="" columns="">
        <TabView id="tabViewContainer" >
            <TabViewItem title="NativeScript">
                <StackLayout>
                        <Label text="NativeScript" class="m-15 h2 text-left" color="blue" />
                        <StackLayout height="100%">
                            <Label text="test test" textWrap="true" class="m-15" />
                        </StackLayout>
                </StackLayout>
            </TabViewItem>
            <TabViewItem title="Icon">
                <StackLayout>
                    <SearchBar id="searchBar" loaded="searchbarLoaded" hint="Search" text="" clear="onClear" submit="onSubmit" />

                    <Label text="NativeScript" textWrap="true" class="h2 m-x-auto" color="blue" />
                </StackLayout>
            </TabViewItem>
        </TabView>
    </GridLayout>
</Page>

TypeScript

import { EventData } from 'data/observable';
import { Page } from 'ui/page';
import { HelloWorldModel } from './main-view-model';
import {ad} from "tns-core-modules/utils/utils"

export function navigatingTo(args: EventData) {

    let page = <Page>args.object;

    page.bindingContext = new HelloWorldModel();
}

export function searchbarLoaded(args){
    console.log("sb loaded");
    setTimeout(() => {
        ad.dismissSoftInput();
    }, 150);

}

Hi @tsonevn ,

Thanks for your suggestion!

So do I have to put the TabViewItem content in the same place as my main page, as you have it. Or can I use the xml namespace to separate out the contents of my tabs? Or will that not trigger the searchBarLoaded event?

I tried your solution with xml namespaces for my tabs, but as mentioned the searchBarLoaded event doesn't get triggered on the navigating to the page, since it's loading the first tab called 'Event'. Nothing from the other tabs gets triggered. I even tried with completely removing androidOffscreenTabLimit="0" option from the TabView, and nothing changed, the other tabs loading events do not get triggered.
Is it perhaps maybe because I have their code and xml in different files? Not in the main page, I just refer to them by xml namespace.

Not sure if this helps, but the console has these messages when I navigate to the page that has the 4 tabs:

image

Hi @glennsyang,
Regarding the keyboard dismiss. You can also try to call the dismissSoftInput on loaded on some of the components in the tab, which is loaded on initial time. For example:
XML

<TabView id="tabViewContainer" >
            <TabViewItem title="NativeScript">
                <StackLayout>
                        <Label loaded="labelLoaded" text="NativeScript" class="m-15 h2 text-left" color="blue" />
                        <StackLayout height="100%">
                            <Label text="test test" textWrap="true" class="m-15" />
                        </StackLayout>
                </StackLayout>
            </TabViewItem>
            <TabViewItem title="Icon">
                <StackLayout>
                    <SearchBar id="searchBar" loaded="searchbarLoaded" hint="Search" text="" clear="onClear" submit="onSubmit" />

                    <Label text="NativeScript" textWrap="true" class="h2 m-x-auto" color="blue" />
                </StackLayout>
            </TabViewItem>
        </TabView>

TypeScript

export function labelLoaded(args){
    console.log("sb loaded");
    setTimeout(() => {
        ad.dismissSoftInput();
    }, 150);

}

About the issue with the navigation to page with four tabs. Can you isolate the problem in a sample project, which we can use for debugging?

Here's a sample project in Playground.

https://play.nativescript.org/?template=play-js&id=uLQKZL&v=41

And the attached code:
NSPlayground.zip

Hi @glennsyang,
Thank you for the sample project.
To solve the issue, add the following code

setTimeout(() => {
        utilsModule.ad.dismissSoftInput();
    }, 150);

in app/event-detail/event-tab/event-tab.js.
I am also attaching the full code for the event-tab.js file.

var EventDetailViewModel = require("./event-detail-view-model");

var utilsModule = require("tns-core-modules/utils/utils");
exports.onTabLoaded = function (args) {
    console.log("onTabLoaded - event-tab");

    var thisTAB = args.object;
    // Get the Parent object
    //var parentView = thisTAB.parent.parent;
    //page = parentView;
    // Get the parent EventModel from parent's bindingContext
    //var parentEventModel = parentView.bindingContext;
    //console.log("EVENTID: " + parentEventModel.selectedEventModel.id);
    // Set the binding context for this tab
    //viewModel = new EventDetailViewModel(parentEventModel.selectedEventModel);
    console.log("test tab loaded")
    thisTAB.bindingContext = new EventDetailViewModel(); //viewModel;
    setTimeout(() => {
        utilsModule.ad.dismissSoftInput();
    }, 150);

};
exports.onTabUnloaded = function (args) {
    console.log("onTabUnloaded - event-tab");

};

That solves it!

Thank you!

I've noticed this same issue as well with the keyboard popping up when using the TabView on Android with my Nativescript Angular project. It seems to happen on pages either side of the Search page.

Here my Playground Example:
https://play.nativescript.org/?template=play-ng&id=eGOyrq&v=11

I've just updated to NS5 RC as instructed here: https://github.com/NativeScript/NativeScript/wiki/Early-Testing-of-NativeScript-5.0-RC and it seems to have fixed this issue.

I've just updated to NS5 RC as instructed here: https://github.com/NativeScript/NativeScript/wiki/Early-Testing-of-NativeScript-5.0-RC and it seems to have fixed this issue.

Thanks for that info, i麓ve recently come to this issue using nativescript playground. And i think that playground is using NS5 , so, idk if it麓s still a bug or they din麓t fully migrate to ns5 as stated here https://www.nativescript.org/roadmap-and-releases#releases

Thank you, setTimeout method resolves my case, too.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

guillaume-roy picture guillaume-roy  路  3Comments

fmmsilva picture fmmsilva  路  3Comments

dhanalakshmitawwa picture dhanalakshmitawwa  路  3Comments

NordlingDev picture NordlingDev  路  3Comments

minjunlan picture minjunlan  路  3Comments