Skip to content
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): Fixes changing background colors for Tabs after they are drawn. #10756

Merged
merged 6 commits into from Mar 11, 2019

Conversation

ypbnv
Copy link
Contributor

@ypbnv ypbnv commented Mar 6, 2019

JIRA: https://jira.appcelerator.org/browse/TIMOB-26859

Description:
Fixes changing TabGroup and Tab background colors for different states after the creation of the
components.

Note: No unit tests. Also I see that in the code sample in the ticket the property backgroundSelectedColor (https://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.Tab-property-backgroundSelectedColor) is being used. When I was refactoring the TabGroup I went for the usage of backgroundFocusedColor (https://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.Tab-property-backgroundFocusedColor) as it explicitly states that is used for changing the color of the Tab according to the state. Do you think we can adjust the docs to just list the latter and add to the description that it acts as backgroundSelectedColor?

Test Case 1:
This tests empty tab group, top/bottom tab color handling, and setting colors after creation but before open.

  1. Build and run the below code on Android.
  2. Verify that an empty window with no tabs appears. (Must not crash.)
  3. Uncomment the // tabs: ... line in the code below.
  4. Rebuild and run on Android.
  5. Verify that left-most tab (the selected tab) is yellow and all others tabs are green.
  6. Tap on center tab and verify that it turns yellow and left tab turns green.
  7. Uncomment the // style: ... line in the code below.
  8. Rebuild and run on Android.
  9. Verify that the tabs are now docked to the bottom of the window instead of the top.
  10. Verify that left-most tab (the selected tab) is yellow and all others tabs are green.
  11. Tap on center tab and verify that it turns yellow and left tab turns green.
function createTab(title) {
	var window = Ti.UI.createWindow({ title: title });
	window.add(Ti.UI.createLabel({ text: title + " View" }));
	return Ti.UI.createTab({ title: title, window: window });
}
var tabGroup = Ti.UI.createTabGroup({
//	tabs: [createTab("Tab 1"), createTab("Tab 2"), createTab("Tab 3")],
//	style: Ti.UI.Android.TABS_STYLE_BOTTOM_NAVIGATION,
	tabsBackgroundColor: "red",
	tabsBackgroundSelectedColor: "orange",
});
tabGroup.tabsBackgroundColor = "green";
tabGroup.tabsBackgroundSelectedColor = "yellow";
tabGroup.open();

Test Case 2:
This tests changing tab colors after opening tab group.

// create tab group
var tabGroup = Titanium.UI.createTabGroup({
	// Test tabsBackgroundColor and tabsBackgroundSelectedColor here.
	tabsBackgroundSelectedColor:'red',
	// Comment/uncomment the bottom line to check both styles.
	// style: Ti.UI.Android.TABS_STYLE_BOTTOM_NAVIGATION,
	tabsBackgroundColor:'blue',
});

var win1 = Titanium.UI.createWindow({
	title:'Tab 1',
	backgroundColor:'#fff'
});

var tab1 = Titanium.UI.createTab({
	backgroundColor: 'lime',
	backgroundFocusedColor: 'red',
	title:'Tab 1',
	activeTitleColor: 'black',
	window:win1
});

var label1 = Titanium.UI.createLabel({
	color:'#999',
	text:'I am Window 1',
	font:{fontSize:20,fontFamily:'Helvetica Neue'},
	textAlign:'center',
	width:'auto'
});

win1.add(label1);

// create controls tab and root window
var win2 = Titanium.UI.createWindow({
	title:'Tab 2',
	backgroundColor:'#fff'
});

var tab2 = Titanium.UI.createTab({
	title:'Tab 2',
	titleColor: 'black',
	window:win2
});

var label2 = Titanium.UI.createLabel({
	color:'#999',
	text:'I am Window 2',
	font:{fontSize:20,fontFamily:'Helvetica Neue'},
	textAlign:'center',
	width:'auto'
});

win2.add(label2);

var win3 = Titanium.UI.createWindow({
	title:'Tab 3',
	backgroundColor:'#fff'
});

var tab3 = Titanium.UI.createTab({
	title:'Tab 3',
	titleColor: 'black',
	window:win3
});

var button3 = Titanium.UI.createButton({
	title: "change background color"
});

button3.addEventListener('click', function(e){
	// Test tabsBackgroundColor and tabsBackgroundSelectedColor here.
	tabGroup.tabsBackgroundColor='orange';
	tabGroup.tabsBackgroundSelectedColor = 'gray';
	tab2.backgroundColor = 'cyan',
	tab2.backgroundFocusedColor = 'magenta'
});

win2.add(button3);

// add tabs
tabGroup.addTab(tab1);
tabGroup.addTab(tab2);
tabGroup.addTab(tab3);
// open tab group
tabGroup.open();

…e drawn.

Fixes changing TabGroup and Tab background colors for different states after the creation of the
components. Fixes TIMOB-26859.
@ypbnv ypbnv added this to the 8.1.0 milestone Mar 6, 2019
@ypbnv ypbnv requested a review from garymathews March 6, 2019 15:59
@build build requested a review from a team March 6, 2019 16:26
@build
Copy link
Contributor

build commented Mar 6, 2019

Messages
📖

💾 Here's the generated SDK zipfile.

📖

✅ All tests are passing
Nice one! All 3536 tests are passing.

Generated by 🚫 dangerJS against e59143d

@@ -48,6 +48,31 @@ public TiUITabLayoutTabGroup(TabGroupProxy proxy, TiBaseActivity activity)
super(proxy, activity);
}

private void setDrawablesForTab(int tabIndex)
{
TabProxy tabProxy = ((TabGroupProxy) this.proxy).getTabList().get(tabIndex);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to validate the given tabIndex before using it. This is especially needed if the TabGroup has no tabs. I've seen some app devs add/remove tabs dynamically before.

ArrayList<TabProxy> tabProxiesList = ((TabGroupProxy) this.proxy).getTabList();
if ((tabIndex < 0) || (tabIndex >= tabProxiesList.length())) {
	return;
}

TabProxy tabProxy = tabProxiesList.get(tabIndex);
if (tabProxy == null) {
	return;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should test this with an empty TabGroup just in case.

function createTab(title) {
	var window = Ti.UI.createWindow({ title: title });
	window.add(Ti.UI.createLabel({ text: title + " View" }));
	return Ti.UI.createTab({ title: title, window: window });
}
var tabGroup = Ti.UI.createTabGroup({
//	tabs: [createTab("Tab 1"), createTab("Tab 2"), createTab("Tab 3")],
//	style: Ti.UI.Android.TABS_STYLE_BOTTOM_NAVIGATION,
	tabsBackgroundColor: "red",
	tabsBackgroundSelectedColor: "orange",
});
tabGroup.tabsBackgroundColor = "green";
tabGroup.tabsBackgroundSelectedColor = "yellow";
tabGroup.addEventListener("open", function() {
	tabGroup.tabsBackgroundColor = "purple";
	tabGroup.tabsBackgroundSelectedColor = "blue";
});
tabGroup.open();

@@ -356,6 +361,9 @@ public void propertyChanged(String key, Object oldValue, Object newValue, KrollP
this.swipeable = TiConvert.toBoolean(newValue);
} else if (key.equals(TiC.PROPERTY_SMOOTH_SCROLL_ON_TAB_CLICK)) {
this.smoothScrollOnTabClick = TiConvert.toBoolean(newValue);
} else if (key.equals(TiC.PROPERTY_TABS_BACKGROUND_COLOR)
|| key.equals(TiC.PROPERTY_TABS_BACKGROUND_SELECTED_COLOR)) {
setDrawables();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setDrawable() call here will create views if currently null. So, we need to test if this works okay when setting these properties after the createTabGroup() call and before the TabGroup.open() call. This means the created tabs will be using the previous activity context instead of the tab group activity context.

Would you mind testing the following please?

function createTab(title) {
	var window = Ti.UI.createWindow({ title: title });
	window.add(Ti.UI.createLabel({ text: title + " View" }));
	return Ti.UI.createTab({ title: title, window: window });
}
var tabGroup = Ti.UI.createTabGroup({
	tabs: [createTab("Tab 1"), createTab("Tab 2"), createTab("Tab 3")],
//	style: Ti.UI.Android.TABS_STYLE_BOTTOM_NAVIGATION,
});
tabGroup.tabsBackgroundColor = "blue"; // <- Will this work?
tabGroup.tabsBackgroundSelectedColor = "red"; // <- Will this work?
tabGroup.open();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use-case here is an app that wants to to dynamically change the color of a tab. For example, to highlight a tab when new content is available or a notification has been received. An Alloy user typically has the creation properties hard-coded in XML, so, the only option is to change it dynamically in the view code. They may do this before the open call.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the PR. I will open a backport to have it ready in case no further changes are done.

Copy link
Contributor

@jquick-axway jquick-axway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CR: Pass

@ssjsamir
Copy link
Contributor

@ypbnv Please could you take a look at the merge conflicts?

@ssjsamir ssjsamir self-requested a review March 11, 2019 14:13
Copy link
Contributor

@ssjsamir ssjsamir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FR Passed: Able to change background colors for Tabs after they are drawn. Tested using the test cases mentioned in the description above.

Test Environment

Pixel XL api 28 
iPhone 6(12.1 Sim)
APPC CLI: 7.0.10-17
Operating System Name: Mac OS Mojave
Operating System Version: 10.14.2
Node.js Version: 8.9.1
Xcode 10.1

@sgtcoolguy sgtcoolguy merged commit b16310f into tidev:master Mar 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants