-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(android): Fix setting an active tab for TabGroup before opening. #10740
Changes from 1 commit
e41c25d
950b0d1
4629dd7
0d235ff
78a4c0f
0445430
caca383
0615929
e31cfa3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -163,14 +163,6 @@ public void addTabItemInController(TabProxy tabProxy) | |
} | ||
// Add the MenuItem to the menu of BottomNavigationView. | ||
this.mMenuItemsArray.add(menuItem); | ||
// TabLayout automatically select the first tab that is added to it, | ||
// but BottomNavigationView does not do that, so we manually trigger it. | ||
// That's necessary to match the behavior across styles. | ||
if (this.mMenuItemsArray.size() == 1) { | ||
((TabGroupProxy) getProxy()).onTabSelected(tabProxy); | ||
currentlySelectedIndex = 0; | ||
selectTab(currentlySelectedIndex); | ||
} | ||
// Set the drawables. | ||
setDrawables(); | ||
// Handle shift mode. | ||
|
@@ -256,10 +248,12 @@ public void removeTabItemFromController(int position) | |
public void selectTabItemInController(int position) | ||
{ | ||
// Fire the UNSELECTED event from the currently selected tab. | ||
((TabGroupProxy) getProxy()) | ||
.getTabList() | ||
.get(currentlySelectedIndex) | ||
.fireEvent(TiC.EVENT_UNSELECTED, null, false); | ||
if (currentlySelectedIndex != -1) { | ||
((TabGroupProxy) getProxy()) | ||
.getTabList() | ||
.get(currentlySelectedIndex) | ||
.fireEvent(TiC.EVENT_UNSELECTED, null, false); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should check if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated. |
||
currentlySelectedIndex = position; | ||
// The ViewPager has changed current page from swiping. | ||
// Or any other interaction with it that can cause page change. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
/* | ||
* Appcelerator Titanium Mobile | ||
* Copyright (c) 2011-Present by Appcelerator, Inc. All Rights Reserved. | ||
* Licensed under the terms of the Apache Public License | ||
* Please see the LICENSE included with this distribution for details. | ||
*/ | ||
/* eslint-env mocha */ | ||
/* global Ti */ | ||
/* eslint no-unused-expressions: "off" */ | ||
'use strict'; | ||
const should = require('./utilities/assertions'); // eslint-disable-line no-unused-vars | ||
|
||
// skipping many test on Windows due to lack of event firing, see https://jira.appcelerator.org/browse/TIMOB-26690 | ||
describe('Titanium.UI.TabGroup', () => { | ||
let tabGroup; | ||
let tab; | ||
|
||
afterEach(() => { | ||
if (tabGroup) { | ||
if (tab) { | ||
tabGroup.removeTab(tab); | ||
} | ||
tabGroup.close(); | ||
tabGroup = null; | ||
} | ||
tab = null; | ||
}); | ||
|
||
it.windowsBroken('#setActiveTab()', finish => { | ||
const winA = Ti.UI.createWindow(), | ||
tabA = Ti.UI.createTab({ | ||
title: 'Tab A', | ||
window: winA | ||
}), | ||
winB = Ti.UI.createWindow(), | ||
tabB = Ti.UI.createTab({ | ||
title: 'Tab B', | ||
window: winB | ||
}); | ||
tabGroup = Ti.UI.createTabGroup(); | ||
|
||
// Does windows fire this event? | ||
// Can we test this without even opening tab group? | ||
tabGroup.addEventListener('open', () => { | ||
try { | ||
tabGroup.setActiveTab(tabB); | ||
should(tabGroup.getActiveTab().title).be.a.String; | ||
should(tabGroup.getActiveTab().title).eql('Tab B'); | ||
finish(); | ||
} catch (err) { | ||
finish(err); | ||
} finally { | ||
tabGroup.removeTab(tabA); | ||
tabGroup.removeTab(tabB); | ||
} | ||
}); | ||
|
||
tabGroup.addTab(tabA); | ||
tabGroup.addTab(tabB); | ||
tabGroup.open(); | ||
}); | ||
|
||
it.windowsBroken('#setActiveTab()_before_open', finish => { | ||
const winA = Ti.UI.createWindow(), | ||
tabA = Ti.UI.createTab({ | ||
title: 'Tab A', | ||
window: winA | ||
}), | ||
winB = Ti.UI.createWindow(), | ||
tabB = Ti.UI.createTab({ | ||
title: 'Tab B', | ||
window: winB | ||
}); | ||
tabGroup = Ti.UI.createTabGroup(); | ||
tabGroup.setActiveTab(1); | ||
// Does windows fire this event? | ||
// Can we test this without even opening tab group? | ||
tabGroup.addEventListener('open', () => { | ||
try { | ||
should(tabGroup.getActiveTab().title).be.a.String; | ||
should(tabGroup.getActiveTab().title).eql('Tab B'); | ||
finish(); | ||
} catch (err) { | ||
finish(err); | ||
} finally { | ||
tabGroup.removeTab(tabA); | ||
tabGroup.removeTab(tabB); | ||
} | ||
}); | ||
|
||
tabGroup.addTab(tabA); | ||
tabGroup.addTab(tabB); | ||
tabGroup.open(); | ||
}); | ||
|
||
it.windowsBroken('#change_activeTab_property', finish => { | ||
const winA = Ti.UI.createWindow(), | ||
tabA = Ti.UI.createTab({ | ||
title: 'Tab A', | ||
window: winA | ||
}), | ||
winB = Ti.UI.createWindow(), | ||
tabB = Ti.UI.createTab({ | ||
title: 'Tab B', | ||
window: winB | ||
}); | ||
tabGroup = Ti.UI.createTabGroup(); | ||
|
||
// Does windows fire this event? | ||
// Can we test this without even opening tab group? | ||
tabGroup.addEventListener('open', () => { | ||
try { | ||
tabGroup.activeTab = tabB; | ||
should(tabGroup.getActiveTab().title).be.a.String; | ||
should(tabGroup.getActiveTab().title).eql('Tab B'); | ||
finish(); | ||
} catch (err) { | ||
finish(err); | ||
} finally { | ||
tabGroup.removeTab(tabA); | ||
tabGroup.removeTab(tabB); | ||
} | ||
}); | ||
|
||
tabGroup.addTab(tabA); | ||
tabGroup.addTab(tabB); | ||
tabGroup.open(); | ||
}); | ||
|
||
it.windowsBroken('#change_activeTab_property_before_open', finish => { | ||
const winA = Ti.UI.createWindow(), | ||
tabA = Ti.UI.createTab({ | ||
title: 'Tab A', | ||
window: winA | ||
}), | ||
winB = Ti.UI.createWindow(), | ||
tabB = Ti.UI.createTab({ | ||
title: 'Tab B', | ||
window: winB | ||
}); | ||
tabGroup = Ti.UI.createTabGroup(); | ||
tabGroup.activeTab = 1; | ||
// Does windows fire this event? | ||
// Can we test this without even opening tab group? | ||
tabGroup.addEventListener('open', () => { | ||
try { | ||
should(tabGroup.getActiveTab().title).be.a.String; | ||
should(tabGroup.getActiveTab().title).eql('Tab B'); | ||
finish(); | ||
} catch (err) { | ||
finish(err); | ||
} finally { | ||
tabGroup.removeTab(tabA); | ||
tabGroup.removeTab(tabB); | ||
} | ||
}); | ||
|
||
tabGroup.addTab(tabA); | ||
tabGroup.addTab(tabB); | ||
tabGroup.open(); | ||
}); | ||
|
||
it.windowsBroken('#set_activeTab_in_creation_dictionary', finish => { | ||
const winA = Ti.UI.createWindow(), | ||
tabA = Ti.UI.createTab({ | ||
title: 'Tab A', | ||
window: winA | ||
}), | ||
winB = Ti.UI.createWindow(), | ||
tabB = Ti.UI.createTab({ | ||
title: 'Tab B', | ||
window: winB | ||
}); | ||
tabGroup = Ti.UI.createTabGroup({ | ||
activeTab: 1 | ||
}); | ||
// Does windows fire this event? | ||
// Can we test this without even opening tab group? | ||
tabGroup.addEventListener('open', () => { | ||
try { | ||
should(tabGroup.getActiveTab().title).be.a.String; | ||
should(tabGroup.getActiveTab().title).eql('Tab B'); | ||
finish(); | ||
} catch (err) { | ||
finish(err); | ||
} finally { | ||
tabGroup.removeTab(tabA); | ||
tabGroup.removeTab(tabB); | ||
} | ||
}); | ||
|
||
tabGroup.addTab(tabA); | ||
tabGroup.addTab(tabB); | ||
tabGroup.open(); | ||
}); | ||
|
||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class'
onTabSelected()
method is missing anull
check on theselectedTab
member variable.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you referring to this
onTabSelected()
method?https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/ui/src/java/ti/modules/titanium/ui/TabGroupProxy.java#L529
If that is the case, it is intended for the
selectedTab
to be null in order to skip the sending of thefocus/blur
events when a tab is set as an active one before the opening of the TabGroup. But I may have not got what you mean.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh you're right. Never mind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the unit test around blur events is now failing, and is likely related to the changes in this area...
https://github.com/appcelerator/titanium-mobile-mocha-suite/blob/master/Resources/ti.ui.tabgroup.test.js#L232-L247
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some digging I found that the "blur" unit test started failing because this PR fixed firing a pair of
focus/blur
events that are not supposed to be fired. That problem was introduced at the same time when the unit test was added (Both by me) and this is the reason it didn't fail every single time in other PRs. With my latest update this should be cleared up.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unit test is passing now.