diff --git a/CHANGELOG.md b/CHANGELOG.md
index 75e92afc2..9c7ea49ec 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -89,7 +89,7 @@ Use `AndroidApplication.startActivity`, `AndroidApplication.foregroundActivity`,
* `start(...)` method in `tns-core-modules/application` module is now removed.
-Use `application.run(...)` method instead.
+Use `application.run(...)` method instead. Check the "Flexible Frame Composition" section in [this document](https://docs.google.com/document/d/1Iia0yEr5seq4H9qk4oMuJs4-M8dgmne98fymCO5IczA/edit) that explains the full migration path from `application.start(...)` to `application.run(...)` and the implications from this change
* `loadPage(...)` method in `tns-core-modules/ui/builder` module is now removed.
diff --git a/e2e/ui-tests-app/app/bottom-navigation/bottom-navigation-view-model.ts b/e2e/ui-tests-app/app/bottom-navigation/bottom-navigation-view-model.ts
index f4f699e5e..464f1dec0 100644
--- a/e2e/ui-tests-app/app/bottom-navigation/bottom-navigation-view-model.ts
+++ b/e2e/ui-tests-app/app/bottom-navigation/bottom-navigation-view-model.ts
@@ -52,7 +52,7 @@ export class BottomNavigationViewModel extends Observable {
const gridlayout = new GridLayout();
label.text = "Content Item " + index;
gridlayout.addChild(label);
- contentItem.view = gridlayout;
+ contentItem.content = gridlayout;
return contentItem;
}
diff --git a/e2e/ui-tests-app/app/bottom-navigation/color-page.css b/e2e/ui-tests-app/app/bottom-navigation/color-page.css
index 17d688073..3b7744d0d 100644
--- a/e2e/ui-tests-app/app/bottom-navigation/color-page.css
+++ b/e2e/ui-tests-app/app/bottom-navigation/color-page.css
@@ -17,3 +17,11 @@ TabStripItem.special {
TabStripItem.special:active {
color: yellowgreen;
}
+
+TabStripItem.nested Label {
+ color: teal;
+}
+
+TabStripItem.nested:active Label {
+ color: yellowgreen;
+}
diff --git a/e2e/ui-tests-app/app/bottom-navigation/color-page.xml b/e2e/ui-tests-app/app/bottom-navigation/color-page.xml
index b8c3e9d4e..b63d6c8c4 100644
--- a/e2e/ui-tests-app/app/bottom-navigation/color-page.xml
+++ b/e2e/ui-tests-app/app/bottom-navigation/color-page.xml
@@ -3,10 +3,13 @@
-
+
-
-
+
+
+
+
+
@@ -20,5 +23,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css
index ee183523d..57076da81 100644
--- a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css
+++ b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css
@@ -6,6 +6,34 @@
font-size: 36;
}
-.color {
- color: blue;
-}
\ No newline at end of file
+TabStrip {
+ color: mediumvioletred;
+}
+
+TabStripItem {
+ color: skyblue;
+}
+
+TabStripItem:active {
+ color: darkblue;
+}
+
+TabStripItem.special Image {
+ color: lightgreen;
+}
+
+TabStripItem.special:active Image {
+ color: darkgreen;
+}
+
+TabStripItem.special Label {
+ color: gold;
+}
+
+TabStripItem.special:active Label {
+ color: darkgoldenrod;
+}
+
+TabStripItem:active .font-size {
+ font-size: 10;
+}
diff --git a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.xml b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.xml
index 644cdb121..c72f3320f 100644
--- a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.xml
+++ b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.xml
@@ -3,32 +3,61 @@
-
+
-
-
+
+
+
+
+
+
-
+
+
+
+
+
-
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/e2e/ui-tests-app/app/bottom-navigation/font-page.css b/e2e/ui-tests-app/app/bottom-navigation/font-page.css
index 22a3ce46c..57b0eda89 100644
--- a/e2e/ui-tests-app/app/bottom-navigation/font-page.css
+++ b/e2e/ui-tests-app/app/bottom-navigation/font-page.css
@@ -17,3 +17,11 @@ TabStripItem.special {
TabStripItem.special:active {
font: 16 monospace;
}
+
+TabStripItem.nested Label {
+ font: 12 monospace;
+}
+
+TabStripItem.nested:active Label {
+ font: 16 monospace;
+}
diff --git a/e2e/ui-tests-app/app/bottom-navigation/font-page.xml b/e2e/ui-tests-app/app/bottom-navigation/font-page.xml
index 6da1c6233..b59f818d8 100644
--- a/e2e/ui-tests-app/app/bottom-navigation/font-page.xml
+++ b/e2e/ui-tests-app/app/bottom-navigation/font-page.xml
@@ -1,12 +1,15 @@
-
+
-
+
-
-
+
+
+
+
+
@@ -20,5 +23,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.ts b/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.ts
index 199c5c566..bfb016431 100644
--- a/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.ts
+++ b/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.ts
@@ -6,10 +6,12 @@ export function onSelectedIndexChanged(args: SelectedIndexChangedEventData) {
const newItem = bottomNav.tabStrip.items[args.newIndex];
if (newItem) {
newItem.iconSource = "res://icon";
+ newItem.title = "selected";
}
const oldItem = bottomNav.tabStrip.items[args.oldIndex];
if (oldItem) {
oldItem.iconSource = "res://testlogo";
+ oldItem.title = "unselected";
}
}
diff --git a/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.xml b/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.xml
index 40bf3afac..1305f2a06 100644
--- a/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.xml
+++ b/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.xml
@@ -4,8 +4,8 @@
-
-
+
+
diff --git a/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.css b/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.css
index 80b3649d4..539c8c817 100644
--- a/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.css
+++ b/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.css
@@ -17,3 +17,11 @@ TabStripItem.special {
TabStripItem.special:active {
text-transform: uppercase;
}
+
+TabStripItem.nested Label {
+ text-transform: lowercase;
+}
+
+TabStripItem.nested:active Label {
+ text-transform: uppercase;
+}
diff --git a/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.xml b/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.xml
index 33db487c6..dcddb8bd6 100644
--- a/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.xml
+++ b/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.xml
@@ -1,12 +1,15 @@
-
+
-
+
+
+
+
@@ -20,5 +23,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/e2e/ui-tests-app/app/tabs/color-page.css b/e2e/ui-tests-app/app/tabs/color-page.css
index b417cfecf..97c0d950b 100644
--- a/e2e/ui-tests-app/app/tabs/color-page.css
+++ b/e2e/ui-tests-app/app/tabs/color-page.css
@@ -17,3 +17,11 @@ TabStripItem.special {
TabStripItem.special:active {
color: yellowgreen;
}
+
+TabStripItem.nested Label {
+ color: teal;
+}
+
+TabStripItem.nested:active Label {
+ color: yellowgreen;
+}
diff --git a/e2e/ui-tests-app/app/tabs/color-page.xml b/e2e/ui-tests-app/app/tabs/color-page.xml
index be732a6c3..5741956f5 100644
--- a/e2e/ui-tests-app/app/tabs/color-page.xml
+++ b/e2e/ui-tests-app/app/tabs/color-page.xml
@@ -1,12 +1,15 @@
-
+
-
+
-
-
+
+
+
+
+
@@ -20,5 +23,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/e2e/ui-tests-app/app/tabs/font-icons-page.css b/e2e/ui-tests-app/app/tabs/font-icons-page.css
index ee183523d..57076da81 100644
--- a/e2e/ui-tests-app/app/tabs/font-icons-page.css
+++ b/e2e/ui-tests-app/app/tabs/font-icons-page.css
@@ -6,6 +6,34 @@
font-size: 36;
}
-.color {
- color: blue;
-}
\ No newline at end of file
+TabStrip {
+ color: mediumvioletred;
+}
+
+TabStripItem {
+ color: skyblue;
+}
+
+TabStripItem:active {
+ color: darkblue;
+}
+
+TabStripItem.special Image {
+ color: lightgreen;
+}
+
+TabStripItem.special:active Image {
+ color: darkgreen;
+}
+
+TabStripItem.special Label {
+ color: gold;
+}
+
+TabStripItem.special:active Label {
+ color: darkgoldenrod;
+}
+
+TabStripItem:active .font-size {
+ font-size: 10;
+}
diff --git a/e2e/ui-tests-app/app/tabs/font-icons-page.xml b/e2e/ui-tests-app/app/tabs/font-icons-page.xml
index 317d5def4..0a31a8d76 100644
--- a/e2e/ui-tests-app/app/tabs/font-icons-page.xml
+++ b/e2e/ui-tests-app/app/tabs/font-icons-page.xml
@@ -3,32 +3,61 @@
-
+
-
-
+
+
+
+
+
+
-
+
+
+
+
+
-
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/e2e/ui-tests-app/app/tabs/font-page.css b/e2e/ui-tests-app/app/tabs/font-page.css
index 1e28cb2a5..d2473e4d7 100644
--- a/e2e/ui-tests-app/app/tabs/font-page.css
+++ b/e2e/ui-tests-app/app/tabs/font-page.css
@@ -17,3 +17,11 @@ TabStripItem.special {
TabStripItem.special:active {
font: 16 monospace;
}
+
+TabStripItem.nested Label {
+ font: 12 monospace;
+}
+
+TabStripItem.nested:active Label {
+ font: 16 monospace;
+}
diff --git a/e2e/ui-tests-app/app/tabs/font-page.xml b/e2e/ui-tests-app/app/tabs/font-page.xml
index a0c8bfa60..ee9003d98 100644
--- a/e2e/ui-tests-app/app/tabs/font-page.xml
+++ b/e2e/ui-tests-app/app/tabs/font-page.xml
@@ -1,12 +1,15 @@
-
+
-
-
+
+
+
+
+
@@ -20,5 +23,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/e2e/ui-tests-app/app/tabs/icon-change-page.ts b/e2e/ui-tests-app/app/tabs/icon-change-page.ts
index 1a466d6a6..cf4e24af1 100644
--- a/e2e/ui-tests-app/app/tabs/icon-change-page.ts
+++ b/e2e/ui-tests-app/app/tabs/icon-change-page.ts
@@ -6,10 +6,12 @@ export function onSelectedIndexChanged(args: SelectedIndexChangedEventData) {
const newItem = tabsNav.tabStrip.items[args.newIndex];
if (newItem) {
newItem.iconSource = "res://icon";
+ newItem.title = "selected";
}
const oldItem = tabsNav.tabStrip.items[args.oldIndex];
if (oldItem) {
oldItem.iconSource = "res://testlogo";
+ oldItem.title = "unselected";
}
}
diff --git a/e2e/ui-tests-app/app/tabs/icon-change-page.xml b/e2e/ui-tests-app/app/tabs/icon-change-page.xml
index 28f78dc9f..9dc1ede30 100644
--- a/e2e/ui-tests-app/app/tabs/icon-change-page.xml
+++ b/e2e/ui-tests-app/app/tabs/icon-change-page.xml
@@ -4,8 +4,8 @@
-
-
+
+
diff --git a/e2e/ui-tests-app/app/tabs/tabs-binding-view-model.ts b/e2e/ui-tests-app/app/tabs/tabs-binding-view-model.ts
index 18a51c893..531961775 100644
--- a/e2e/ui-tests-app/app/tabs/tabs-binding-view-model.ts
+++ b/e2e/ui-tests-app/app/tabs/tabs-binding-view-model.ts
@@ -53,7 +53,7 @@ export class TabsBindingNavigationViewModel extends Observable {
const gridlayout = new GridLayout();
label.text = "Content Item " + index;
gridlayout.addChild(label);
- contentItem.view = gridlayout;
+ contentItem.content = gridlayout;
return contentItem;
}
diff --git a/e2e/ui-tests-app/app/tabs/text-transform-page.css b/e2e/ui-tests-app/app/tabs/text-transform-page.css
index db5fd0e50..ebbc005bd 100644
--- a/e2e/ui-tests-app/app/tabs/text-transform-page.css
+++ b/e2e/ui-tests-app/app/tabs/text-transform-page.css
@@ -17,3 +17,11 @@ TabStripItem.special {
TabStripItem.special:active {
text-transform: uppercase;
}
+
+TabStripItem.nested Label {
+ text-transform: lowercase;
+}
+
+TabStripItem.nested:active Label {
+ text-transform: uppercase;
+}
diff --git a/e2e/ui-tests-app/app/tabs/text-transform-page.xml b/e2e/ui-tests-app/app/tabs/text-transform-page.xml
index c80979319..aa9ea5bf3 100644
--- a/e2e/ui-tests-app/app/tabs/text-transform-page.xml
+++ b/e2e/ui-tests-app/app/tabs/text-transform-page.xml
@@ -1,12 +1,15 @@
-
+
-
+
+
+
+
@@ -20,5 +23,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/app/ui/bottom-navigation/bottom-navigation-navigation-tests.ts b/tests/app/ui/bottom-navigation/bottom-navigation-navigation-tests.ts
index c1ed2b09c..a72d3e2e6 100644
--- a/tests/app/ui/bottom-navigation/bottom-navigation-navigation-tests.ts
+++ b/tests/app/ui/bottom-navigation/bottom-navigation-navigation-tests.ts
@@ -23,7 +23,7 @@ function _createContentItems(count: number): Array {
const label = new Label();
label.text = "Tab " + i;
const tabEntry = new TabContentItem();
- tabEntry.view = label;
+ tabEntry.content = label;
items.push(tabEntry);
}
@@ -101,12 +101,12 @@ export function testBackNavigationToTabViewWithNestedFramesShouldWork() {
let items = Array();
let tabViewitem = new TabContentItem();
// tabViewitem.title = "Item1";
- tabViewitem.view = _createFrameView();
+ tabViewitem.content = _createFrameView();
items.push(tabViewitem);
let tabViewitem2 = new TabContentItem();
// tabViewitem2.title = "Item2";
- tabViewitem2.view = _createFrameView();
+ tabViewitem2.content = _createFrameView();
items.push(tabViewitem2);
tabView.items = items;
@@ -145,7 +145,7 @@ export function testWhenNavigatingBackToANonCachedPageContainingATabViewWithALis
let items = Array();
let tabViewitem = new TabContentItem();
// tabViewitem.title = "List";
- tabViewitem.view = _createListView();
+ tabViewitem.content = _createListView();
items.push(tabViewitem);
let label = new Label();
@@ -155,7 +155,7 @@ export function testWhenNavigatingBackToANonCachedPageContainingATabViewWithALis
aboutLayout.addChild(label);
tabViewitem = new TabContentItem();
// tabViewitem.title = "About";
- tabViewitem.view = aboutLayout;
+ tabViewitem.content = aboutLayout;
items.push(tabViewitem);
tabView.items = items;
@@ -184,7 +184,7 @@ export function testWhenNavigatingBackToANonCachedPageContainingATabViewWithALis
TKUnit.waitUntilReady(() => topFrame.currentPage === rootPage);
- TKUnit.assert(tabView.items[0].view instanceof ListView, "ListView should be created when navigating back to the main page.");
+ TKUnit.assert(tabView.items[0].content instanceof ListView, "ListView should be created when navigating back to the main page.");
}
function tabViewIsFullyLoaded(tabView: BottomNavigation): boolean {
@@ -232,8 +232,8 @@ export function testLoadedAndUnloadedAreFired_WhenNavigatingAwayAndBack() {
}
tabView.items.forEach((item, i) => {
- item.view.on("loaded", createLoadedFor(i));
- item.view.on("unloaded", createUnloadedFor(i));
+ item.content.on("loaded", createLoadedFor(i));
+ item.content.on("unloaded", createUnloadedFor(i));
});
const tabViewPage = new Page();
@@ -252,8 +252,8 @@ export function testLoadedAndUnloadedAreFired_WhenNavigatingAwayAndBack() {
TKUnit.assertEqual(topFrame.currentPage, tabViewPage);
for (let i = 0; i < itemCount; i++) {
- tabView.items[i].view.off("loaded");
- tabView.items[i].view.off("unloaded");
+ tabView.items[i].content.off("loaded");
+ tabView.items[i].content.off("unloaded");
}
helper.goBack();
@@ -267,7 +267,7 @@ export function testLoadedAndUnloadedAreFired_WhenNavigatingAwayAndBack() {
function _clickTheFirstButtonInTheListViewNatively(tabView: BottomNavigation) {
if (tabView.android) {
- const androidListView = tabView.items[0].view.nativeView;
+ const androidListView = tabView.items[0].content.nativeView;
// var viewPager: android.support.v4.view.ViewPager = (tabView)._viewPager;
// var androidListView = viewPager.getChildAt(0);
var stackLayout = androidListView.getChildAt(0);
diff --git a/tests/app/ui/bottom-navigation/bottom-navigation-root-tests.ts b/tests/app/ui/bottom-navigation/bottom-navigation-root-tests.ts
index 39bccdb96..c92841c23 100644
--- a/tests/app/ui/bottom-navigation/bottom-navigation-root-tests.ts
+++ b/tests/app/ui/bottom-navigation/bottom-navigation-root-tests.ts
@@ -47,7 +47,7 @@ function createFrame(i: number, page: Page) {
function createTabItem(i: number, frame: Frame) {
const tabEntry = new TabContentItem();
// tabEntry.title = "Tab " + i;
- tabEntry.view = frame;
+ tabEntry.content = frame;
tabEntry["index"] = i;
return tabEntry;
diff --git a/tests/app/ui/bottom-navigation/bottom-navigation-tests.ts b/tests/app/ui/bottom-navigation/bottom-navigation-tests.ts
index 5678dbdcf..c0afbaf0d 100644
--- a/tests/app/ui/bottom-navigation/bottom-navigation-tests.ts
+++ b/tests/app/ui/bottom-navigation/bottom-navigation-tests.ts
@@ -27,7 +27,7 @@ export class BottomNavigationTest extends UITest {
const label = new Label();
label.text = "Tab " + i;
const tabEntry = new TabContentItem();
- tabEntry.view = label;
+ tabEntry.content = label;
items.push(tabEntry);
}
@@ -208,7 +208,7 @@ export class BottomNavigationTest extends UITest {
TKUnit.assertThrows(() => {
let item = new TabContentItem();
// item.title = "Tab 0";
- item.view = undefined;
+ item.content = undefined;
tabView.items = [item];
}, "Binding TabNavigation to a TabItem with undefined view should throw.");
@@ -221,7 +221,7 @@ export class BottomNavigationTest extends UITest {
TKUnit.assertThrows(() => {
let item = new TabContentItem();
// item.title = "Tab 0";
- item.view = null;
+ item.content = null;
tabView.items = [item];
}, "Binding TabNavigation to a TabItem with null view should throw.");
diff --git a/tests/app/ui/tabs/tabs-navigation-tests.ts b/tests/app/ui/tabs/tabs-navigation-tests.ts
index 8489663d1..03e8ca191 100644
--- a/tests/app/ui/tabs/tabs-navigation-tests.ts
+++ b/tests/app/ui/tabs/tabs-navigation-tests.ts
@@ -23,7 +23,7 @@ function _createContentItems(count: number): Array {
const label = new Label();
label.text = "Tab " + i;
const tabEntry = new TabContentItem();
- tabEntry.view = label;
+ tabEntry.content = label;
items.push(tabEntry);
}
@@ -101,12 +101,12 @@ export function testBackNavigationToTabViewWithNestedFramesShouldWork() {
let items = Array();
let tabViewitem = new TabContentItem();
// tabViewitem.title = "Item1";
- tabViewitem.view = _createFrameView();
+ tabViewitem.content = _createFrameView();
items.push(tabViewitem);
let tabViewitem2 = new TabContentItem();
// tabViewitem2.title = "Item2";
- tabViewitem2.view = _createFrameView();
+ tabViewitem2.content = _createFrameView();
items.push(tabViewitem2);
tabView.items = items;
@@ -145,7 +145,7 @@ export function testWhenNavigatingBackToANonCachedPageContainingATabViewWithALis
let items = Array();
let tabViewitem = new TabContentItem();
// tabViewitem.title = "List";
- tabViewitem.view = _createListView();
+ tabViewitem.content = _createListView();
items.push(tabViewitem);
let label = new Label();
@@ -155,7 +155,7 @@ export function testWhenNavigatingBackToANonCachedPageContainingATabViewWithALis
aboutLayout.addChild(label);
tabViewitem = new TabContentItem();
// tabViewitem.title = "About";
- tabViewitem.view = aboutLayout;
+ tabViewitem.content = aboutLayout;
items.push(tabViewitem);
tabView.items = items;
@@ -184,7 +184,7 @@ export function testWhenNavigatingBackToANonCachedPageContainingATabViewWithALis
TKUnit.waitUntilReady(() => topFrame.currentPage === rootPage);
- TKUnit.assert(tabView.items[0].view instanceof ListView, "ListView should be created when navigating back to the main page.");
+ TKUnit.assert(tabView.items[0].content instanceof ListView, "ListView should be created when navigating back to the main page.");
}
function tabViewIsFullyLoaded(tabView: Tabs): boolean {
@@ -232,8 +232,8 @@ export function testLoadedAndUnloadedAreFired_WhenNavigatingAwayAndBack() {
}
tabView.items.forEach((item, i) => {
- item.view.on("loaded", createLoadedFor(i));
- item.view.on("unloaded", createUnloadedFor(i));
+ item.content.on("loaded", createLoadedFor(i));
+ item.content.on("unloaded", createUnloadedFor(i));
});
const tabViewPage = new Page();
@@ -252,8 +252,8 @@ export function testLoadedAndUnloadedAreFired_WhenNavigatingAwayAndBack() {
TKUnit.assertEqual(topFrame.currentPage, tabViewPage);
for (let i = 0; i < itemCount; i++) {
- tabView.items[i].view.off("loaded");
- tabView.items[i].view.off("unloaded");
+ tabView.items[i].content.off("loaded");
+ tabView.items[i].content.off("unloaded");
}
helper.goBack();
@@ -267,7 +267,7 @@ export function testLoadedAndUnloadedAreFired_WhenNavigatingAwayAndBack() {
function _clickTheFirstButtonInTheListViewNatively(tabView: Tabs) {
if (tabView.android) {
- const androidListView = tabView.items[0].view.nativeView;
+ const androidListView = tabView.items[0].content.nativeView;
// var viewPager: android.support.v4.view.ViewPager = (tabView)._viewPager;
// var androidListView = viewPager.getChildAt(0);
var stackLayout = androidListView.getChildAt(0);
diff --git a/tests/app/ui/tabs/tabs-root-tests.ts b/tests/app/ui/tabs/tabs-root-tests.ts
index 594f4622b..c06f6d0db 100644
--- a/tests/app/ui/tabs/tabs-root-tests.ts
+++ b/tests/app/ui/tabs/tabs-root-tests.ts
@@ -35,7 +35,7 @@ function createFrame(i: number, page: Page) {
function createTabItem(i: number, frame: Frame) {
const tabEntry = new TabContentItem();
// tabEntry.title = "Tab " + i;
- tabEntry.view = frame;
+ tabEntry.content = frame;
tabEntry["index"] = i;
return tabEntry;
diff --git a/tests/app/ui/tabs/tabs-tests.ts b/tests/app/ui/tabs/tabs-tests.ts
index edb848bdc..2e5d34de6 100644
--- a/tests/app/ui/tabs/tabs-tests.ts
+++ b/tests/app/ui/tabs/tabs-tests.ts
@@ -27,7 +27,7 @@ export class TabsTest extends UITest {
const label = new Label();
label.text = "Tab " + i;
const tabEntry = new TabContentItem();
- tabEntry.view = label;
+ tabEntry.content = label;
items.push(tabEntry);
}
@@ -210,7 +210,7 @@ export class TabsTest extends UITest {
TKUnit.assertThrows(() => {
let item = new TabContentItem();
// item.title = "Tab 0";
- item.view = undefined;
+ item.content = undefined;
tabView.items = [item];
}, "Binding TabNavigation to a TabItem with undefined view should throw.");
@@ -223,7 +223,7 @@ export class TabsTest extends UITest {
TKUnit.assertThrows(() => {
let item = new TabContentItem();
// item.title = "Tab 0";
- item.view = null;
+ item.content = null;
tabView.items = [item];
}, "Binding TabNavigation to a TabItem with null view should throw.");
diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java
index 29a5c0492..4e2cd7eeb 100644
--- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java
+++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java
@@ -201,6 +201,19 @@ public class BottomNavigationBar extends LinearLayout {
if (tabItem.title != null && !tabItem.title.isEmpty()) {
textView.setText(tabItem.title);
textView.setVisibility(VISIBLE);
+
+ if (tabItem.typeFace != null) {
+ textView.setTypeface(tabItem.typeFace);
+ }
+
+ if (tabItem.fontSize != 0) {
+ textView.setTextSize(tabItem.fontSize);
+ }
+
+ if (tabItem.color != 0) {
+ textView.setTextColor(tabItem.color);
+ mTabStrip.setShouldUpdateTabsTextColor(false);
+ }
} else {
textView.setVisibility(GONE);
}
diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabItemSpec.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabItemSpec.java
index 2aa6ff08b..1494e407f 100644
--- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabItemSpec.java
+++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabItemSpec.java
@@ -1,10 +1,14 @@
package org.nativescript.widgets;
import android.graphics.drawable.Drawable;
+import android.graphics.Typeface;
public class TabItemSpec {
public String title;
+ public int fontSize;
+ public Typeface typeFace;
public int iconId;
public Drawable iconDrawable;
public int backgroundColor;
+ public int color;
}
\ No newline at end of file
diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabStrip.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabStrip.java
index 557be52a1..37cb21c13 100644
--- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabStrip.java
+++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabStrip.java
@@ -52,6 +52,8 @@ class TabStrip extends LinearLayout {
private int mSelectedTabTextColor;
private float mTabTextFontSize;
+ private boolean mShouldUpdateTabsTextColor;
+
TabStrip(Context context) {
this(context, null);
}
@@ -87,6 +89,8 @@ class TabStrip extends LinearLayout {
// Default selected color is the same as mTabTextColor
mSelectedTabTextColor = mTabTextColor;
+ mShouldUpdateTabsTextColor = true;
+
setMeasureWithLargestChildEnabled(true);
}
@@ -120,16 +124,22 @@ class TabStrip extends LinearLayout {
return mSelectedTabTextColor;
}
+ void setShouldUpdateTabsTextColor(boolean value) {
+ mShouldUpdateTabsTextColor = value;
+ }
+
private void updateTabsTextColor(){
- final int childCount = getChildCount();
- for (int i = 0; i < childCount; i++){
- LinearLayout linearLayout = (LinearLayout)getChildAt(i);
- TextView textView = (TextView)linearLayout.getChildAt(1);
- if (i == mSelectedPosition){
- textView.setTextColor(mSelectedTabTextColor);
- }
- else {
- textView.setTextColor(mTabTextColor);
+ if (mShouldUpdateTabsTextColor) {
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++){
+ LinearLayout linearLayout = (LinearLayout)getChildAt(i);
+ TextView textView = (TextView)linearLayout.getChildAt(1);
+ if (i == mSelectedPosition){
+ textView.setTextColor(mSelectedTabTextColor);
+ }
+ else {
+ textView.setTextColor(mTabTextColor);
+ }
}
}
}
diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabsBar.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabsBar.java
index c53661cc7..20dfdfd0c 100644
--- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabsBar.java
+++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabsBar.java
@@ -252,7 +252,6 @@ public class TabsBar extends HorizontalScrollView {
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
textView.setTypeface(Typeface.DEFAULT_BOLD);
textView.setEllipsize(TextUtils.TruncateAt.END);
- textView.setAllCaps(true);
textView.setMaxLines(2);
textView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
textView.setPadding(padding, 0, padding, 0);
@@ -280,6 +279,19 @@ public class TabsBar extends HorizontalScrollView {
if (tabItem.title != null && !tabItem.title.isEmpty()) {
textView.setText(tabItem.title);
textView.setVisibility(VISIBLE);
+
+ if (tabItem.typeFace != null) {
+ textView.setTypeface(tabItem.typeFace);
+ }
+
+ if (tabItem.fontSize != 0) {
+ textView.setTextSize(tabItem.fontSize);
+ }
+
+ if (tabItem.color != 0) {
+ textView.setTextColor(tabItem.color);
+ mTabStrip.setShouldUpdateTabsTextColor(false);
+ }
} else {
textView.setVisibility(GONE);
}
diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts
index 8cca2d108..e229ce202 100644
--- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts
+++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts
@@ -85,7 +85,7 @@ function initializeNativeClasses() {
public onCreateView(inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle): android.view.View {
const tabItem = this.tab.items[this.index];
- return tabItem.view.nativeViewProtected;
+ return tabItem.nativeViewProtected;
}
}
@@ -167,43 +167,58 @@ function initializeNativeClasses() {
}
function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets.TabItemSpec {
- let iconSource;
const tabItemSpec = new org.nativescript.widgets.TabItemSpec();
- // Image and Label children of TabStripItem
- // take priority over its `iconSource` and `title` properties
- iconSource = tabStripItem.image ? tabStripItem.image.src : tabStripItem.iconSource;
- tabItemSpec.title = tabStripItem.label ? tabStripItem.label.text : tabStripItem.title;
+ if (tabStripItem.isLoaded) {
+ const titleLabel = tabStripItem.label;
+ let title = titleLabel.text;
- if (tabStripItem.backgroundColor instanceof Color) {
- tabItemSpec.backgroundColor = tabStripItem.backgroundColor.android;
- }
+ // TEXT-TRANSFORM
+ const textTransform = titleLabel.style.textTransform;
+ if (textTransform) {
+ title = getTransformedText(title, textTransform);
+ }
+ tabItemSpec.title = title;
- if (iconSource) {
- if (iconSource.indexOf(RESOURCE_PREFIX) === 0) {
- tabItemSpec.iconId = ad.resources.getDrawableId(iconSource.substr(RESOURCE_PREFIX.length));
- if (tabItemSpec.iconId === 0) {
- // TODO:
- // traceMissingIcon(iconSource);
- }
- } else {
- let is = new ImageSource();
- if (isFontIconURI(tabStripItem.iconSource)) {
- const fontIconCode = tabStripItem.iconSource.split("//")[1];
- const font = tabStripItem.style.fontInternal;
- const color = tabStripItem.style.color;
- is = fromFontIconCode(fontIconCode, font, color);
+ // BACKGROUND-COLOR
+ const backgroundColor = tabStripItem.style.backgroundColor;
+ if (backgroundColor) {
+ tabItemSpec.backgroundColor = backgroundColor.android;
+ }
+
+ // COLOR
+ const color = titleLabel.style.color;
+ if (color) {
+ tabItemSpec.color = color.android;
+ }
+
+ // FONT
+ const fontInternal = titleLabel.style.fontInternal;
+ if (fontInternal) {
+ tabItemSpec.fontSize = fontInternal.fontSize;
+ tabItemSpec.typeFace = fontInternal.getAndroidTypeface();
+ }
+
+ // ICON
+ const iconSource = tabStripItem.image && tabStripItem.image.src;
+ if (iconSource) {
+ if (iconSource.indexOf(RESOURCE_PREFIX) === 0) {
+ tabItemSpec.iconId = ad.resources.getDrawableId(iconSource.substr(RESOURCE_PREFIX.length));
+ if (tabItemSpec.iconId === 0) {
+ // TODO:
+ // traceMissingIcon(iconSource);
+ }
} else {
- is = fromFileOrResource(tabStripItem.iconSource);
- }
+ const icon = _getIcon(tabStripItem);
- if (is) {
- // TODO: Make this native call that accepts string so that we don't load Bitmap in JS.
- // tslint:disable-next-line:deprecation
- tabItemSpec.iconDrawable = new android.graphics.drawable.BitmapDrawable(application.android.context.getResources(), is.android);
- } else {
- // TODO:
- // traceMissingIcon(iconSource);
+ if (icon) {
+ // TODO: Make this native call that accepts string so that we don't load Bitmap in JS.
+ // tslint:disable-next-line:deprecation
+ tabItemSpec.iconDrawable = icon;
+ } else {
+ // TODO:
+ // traceMissingIcon(iconSource);
+ }
}
}
}
@@ -211,11 +226,29 @@ function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets
return tabItemSpec;
}
-function setElevation(grid: org.nativescript.widgets.GridLayout, bottomNavigationBar: org.nativescript.widgets.BottomNavigationBar) {
+function _getIcon(tabStripItem: TabStripItem): android.graphics.drawable.BitmapDrawable {
+ const iconSource = tabStripItem.image && tabStripItem.image.src;
+
+ let is: ImageSource;
+ if (isFontIconURI(iconSource)) {
+ const fontIconCode = iconSource.split("//")[1];
+ const target = tabStripItem.image ? tabStripItem.image : tabStripItem;
+ const font = target.style.fontInternal;
+ const color = target.style.color;
+ is = fromFontIconCode(fontIconCode, font, color);
+ } else {
+ is = fromFileOrResource(iconSource);
+ }
+
+ const image = new android.graphics.drawable.BitmapDrawable(application.android.context.getResources(), is.android);
+
+ return image;
+}
+
+function setElevation(bottomNavigationBar: org.nativescript.widgets.BottomNavigationBar) {
const compat = androidx.core.view.ViewCompat;
if (compat.setElevation) {
const val = DEFAULT_ELEVATION * layout.getDisplayDensity();
- compat.setElevation(grid, val);
compat.setElevation(bottomNavigationBar, val);
}
}
@@ -288,7 +321,7 @@ export class BottomNavigation extends TabNavigationBase {
nativeView.addView(bottomNavigationBar);
(nativeView).bottomNavigationBar = bottomNavigationBar;
- setElevation(nativeView, bottomNavigationBar);
+ setElevation(bottomNavigationBar);
const primaryColor = ad.resources.getPaletteColor(PRIMARY_COLOR, context);
if (primaryColor) {
@@ -341,12 +374,12 @@ export class BottomNavigation extends TabNavigationBase {
toUnload.forEach(index => {
const item = items[index];
if (items[index]) {
- item.unloadView(item.view);
+ item.unloadView(item.content);
}
});
const newItem = items[newIndex];
- const selectedView = newItem && newItem.view;
+ const selectedView = newItem && newItem.content;
if (selectedView instanceof Frame) {
selectedView._pushInFrameStackRecursive();
}
@@ -354,7 +387,7 @@ export class BottomNavigation extends TabNavigationBase {
toLoad.forEach(index => {
const item = items[index];
if (this.isLoaded && items[index]) {
- item.loadView(item.view);
+ item.loadView(item.content);
}
});
}
@@ -562,18 +595,11 @@ export class BottomNavigation extends TabNavigationBase {
}
}
- public getTabBarColor(): number {
- return this._bottomNavigationBar.getTabTextColor();
- }
-
- public setTabBarColor(value: number | Color): void {
- if (value instanceof Color) {
- this._bottomNavigationBar.setTabTextColor(value.android);
- this._bottomNavigationBar.setSelectedTabTextColor(value.android);
- } else {
- this._bottomNavigationBar.setTabTextColor(value);
- this._bottomNavigationBar.setSelectedTabTextColor(value);
- }
+ public setTabBarItemTitle(tabStripItem: TabStripItem, value: string): void {
+ // TODO: Should figure out a way to do it directly with the the nativeView
+ const tabStripItemIndex = this.tabStrip.items.indexOf(tabStripItem);
+ const tabItemSpec = createTabItemSpec(tabStripItem);
+ this.updateAndroidItemAt(tabStripItemIndex, tabItemSpec);
}
public setTabBarItemBackgroundColor(tabStripItem: TabStripItem, value: android.graphics.drawable.Drawable | Color): void {
@@ -583,10 +609,6 @@ export class BottomNavigation extends TabNavigationBase {
this.updateAndroidItemAt(tabStripItemIndex, tabItemSpec);
}
- public getTabBarItemColor(tabStripItem: TabStripItem): number {
- return tabStripItem.nativeViewProtected.getCurrentTextColor();
- }
-
public setTabBarItemColor(tabStripItem: TabStripItem, value: number | Color): void {
if (typeof value === "number") {
tabStripItem.nativeViewProtected.setTextColor(value);
@@ -595,45 +617,24 @@ export class BottomNavigation extends TabNavigationBase {
}
}
- public getTabBarItemFontSize(tabStripItem: TabStripItem): { nativeSize: number } {
- return { nativeSize: tabStripItem.nativeViewProtected.getTextSize() };
+ public setTabBarIconColor(tabStripItem: TabStripItem, value: number | Color): void {
+ const index = (tabStripItem).index;
+ const tabBarItem = this._bottomNavigationBar.getViewForItemAt(index);
+ const imgView = tabBarItem.getChildAt(0);
+ const drawable = _getIcon(tabStripItem);
+
+ imgView.setImageDrawable(drawable);
}
- public setTabBarItemFontSize(tabStripItem: TabStripItem, value: number | { nativeSize: number }): void {
- if (typeof value === "number") {
- tabStripItem.nativeViewProtected.setTextSize(value);
- } else {
- tabStripItem.nativeViewProtected.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, value.nativeSize);
- }
+ public setTabBarItemFontInternal(tabStripItem: TabStripItem, value: Font): void {
+ tabStripItem.nativeViewProtected.setTextSize(value.fontSize);
+ tabStripItem.nativeViewProtected.setTypeface(value.getAndroidTypeface());
}
- public getTabBarItemFontInternal(tabStripItem: TabStripItem): android.graphics.Typeface {
- return tabStripItem.nativeViewProtected.getTypeface();
- }
-
- public setTabBarItemFontInternal(tabStripItem: TabStripItem, value: Font | android.graphics.Typeface): void {
- tabStripItem.nativeViewProtected.setTypeface(value instanceof Font ? value.getAndroidTypeface() : value);
- }
-
- private _defaultTransformationMethod: android.text.method.TransformationMethod;
-
- public getTabBarItemTextTransform(tabStripItem: TabStripItem): "default" {
- return "default";
- }
-
- public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform | "default"): void {
- const tv = tabStripItem.nativeViewProtected;
-
- this._defaultTransformationMethod = this._defaultTransformationMethod || tv.getTransformationMethod();
-
- if (value === "default") {
- tv.setTransformationMethod(this._defaultTransformationMethod);
- tv.setText(tabStripItem.title);
- } else {
- const result = getTransformedText(tabStripItem.title, value);
- tv.setText(result);
- tv.setTransformationMethod(null);
- }
+ public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform): void {
+ const titleLabel = tabStripItem.label;
+ const title = getTransformedText(titleLabel.text, value);
+ tabStripItem.nativeViewProtected.setText(title);
}
[selectedIndexProperty.setNative](value: number) {
diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts
index e3daa9470..62d0c26d7 100644
--- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts
+++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts
@@ -259,8 +259,10 @@ export class BottomNavigation extends TabNavigationBase {
public onLoaded() {
super.onLoaded();
+ this.setViewControllers(this.items);
+
const selectedIndex = this.selectedIndex;
- const selectedView = this.items && this.items[selectedIndex] && this.items[selectedIndex].view;
+ const selectedView = this.items && this.items[selectedIndex] && this.items[selectedIndex].content;
if (selectedView instanceof Frame) {
selectedView._pushInFrameStackRecursive();
}
@@ -295,18 +297,18 @@ export class BottomNavigation extends TabNavigationBase {
const oldItem = items[oldIndex];
if (oldItem) {
oldItem.canBeLoaded = false;
- oldItem.unloadView(oldItem.view);
+ oldItem.unloadView(oldItem.content);
}
const newItem = items[newIndex];
if (newItem && this.isLoaded) {
- const selectedView = items[newIndex].view;
+ const selectedView = items[newIndex].content;
if (selectedView instanceof Frame) {
selectedView._pushInFrameStackRecursive();
}
newItem.canBeLoaded = true;
- newItem.loadView(newItem.view);
+ newItem.loadView(newItem.content);
}
super.onSelectedIndexChanged(oldIndex, newIndex);
@@ -320,21 +322,8 @@ export class BottomNavigation extends TabNavigationBase {
this._ios.tabBar.barTintColor = value instanceof Color ? value.ios : value;
}
- public getTabBarColor(): UIColor {
- return this._ios.tabBar.tintColor;
- }
-
- public setTabBarColor(value: UIColor | Color): void {
- this._ios.tabBar.tintColor = value instanceof Color ? value.ios : value;
-
- if (!this.tabStrip) {
- return;
- }
-
- const states = getTitleAttributesForStates(this.tabStrip);
- this.tabStrip.items.forEach((tabStripItem) => {
- applyStatesToItem(tabStripItem.nativeView, states);
- });
+ public setTabBarItemTitle(tabStripItem: TabStripItem, value: string): void {
+ tabStripItem.nativeView.title = value;
}
public setTabBarItemBackgroundColor(tabStripItem: TabStripItem, value: UIColor | Color): void {
@@ -355,39 +344,25 @@ export class BottomNavigation extends TabNavigationBase {
bgView.backgroundColor = value instanceof Color ? value.ios : value;
}
- public getTabBarItemColor(tabStripItem: TabStripItem): UIColor {
- return this._ios.tabBar.tintColor;
- }
-
public setTabBarItemColor(tabStripItem: TabStripItem, value: UIColor | Color): void {
- const states = getTitleAttributesForStates(tabStripItem);
+ const states = getTitleAttributesForStates(tabStripItem.label);
applyStatesToItem(tabStripItem.nativeView, states);
}
- public getTabBarItemFontSize(tabStripItem: TabStripItem): number {
- return null;
- }
+ public setTabBarIconColor(tabStripItem: TabStripItem, value: UIColor | Color): void {
+ const image = this._getIcon(tabStripItem);
- public setTabBarItemFontSize(tabStripItem: TabStripItem, value: number | { nativeSize: number }): void {
- const states = getTitleAttributesForStates(tabStripItem);
- applyStatesToItem(tabStripItem.nativeView, states);
- }
-
- public getTabBarItemFontInternal(tabStripItem: TabStripItem): Font {
- return null;
+ tabStripItem.nativeView.image = image;
+ tabStripItem.nativeView.selectedImage = image;
}
public setTabBarItemFontInternal(tabStripItem: TabStripItem, value: Font): void {
- const states = getTitleAttributesForStates(tabStripItem);
+ const states = getTitleAttributesForStates(tabStripItem.label);
applyStatesToItem(tabStripItem.nativeView, states);
}
- public getTabBarItemTextTransform(tabStripItem: TabStripItem): TextTransform {
- return null;
- }
-
public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform): void {
- const title = getTransformedText(tabStripItem.title, value);
+ const title = getTransformedText(tabStripItem.label.text, value);
tabStripItem.nativeView.title = title;
}
@@ -463,7 +438,7 @@ export class BottomNavigation extends TabNavigationBase {
}
private getViewController(item: TabContentItem): UIViewController {
- let newController: UIViewController = item.view ? item.view.viewController : null;
+ let newController: UIViewController = item.content ? item.content.viewController : null;
if (newController) {
(item).setViewController(newController, newController.view);
@@ -471,17 +446,17 @@ export class BottomNavigation extends TabNavigationBase {
return newController;
}
- if (item.view.ios instanceof UIViewController) {
- newController = item.view.ios;
+ if (item.content.ios instanceof UIViewController) {
+ newController = item.content.ios;
(item).setViewController(newController, newController.view);
- } else if (item.view.ios && item.view.ios.controller instanceof UIViewController) {
- newController = item.view.ios.controller;
+ } else if (item.content.ios && item.content.ios.controller instanceof UIViewController) {
+ newController = item.content.ios.controller;
(item).setViewController(newController, newController.view);
} else {
- newController = iosView.UILayoutViewController.initWithOwner(new WeakRef(item.view)) as UIViewController;
- newController.view.addSubview(item.view.nativeViewProtected);
- item.view.viewController = newController;
- (item).setViewController(newController, item.view.nativeViewProtected);
+ newController = iosView.UILayoutViewController.initWithOwner(new WeakRef(item.content)) as UIViewController;
+ newController.view.addSubview(item.content.nativeViewProtected);
+ item.content.viewController = newController;
+ (item).setViewController(newController, item.content.nativeViewProtected);
}
return newController;
@@ -499,7 +474,6 @@ export class BottomNavigation extends TabNavigationBase {
items = items.slice(0, maxTabsCount);
const controllers = NSMutableArray.alloc().initWithCapacity(length);
- const states = getTitleAttributesForStates(this);
if (this.tabStrip) {
this.tabStrip.setNativeView(this._ios.tabBar);
@@ -513,6 +487,7 @@ export class BottomNavigation extends TabNavigationBase {
const tabBarItem = this.createTabBarItem(tabStripItem, i);
updateTitleAndIconPositions(tabStripItem, tabBarItem, controller);
+ const states = getTitleAttributesForStates(tabStripItem.label);
applyStatesToItem(tabBarItem, states);
controller.tabBarItem = tabBarItem;
@@ -534,8 +509,15 @@ export class BottomNavigation extends TabNavigationBase {
let image: UIImage;
let title: string;
- image = this._getIcon(item);
- title = item.label ? item.label.text : item.title;
+ if (item.isLoaded) {
+ image = this._getIcon(item);
+ title = item.label.text;
+
+ const textTransform = item.label.style.textTransform;
+ if (textTransform) {
+ title = getTransformedText(title, textTransform);
+ }
+ }
const tabBarItem = UITabBarItem.alloc().initWithTitleImageTag(title, image, index);
@@ -549,18 +531,21 @@ export class BottomNavigation extends TabNavigationBase {
public _getIcon(tabStripItem: TabStripItem): UIImage {
// Image and Label children of TabStripItem
// take priority over its `iconSource` and `title` properties
- const iconSource = tabStripItem.image ? tabStripItem.image.src : tabStripItem.iconSource;
+ const iconSource = tabStripItem.image && tabStripItem.image.src;
if (!iconSource) {
return null;
}
- let image: UIImage = this._iconsCache[iconSource];
+ const target = tabStripItem.image;
+ const font = target.style.fontInternal;
+ const color = target.style.color;
+ const iconTag = [iconSource, font.fontStyle, font.fontWeight, font.fontSize, font.fontFamily, color].join(";");
+
+ let image: UIImage = this._iconsCache[iconTag];
if (!image) {
let is = new ImageSource;
if (isFontIconURI(iconSource)) {
const fontIconCode = iconSource.split("//")[1];
- const font = tabStripItem.style.fontInternal;
- const color = tabStripItem.style.color;
is = fromFontIconCode(fontIconCode, font, color);
} else {
is = fromFileOrResource(iconSource);
@@ -568,7 +553,7 @@ export class BottomNavigation extends TabNavigationBase {
if (is && is.ios) {
const originalRenderedImage = is.ios.imageWithRenderingMode(this._getIconRenderingMode());
- this._iconsCache[iconSource] = originalRenderedImage;
+ this._iconsCache[iconTag] = originalRenderedImage;
image = originalRenderedImage;
} else {
// TODO
@@ -615,6 +600,12 @@ export class BottomNavigation extends TabNavigationBase {
return null;
}
[itemsProperty.setNative](value: TabContentItem[]) {
+ if (value) {
+ value.forEach((item: TabContentItem, i) => {
+ (item).index = i;
+ });
+ }
+
this.setViewControllers(value);
selectedIndexProperty.coerce(this);
}
diff --git a/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item-common.ts b/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item-common.ts
index 71741dd3c..024febd0a 100644
--- a/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item-common.ts
+++ b/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item-common.ts
@@ -5,38 +5,15 @@ import { TabNavigationBase } from "../tab-navigation-base";
// Requires
import { View, ViewBase, CSSType } from "../../core/view";
-
+import { ContentView } from "../../content-view";
export const traceCategory = "TabView";
@CSSType("TabContentItem")
-export abstract class TabContentItemBase extends ViewBase implements TabContentItemDefinition, AddChildFromBuilder {
- private _view: View;
+export abstract class TabContentItemBase extends ContentView implements TabContentItemDefinition, AddChildFromBuilder {
- public _addChildFromBuilder(name: string, value: any): void {
- if (value instanceof View) {
- this.view = value;
- }
- }
-
- // TODO: Should we rename this to content? Or even better - inherit ContentView???
- get view(): View {
- return this._view;
- }
- set view(value: View) {
- if (this._view !== value) {
- if (this._view) {
- throw new Error("Changing the view of an already loaded TabContentItem is not currently supported.");
- }
-
- this._view = value;
- this._addView(value);
- }
- }
-
- public eachChild(callback: (child: ViewBase) => boolean) {
- const view = this._view;
- if (view) {
- callback(view);
+ public eachChild(callback: (child: View) => boolean) {
+ if (this.content) {
+ callback(this.content);
}
}
diff --git a/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item.android.ts b/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item.android.ts
index 409d1cc39..73aba71b0 100644
--- a/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item.android.ts
+++ b/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item.android.ts
@@ -1,15 +1,16 @@
// Types
import { TabContentItem as TabContentItemDefinition } from ".";
import { TabNavigationBase } from "../tab-navigation-base";
+import { GridLayout } from "../../layouts/grid-layout";
// Requires
import { TabContentItemBase, traceCategory } from "./tab-content-item-common";
-import { traceEnabled, traceWrite, traceMessageType } from "../../core/view";
+import { View, traceWrite, traceMessageType } from "../../core/view";
export * from "./tab-content-item-common";
export class TabContentItem extends TabContentItemBase {
- public nativeViewProtected: android.widget.TextView;
+ public nativeViewProtected: org.nativescript.widgets.GridLayout;
public tabItemSpec: org.nativescript.widgets.TabItemSpec;
public index: number;
@@ -17,6 +18,26 @@ export class TabContentItem extends TabContentItemBase {
return true;
}
+ public createNativeView() {
+ const layout = new org.nativescript.widgets.GridLayout(this._context);
+ layout.addRow(new org.nativescript.widgets.ItemSpec(1, org.nativescript.widgets.GridUnitType.star));
+
+ return layout;
+ }
+
+ public initNativeView(): void {
+ super.initNativeView();
+ }
+
+ public _addViewToNativeVisualTree(child: View, atIndex?: number): boolean {
+ // Set the row property for the child
+ if (this.nativeViewProtected && child.nativeViewProtected) {
+ GridLayout.setRow(child, 0);
+ }
+
+ return super._addViewToNativeVisualTree(child, atIndex);
+ }
+
public disposeNativeView(): void {
super.disposeNativeView();
(this).canBeLoaded = false;
diff --git a/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item.d.ts b/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item.d.ts
index 34ced73c3..e1c8a0180 100644
--- a/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item.d.ts
+++ b/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item.d.ts
@@ -4,16 +4,12 @@
*/ /** */
import { View, ViewBase } from "../../core/view";
+import { ContentView } from "../../content-view";
/**
* Represents a tab navigation content entry.
*/
-export class TabContentItem extends ViewBase {
- /**
- * Gets or sets the view of the TabViewItem.
- */
- public view: View;
-
+export class TabContentItem extends ContentView {
/**
* @private
*/
diff --git a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts
index 400b158a5..6a11acd77 100644
--- a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts
+++ b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts
@@ -144,6 +144,12 @@ export class TabNavigationBase extends View {
*/
setTabBarHighlightColor(value: any)
+ /**
+ * @private
+ * Method is intended to be overridden by inheritors and used as "protected"
+ */
+ setTabBarItemTitle(tabStripItem: TabStripItem, value: any): any
+
/**
* @private
* Method is intended to be overridden by inheritors and used as "protected"
@@ -168,6 +174,12 @@ export class TabNavigationBase extends View {
*/
setTabBarItemColor(tabStripItem: TabStripItem, value: any): void
+ /**
+ * @private
+ * Method is intended to be overridden by inheritors and used as "protected"
+ */
+ setTabBarIconColor(tabStripItem: TabStripItem, value: any): void
+
/**
* @private
* Method is intended to be overridden by inheritors and used as "protected"
diff --git a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts
index 599a6771a..b72d5640d 100644
--- a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts
+++ b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts
@@ -45,7 +45,7 @@ export class TabNavigationBase extends View implements TabNavigationBaseDefiniti
get _selectedView(): View {
let selectedIndex = this.selectedIndex;
- return selectedIndex > -1 ? this.items[selectedIndex].view : null;
+ return selectedIndex > -1 ? this.items[selectedIndex].content : null;
}
get _childrenCount(): number {
@@ -72,7 +72,7 @@ export class TabNavigationBase extends View implements TabNavigationBaseDefiniti
const items = this.items;
if (items) {
items.forEach((item, i) => {
- callback(item.view);
+ callback(item.content);
});
}
}
@@ -84,8 +84,8 @@ export class TabNavigationBase extends View implements TabNavigationBaseDefiniti
if (newItems) {
newItems.forEach(item => {
- if (!item.view) {
- throw new Error(`TabContentItem must have a view.`);
+ if (!item.content) {
+ throw new Error(`TabContentItem must have a content (view).`);
}
this._addView(item);
@@ -152,6 +152,10 @@ export class TabNavigationBase extends View implements TabNavigationBaseDefiniti
// overridden by inheritors
}
+ public setTabBarItemTitle(tabStripItem: TabStripItem, value: any): void {
+ // overridden by inheritors
+ }
+
public getTabBarItemBackgroundColor(tabStripItem: TabStripItem): any {
// overridden by inheritors
return null;
@@ -170,6 +174,10 @@ export class TabNavigationBase extends View implements TabNavigationBaseDefiniti
// overridden by inheritors
}
+ public setTabBarIconColor(tabStripItem: TabStripItem, value: any): void {
+ // overridden by inheritors
+ }
+
public getTabBarItemFontSize(tabStripItem: TabStripItem): any {
// overridden by inheritors
return null;
diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts
index 9d81137f9..79753759d 100644
--- a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts
+++ b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts
@@ -1,5 +1,6 @@
// Types
import { TabStripItem as TabStripItemDefinition } from ".";
+import { PropertyChangeData } from "../../../data/observable";
import { TabNavigationBase } from "../tab-navigation-base";
import { TabStrip } from "../tab-strip";
import { Image } from "../../image/image";
@@ -9,10 +10,8 @@ import { AddChildFromBuilder } from "../../core/view";
// Requires
import {
- View, CSSType, backgroundColorProperty, backgroundInternalProperty, colorProperty,
- fontSizeProperty, fontInternalProperty, PseudoClassHandler
+ View, ViewBase, CSSType, backgroundColorProperty, backgroundInternalProperty, PseudoClassHandler
} from "../../core/view";
-import { textTransformProperty, TextTransform } from "../../text-base";
export * from "../../core/view";
export const traceCategory = "TabView";
@@ -23,14 +22,153 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi
public static selectEvent = "select";
public static unselectEvent = "unselect";
- public title: string;
- public iconSource: string;
public image: Image;
public label: Label;
+ private _title: string;
+ private _iconSource: string;
+
private _highlightedHandler: () => void;
private _normalHandler: () => void;
+ private _labelColorHandler: (args: PropertyChangeData) => void;
+ private _labelFontHandler: (args: PropertyChangeData) => void;
+ private _labelTextTransformHandler: (args: PropertyChangeData) => void;
+ private _labelTextHandler: (args: PropertyChangeData) => void;
+
+ private _imageColorHandler: (args: PropertyChangeData) => void;
+ private _imageFontHandler: (args: PropertyChangeData) => void;
+ private _imageSrcHandler: (args: PropertyChangeData) => void;
+
+ get title(): string {
+ if (this.isLoaded) {
+ return this.label.text;
+ }
+
+ return this._title;
+ }
+
+ set title(value: string) {
+ this._title = value;
+
+ if (this.isLoaded) {
+ this.label.text = value;
+ }
+ }
+
+ get iconSource(): string {
+ if (this.isLoaded) {
+ return this.image.src;
+ }
+
+ return this._iconSource;
+ }
+
+ set iconSource(value: string) {
+ this._iconSource = value;
+
+ if (this.isLoaded) {
+ this.image.src = value;
+ }
+ }
+
+ public onLoaded() {
+ if (!this.image) {
+ const image = new Image();
+ image.src = this.iconSource;
+ this.image = image;
+ this._addView(this.image);
+ }
+
+ if (!this.label) {
+ const label = new Label();
+ label.text = this.title;
+ this.label = label;
+ this._addView(this.label);
+ }
+
+ super.onLoaded();
+
+ this._labelColorHandler = this._labelColorHandler || ((args: PropertyChangeData) => {
+ const parent = this.parent;
+ const tabStripParent = parent && parent.parent;
+
+ return tabStripParent && tabStripParent.setTabBarItemColor(this, args.value);
+ });
+ this.label.style.on("colorChange", this._labelColorHandler);
+
+ this._labelFontHandler = this._labelFontHandler || ((args: PropertyChangeData) => {
+ const parent = this.parent;
+ const tabStripParent = parent && parent.parent;
+
+ return tabStripParent && tabStripParent.setTabBarItemFontInternal(this, args.value);
+ });
+ this.label.style.on("fontInternalChange", this._labelFontHandler);
+
+ this._labelTextTransformHandler = this._labelTextTransformHandler || ((args: PropertyChangeData) => {
+ const parent = this.parent;
+ const tabStripParent = parent && parent.parent;
+
+ return tabStripParent && tabStripParent.setTabBarItemTextTransform(this, args.value);
+ });
+ this.label.style.on("textTransformChange", this._labelTextTransformHandler);
+
+ this._labelTextHandler = this._labelTextHandler || ((args: PropertyChangeData) => {
+ const parent = this.parent;
+ const tabStripParent = parent && parent.parent;
+
+ return tabStripParent && tabStripParent.setTabBarItemTitle(this, args.value);
+ });
+ this.label.on("textChange", this._labelTextHandler);
+
+ this._imageColorHandler = this._imageColorHandler || ((args: PropertyChangeData) => {
+ const parent = this.parent;
+ const tabStripParent = parent && parent.parent;
+
+ return tabStripParent && (tabStripParent).setTabBarIconColor(this, args.value);
+ });
+ this.image.style.on("colorChange", this._imageColorHandler);
+
+ this._imageFontHandler = this._imageFontHandler || ((args: PropertyChangeData) => {
+ const parent = this.parent;
+ const tabStripParent = parent && parent.parent;
+
+ return tabStripParent && (tabStripParent).setTabBarIconColor(this, args.value);
+ });
+ this.image.style.on("fontInternalChange", this._imageFontHandler);
+
+ this._imageSrcHandler = this._imageSrcHandler || ((args: PropertyChangeData) => {
+ const parent = this.parent;
+ const tabStripParent = parent && parent.parent;
+
+ return tabStripParent && (tabStripParent).setTabBarIconColor(this, args.value);
+ });
+ this.image.on("srcChange", this._imageSrcHandler);
+ }
+
+ public onUnloaded() {
+ super.onUnloaded();
+
+ this.label.style.off("colorChange", this._labelColorHandler);
+ this.label.style.off("fontInternalChange", this._labelFontHandler);
+ this.label.style.off("textTransformChange", this._labelTextTransformHandler);
+ this.label.style.off("textChange", this._labelTextHandler);
+
+ this.image.style.off("colorChange", this._imageColorHandler);
+ this.image.style.off("fontInternalChange", this._imageFontHandler);
+ this.image.style.off("srcChange", this._imageSrcHandler);
+ }
+
+ public eachChild(callback: (child: ViewBase) => boolean) {
+ if (this.label) {
+ callback(this.label);
+ }
+
+ if (this.image) {
+ callback(this.image);
+ }
+ }
+
public _addChildFromBuilder(name: string, value: any): void {
if (name === "Image") {
this.image = value;
@@ -99,56 +237,4 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi
[backgroundInternalProperty.setNative](value: any) {
// disable the background CSS properties
}
-
- [colorProperty.getDefault](): Color {
- const parent = this.parent;
- const tabStripParent = parent && parent.parent;
-
- return tabStripParent && tabStripParent.getTabBarItemColor(this);
- }
- [colorProperty.setNative](value: Color) {
- const parent = this.parent;
- const tabStripParent = parent && parent.parent;
-
- return tabStripParent && tabStripParent.setTabBarItemColor(this, value);
- }
-
- [fontSizeProperty.getDefault](): { nativeSize: number } {
- const parent = this.parent;
- const tabStripParent = parent && parent.parent;
-
- return tabStripParent && tabStripParent.getTabBarItemFontSize(this);
- }
- [fontSizeProperty.setNative](value: number | { nativeSize: number }) {
- const parent = this.parent;
- const tabStripParent = parent && parent.parent;
-
- return tabStripParent && tabStripParent.setTabBarItemFontSize(this, value);
- }
-
- [fontInternalProperty.getDefault](): any {
- const parent = this.parent;
- const tabStripParent = parent && parent.parent;
-
- return tabStripParent && tabStripParent.getTabBarItemFontInternal(this);
- }
- [fontInternalProperty.setNative](value: any) {
- const parent = this.parent;
- const tabStripParent = parent && parent.parent;
-
- return tabStripParent && tabStripParent.setTabBarItemFontInternal(this, value);
- }
-
- [textTransformProperty.getDefault](): any {
- const parent = this.parent;
- const tabStripParent = parent && parent.parent;
-
- return tabStripParent && tabStripParent.getTabBarItemTextTransform(this);
- }
- [textTransformProperty.setNative](value: any) {
- const parent = this.parent;
- const tabStripParent = parent && parent.parent;
-
- return tabStripParent && tabStripParent.setTabBarItemTextTransform(this, value);
- }
}
diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts
index 774af491d..bd2280d12 100644
--- a/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts
+++ b/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts
@@ -51,6 +51,18 @@ export class TabStrip extends View implements TabStripDefinition, AddChildFromBu
}
}
+ public onItemsChanged(oldItems: TabStripItem[], newItems: TabStripItem[]): void {
+ if (oldItems) {
+ oldItems.forEach(item => this._removeView(item));
+ }
+
+ if (newItems) {
+ newItems.forEach(item => {
+ this._addView(item);
+ });
+ }
+ }
+
[backgroundColorProperty.getDefault](): Color {
const parent = this.parent;
@@ -112,7 +124,14 @@ export class TabStrip extends View implements TabStripDefinition, AddChildFromBu
return parent && parent.setTabBarHighlightColor(value);
}
-}
+}
+
+export const itemsProperty = new Property({
+ name: "items", valueChanged: (target, oldValue, newValue) => {
+ target.onItemsChanged(oldValue, newValue);
+ }
+});
+itemsProperty.register(TabStrip);
export const iosIconRenderingModeProperty = new Property({ name: "iosIconRenderingMode", defaultValue: "automatic" });
iosIconRenderingModeProperty.register(TabStrip);
diff --git a/tns-core-modules/ui/tabs/tabs.android.ts b/tns-core-modules/ui/tabs/tabs.android.ts
index 13b4571a7..9fa203fb4 100644
--- a/tns-core-modules/ui/tabs/tabs.android.ts
+++ b/tns-core-modules/ui/tabs/tabs.android.ts
@@ -82,7 +82,7 @@ function initializeNativeClasses() {
public onCreateView(inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle): android.view.View {
const tabItem = this.tab.items[this.index];
- return tabItem.view.nativeViewProtected;
+ return tabItem.nativeViewProtected;
}
}
@@ -284,42 +284,58 @@ function initializeNativeClasses() {
}
function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets.TabItemSpec {
- let iconSource;
const tabItemSpec = new org.nativescript.widgets.TabItemSpec();
- if (tabStripItem.backgroundColor instanceof Color) {
- tabItemSpec.backgroundColor = tabStripItem.backgroundColor.android;
- }
+ if (tabStripItem.isLoaded) {
+ const nestedLabel = tabStripItem.label;
+ let title = nestedLabel.text;
- // Image and Label children of TabStripItem
- // take priority over its `iconSource` and `title` properties
- iconSource = tabStripItem.image ? tabStripItem.image.src : tabStripItem.iconSource;
- tabItemSpec.title = tabStripItem.label ? tabStripItem.label.text : tabStripItem.title;
+ // TEXT-TRANSFORM
+ const textTransform = nestedLabel.style.textTransform;
+ if (textTransform) {
+ title = getTransformedText(title, textTransform);
+ }
+ tabItemSpec.title = title;
- if (iconSource) {
- if (iconSource.indexOf(RESOURCE_PREFIX) === 0) {
- tabItemSpec.iconId = ad.resources.getDrawableId(iconSource.substr(RESOURCE_PREFIX.length));
- if (tabItemSpec.iconId === 0) {
- // TODO
- // traceMissingIcon(iconSource);
- }
- } else {
- let is = new ImageSource();
- if (isFontIconURI(tabStripItem.iconSource)) {
- const fontIconCode = tabStripItem.iconSource.split("//")[1];
- const font = tabStripItem.style.fontInternal;
- const color = tabStripItem.style.color;
- is = fromFontIconCode(fontIconCode, font, color);
+ // BACKGROUND-COLOR
+ const backgroundColor = tabStripItem.style.backgroundColor;
+ if (backgroundColor) {
+ tabItemSpec.backgroundColor = backgroundColor.android;
+ }
+
+ // COLOR
+ const color = nestedLabel.style.color;
+ if (color) {
+ tabItemSpec.color = color.android;
+ }
+
+ // FONT
+ const fontInternal = nestedLabel.style.fontInternal;
+ if (fontInternal) {
+ tabItemSpec.fontSize = fontInternal.fontSize;
+ tabItemSpec.typeFace = fontInternal.getAndroidTypeface();
+ }
+
+ // ICON
+ const iconSource = tabStripItem.image && tabStripItem.image.src;
+ if (iconSource) {
+ if (iconSource.indexOf(RESOURCE_PREFIX) === 0) {
+ tabItemSpec.iconId = ad.resources.getDrawableId(iconSource.substr(RESOURCE_PREFIX.length));
+ if (tabItemSpec.iconId === 0) {
+ // TODO:
+ // traceMissingIcon(iconSource);
+ }
} else {
- is = fromFileOrResource(tabStripItem.iconSource);
- }
+ const icon = _getIcon(tabStripItem);
- if (is) {
- // TODO: Make this native call that accepts string so that we don't load Bitmap in JS.
- tabItemSpec.iconDrawable = new android.graphics.drawable.BitmapDrawable(application.android.context.getResources(), is.android);
- } else {
- // TODO
- // traceMissingIcon(iconSource);
+ if (icon) {
+ // TODO: Make this native call that accepts string so that we don't load Bitmap in JS.
+ // tslint:disable-next-line:deprecation
+ tabItemSpec.iconDrawable = icon;
+ } else {
+ // TODO:
+ // traceMissingIcon(iconSource);
+ }
}
}
}
@@ -327,6 +343,25 @@ function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets
return tabItemSpec;
}
+function _getIcon(tabStripItem: TabStripItem): android.graphics.drawable.BitmapDrawable {
+ const iconSource = tabStripItem.image && tabStripItem.image.src;
+
+ let is = new ImageSource();
+ if (isFontIconURI(iconSource)) {
+ const fontIconCode = iconSource.split("//")[1];
+ const target = tabStripItem.image ? tabStripItem.image : tabStripItem;
+ const font = target.style.fontInternal;
+ const color = target.style.color;
+ is = fromFontIconCode(fontIconCode, font, color);
+ } else {
+ is = fromFileOrResource(iconSource);
+ }
+
+ const image = new android.graphics.drawable.BitmapDrawable(application.android.context.getResources(), is.android);
+
+ return image;
+}
+
let defaultAccentColor: number = undefined;
function getDefaultAccentColor(context: android.content.Context): number {
if (defaultAccentColor === undefined) {
@@ -337,11 +372,15 @@ function getDefaultAccentColor(context: android.content.Context): number {
return defaultAccentColor;
}
-function setElevation(grid: org.nativescript.widgets.GridLayout, tabsBar: org.nativescript.widgets.TabsBar) {
+function setElevation(grid: org.nativescript.widgets.GridLayout, tabsBar: org.nativescript.widgets.TabsBar, tabsPosition: string) {
const compat = androidx.core.view.ViewCompat;
if (compat.setElevation) {
const val = DEFAULT_ELEVATION * layout.getDisplayDensity();
- compat.setElevation(grid, val);
+
+ if (tabsPosition === "top") {
+ compat.setElevation(grid, val);
+ }
+
compat.setElevation(tabsBar, val);
}
}
@@ -422,7 +461,7 @@ export class Tabs extends TabsBase {
nativeView.addView(tabsBar);
(nativeView).tabsBar = tabsBar;
- setElevation(nativeView, tabsBar);
+ setElevation(nativeView, tabsBar, this.tabsPosition);
if (accentColor) {
tabsBar.setSelectedIndicatorColors([accentColor]);
@@ -471,12 +510,12 @@ export class Tabs extends TabsBase {
toUnload.forEach(index => {
const item = items[index];
if (items[index]) {
- item.unloadView(item.view);
+ item.unloadView(item.content);
}
});
const newItem = items[newIndex];
- const selectedView = newItem && newItem.view;
+ const selectedView = newItem && newItem.content;
if (selectedView instanceof Frame) {
(selectedView)._pushInFrameStackRecursive();
}
@@ -484,7 +523,7 @@ export class Tabs extends TabsBase {
toLoad.forEach(index => {
const item = items[index];
if (this.isLoaded && items[index]) {
- item.loadView(item.view);
+ item.loadView(item.content);
}
});
}
@@ -661,20 +700,6 @@ export class Tabs extends TabsBase {
}
}
- public getTabBarColor(): number {
- return this._tabsBar.getTabTextColor();
- }
-
- public setTabBarColor(value: number | Color): void {
- if (value instanceof Color) {
- this._tabsBar.setTabTextColor(value.android);
- this._tabsBar.setSelectedTabTextColor(value.android);
- } else {
- this._tabsBar.setTabTextColor(value);
- this._tabsBar.setSelectedTabTextColor(value);
- }
- }
-
public getTabBarHighlightColor(): number {
return getDefaultAccentColor(this._context);
}
@@ -684,15 +709,18 @@ export class Tabs extends TabsBase {
this._tabsBar.setSelectedIndicatorColors([color]);
}
- public setTabBarItemBackgroundColor(tabStripItem: TabStripItem, value: android.graphics.drawable.Drawable | Color): void {
+ public setTabBarItemTitle(tabStripItem: TabStripItem, value: string): void {
// TODO: Should figure out a way to do it directly with the the nativeView
const tabStripItemIndex = this.tabStrip.items.indexOf(tabStripItem);
const tabItemSpec = createTabItemSpec(tabStripItem);
this.updateAndroidItemAt(tabStripItemIndex, tabItemSpec);
}
- public getTabBarItemColor(tabStripItem: TabStripItem): number {
- return tabStripItem.nativeViewProtected.getCurrentTextColor();
+ public setTabBarItemBackgroundColor(tabStripItem: TabStripItem, value: android.graphics.drawable.Drawable | Color): void {
+ // TODO: Should figure out a way to do it directly with the the nativeView
+ const tabStripItemIndex = this.tabStrip.items.indexOf(tabStripItem);
+ const tabItemSpec = createTabItemSpec(tabStripItem);
+ this.updateAndroidItemAt(tabStripItemIndex, tabItemSpec);
}
public setTabBarItemColor(tabStripItem: TabStripItem, value: number | Color): void {
@@ -703,45 +731,24 @@ export class Tabs extends TabsBase {
}
}
- public getTabBarItemFontSize(tabStripItem: TabStripItem): { nativeSize: number } {
- return { nativeSize: tabStripItem.nativeViewProtected.getTextSize() };
+ public setTabBarIconColor(tabStripItem: TabStripItem, value: number | Color): void {
+ const index = (tabStripItem).index;
+ const tabBarItem = this._tabsBar.getViewForItemAt(index);
+ const imgView = tabBarItem.getChildAt(0);
+ const drawable = _getIcon(tabStripItem);
+
+ imgView.setImageDrawable(drawable);
}
- public setTabBarItemFontSize(tabStripItem: TabStripItem, value: number | { nativeSize: number }): void {
- if (typeof value === "number") {
- tabStripItem.nativeViewProtected.setTextSize(value);
- } else {
- tabStripItem.nativeViewProtected.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, value.nativeSize);
- }
+ public setTabBarItemFontInternal(tabStripItem: TabStripItem, value: Font): void {
+ tabStripItem.nativeViewProtected.setTextSize(value.fontSize);
+ tabStripItem.nativeViewProtected.setTypeface(value.getAndroidTypeface());
}
- public getTabBarItemFontInternal(tabStripItem: TabStripItem): android.graphics.Typeface {
- return tabStripItem.nativeViewProtected.getTypeface();
- }
-
- public setTabBarItemFontInternal(tabStripItem: TabStripItem, value: Font | android.graphics.Typeface): void {
- tabStripItem.nativeViewProtected.setTypeface(value instanceof Font ? value.getAndroidTypeface() : value);
- }
-
- private _defaultTransformationMethod: android.text.method.TransformationMethod;
-
- public getTabBarItemTextTransform(tabStripItem: TabStripItem): "default" {
- return "default";
- }
-
- public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform | "default"): void {
- const tv = tabStripItem.nativeViewProtected;
-
- this._defaultTransformationMethod = this._defaultTransformationMethod || tv.getTransformationMethod();
-
- if (value === "default") {
- tv.setTransformationMethod(this._defaultTransformationMethod);
- tv.setText(tabStripItem.title);
- } else {
- const result = getTransformedText(tabStripItem.title, value);
- tv.setText(result);
- tv.setTransformationMethod(null);
- }
+ public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform): void {
+ const nestedLabel = tabStripItem.label;
+ const title = getTransformedText(nestedLabel.text, value);
+ tabStripItem.nativeViewProtected.setText(title);
}
[selectedIndexProperty.setNative](value: number) {
diff --git a/tns-core-modules/ui/tabs/tabs.ios.ts b/tns-core-modules/ui/tabs/tabs.ios.ts
index aa52dca18..8579f0755 100644
--- a/tns-core-modules/ui/tabs/tabs.ios.ts
+++ b/tns-core-modules/ui/tabs/tabs.ios.ts
@@ -532,7 +532,7 @@ export class Tabs extends TabsBase {
super.onLoaded();
const selectedIndex = this.selectedIndex;
- const selectedView = this.items && this.items[selectedIndex] && this.items[selectedIndex].view;
+ const selectedView = this.items && this.items[selectedIndex] && this.items[selectedIndex].content;
if (selectedView instanceof Frame) {
(selectedView)._pushInFrameStackRecursive();
}
@@ -540,10 +540,8 @@ export class Tabs extends TabsBase {
this._ios.dataSource = this._dataSource;
this._ios.delegate = this._delegate;
- if (!this.tabBarItems) {
- const tabStripItems = this.tabStrip ? this.tabStrip.items : null;
- this.setTabStripItems(tabStripItems);
- }
+ const tabStripItems = this.tabStrip ? this.tabStrip.items : null;
+ this.setTabStripItems(tabStripItems);
}
public onUnloaded() {
@@ -611,12 +609,12 @@ export class Tabs extends TabsBase {
toUnload.forEach(index => {
const item = items[index];
if (items[index]) {
- item.unloadView(item.view);
+ item.unloadView(item.content);
}
});
const newItem = items[newIndex];
- const selectedView = newItem && newItem.view;
+ const selectedView = newItem && newItem.content;
if (selectedView instanceof Frame) {
selectedView._pushInFrameStackRecursive();
}
@@ -624,7 +622,7 @@ export class Tabs extends TabsBase {
toLoad.forEach(index => {
const item = items[index];
if (this.isLoaded && items[index]) {
- item.loadView(item.view);
+ item.loadView(item.content);
}
});
}
@@ -699,7 +697,7 @@ export class Tabs extends TabsBase {
// }
public getViewController(item: TabContentItem): UIViewController {
- let newController: UIViewController = item.view ? item.view.viewController : null;
+ let newController: UIViewController = item.content ? item.content.viewController : null;
if (newController) {
(item).setViewController(newController, newController.view);
@@ -707,17 +705,17 @@ export class Tabs extends TabsBase {
return newController;
}
- if (item.view.ios instanceof UIViewController) {
- newController = item.view.ios;
+ if (item.content.ios instanceof UIViewController) {
+ newController = item.content.ios;
(item).setViewController(newController, newController.view);
- } else if (item.view.ios && item.view.ios.controller instanceof UIViewController) {
- newController = item.view.ios.controller;
+ } else if (item.content.ios && item.content.ios.controller instanceof UIViewController) {
+ newController = item.content.ios.controller;
(item).setViewController(newController, newController.view);
} else {
- newController = iosView.UILayoutViewController.initWithOwner(new WeakRef(item.view)) as UIViewController;
- newController.view.addSubview(item.view.nativeViewProtected);
- item.view.viewController = newController;
- (item).setViewController(newController, item.view.nativeViewProtected);
+ newController = iosView.UILayoutViewController.initWithOwner(new WeakRef(item.content)) as UIViewController;
+ newController.view.addSubview(item.content.nativeViewProtected);
+ item.content.viewController = newController;
+ (item).setViewController(newController, item.content.nativeViewProtected);
}
return newController;
@@ -850,8 +848,8 @@ export class Tabs extends TabsBase {
let image: UIImage;
let title: string;
- image = this._getIcon(item);
- title = item.label ? item.label.text : item.title;
+ image = item.isLoaded && this._getIcon(item);
+ title = item.label && item.label.text;
if (!this.tabStrip._hasImage) {
this.tabStrip._hasImage = !!image;
@@ -884,20 +882,21 @@ export class Tabs extends TabsBase {
}
public _getIcon(tabStripItem: TabStripItem): UIImage {
- // Image and Label children of TabStripItem
- // take priority over its `iconSource` and `title` properties
- const iconSource = tabStripItem.image ? tabStripItem.image.src : tabStripItem.iconSource;
+ const iconSource = tabStripItem.image && tabStripItem.image.src;
if (!iconSource) {
return null;
}
- let image: UIImage = this._iconsCache[iconSource];
+ const target = tabStripItem.image;
+ const font = target.style.fontInternal;
+ const color = target.style.color;
+ const iconTag = [iconSource, font.fontStyle, font.fontWeight, font.fontSize, font.fontFamily, color].join(";");
+
+ let image: UIImage = this._iconsCache[iconTag];
if (!image) {
let is = new ImageSource;
if (isFontIconURI(iconSource)) {
const fontIconCode = iconSource.split("//")[1];
- const font = tabStripItem.style.fontInternal;
- const color = tabStripItem.style.color;
is = fromFontIconCode(fontIconCode, font, color);
} else {
is = fromFileOrResource(iconSource);
@@ -905,7 +904,7 @@ export class Tabs extends TabsBase {
if (is && is.ios) {
const originalRenderedImage = is.ios.imageWithRenderingMode(this._getIconRenderingMode());
- this._iconsCache[iconSource] = originalRenderedImage;
+ this._iconsCache[iconTag] = originalRenderedImage;
image = originalRenderedImage;
} else {
// TODO
diff --git a/tns-platform-declarations/android/org.nativescript.widgets.d.ts b/tns-platform-declarations/android/org.nativescript.widgets.d.ts
index b78e57aa2..dc17e7638 100644
--- a/tns-platform-declarations/android/org.nativescript.widgets.d.ts
+++ b/tns-platform-declarations/android/org.nativescript.widgets.d.ts
@@ -452,9 +452,12 @@
export class TabItemSpec {
title: string;
+ fontSize: number;
+ typeFace: android.graphics.Typeface;
iconId: number;
iconDrawable: android.graphics.drawable.Drawable;
backgroundColor: number;
+ color: number;
}
export namespace image {