[TIMOB-8673] Ti API: Horizontal Layout Modes do not match.
GitHub Issue | n/a |
---|---|
Type | Epic |
Priority | High |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2012-06-18T14:31:39.000+0000 |
Affected Version/s | Release 2.0.0 |
Fix Version/s | Release 2.1.0, Sprint 2012-12 Core |
Components | TiAPI |
Labels | core, parity |
Reporter | Arthur Evans |
Assignee | Max Stepanov |
Created | 2012-04-10T23:07:42.000+0000 |
Updated | 2017-03-21T20:38:15.000+0000 |
Description
When creating a horizontal layout containing the same set of views on Android and iOS, the views display differently.
var win = Ti.UI.createWindow({ fullscreen: true, backgroundColor: 'white'});
//Horizontal Layout behavior. Green child centered vertically (No positioning pins)
var parent = Ti.UI.createView({backgroundColor:'red',layout:'horizontal',width:300, height:300})
var child1 =Ti.UI.createView({backgroundColor:'green',height:60,width:150});
var child2 =Ti.UI.createView({backgroundColor:'blue',height:120,width:120});
var child3 =Ti.UI.createView({backgroundColor:'#eee',height:120,width:150});
var child4 =Ti.UI.createView({backgroundColor:'#666',height:60,width:150});
parent.add(child1);
parent.add(child2);
parent.add(child3);
parent.add(child4);
win.add(parent);
win.open();
On iOS, the "child1" view is centered vertically with respect to the "Child2" view, and child2 is flush to the top of the parent view. Child3 and Child4 are on the next line, again centered vertically relative to each other.
On Android, child1 and child2 are centered vertically in the parent view, and child3 and child4 are flush against the bottom of the view.
On both platforms, the child3 and child4 views wrap to the next line rather than going off-screen. This is inconsistent with the behavior of vertical layouts, -and a break with Android behavior pre-2.0-.
Correction--wrapping is not a behavior change from pre-2.0. Both iOS and Android wrapped pre-2.0, and my original testing was incorrect.
Meanwhile, Mobile Web does *not* wrap the children, but also doesn't center them vertically. See attached screenshots for comparison
As an additional note, the treatment of top and bottom is not consistent when the views wrap:
* On iOS, specifying either top or bottom causes the child view to be aligned to the top or bottom _of the row_. However, specifying both top and bottom *without specifying a height* causes the child view to be pinned to the top and bottom _of the parent view_. If height is not specified and top and bottom are both specified, the child's height is set implicitly.
* On Android, top and bottom behave as they do in a composite layout--pinning the child to the top and/or bottom of the parent view. If height is not specified and top and bottom are both specified, the child's height is set implicitly.
* On Mobile Web, I believe top and bottom are interpreted as padding, so if both top and bottom are specified, the height is *not* set implicitly.
If we address horizontal layout parity, we might also want to consider Ivan's suggestion of adding a gravity or default vertical alignment within the rows. I believe Mobile Web already uses something like this internally.
Attachments
File | Date | Size |
---|---|---|
horizontal_layout_mobileweb.png | 2012-04-10T23:22:53.000+0000 | 5693 |
horizontal_layout.png | 2012-04-10T23:20:28.000+0000 | 18120 |
Pictures are awesome. :D Anyway, I don't know what composite layout specification contains (it's still top secret for outside world :( ), but I really miss functionality like "float" is in CSS world. It would be extremely useful if there was something like that. When building forms, typical use-case is to have label and input element like this: label1 input1 label2 input2 ... To achieve this, parent container must have "vertical" layout and all label-inputs needs to be wrapped with view that have "horizontal" layout (ok, this can be achieved by setting parent's layout property to "absolute" and hardcode position of label-inputs, but that is limited in dynamic scenarios when there are components that can change their height dynamically). That solution is fine, but it is not optimal and it impacts performances when there are a lot of elements (one extra view needs to be created for every label-input pair). So, IMHO, having something like "float" could be very benifitical in use-case I described. Sorry for invading this issue, this does not belong here, but it's related (hopefully we can have a decent place for discussion, heh?). :)
Hi Ivan, Yeah, you could sort of do that with 'horizontal' as it is defined in iOS, but I don't think it's optimal, and I also think there are valid use cases for 'horizontal' as it was defined on Android. The label/input use case is such a common one that we should really provide a simpler way to put it together.
Fixed sample code to match screenshots.
Corrected description. This is NOT a behavior change on Android, but handling of this layout type should be made consistent. Given the wrapping behavior, iOS is probably doing this the 'right' way. But it really seems like this should be a separate layout mode and we should have a normal 'horizontal'.
Ivan: Until we have a discussion forum available... One approach to the type of layout you described is to use the 'horizontal' layout and use percentage widths adding up to 100% for the label and input field. Here's an example:
This appears to work in Android back to 1.7.5. In 2.0 it will work on both iOS and Android, but not Mobile Web.
Arthur, thanks a lot. That's exactly what I wanted to achieve. But that solution does not work for ScrollView (and ScrollView must be used when there is large number of form components present). Btw, ScrollView component has issues on Android and usually wrapping ScrollView's content with basic View helps. I tried to play a bit with your code and I managed to come to some solution (it has some issues, but could be used as a workaround)
If issues with ScrollView will be fixed, then this solution is satisfying. But still, there is unnecessary code (top: 0) and in my opinion it would be more useful if we could set, for example, some layout property that would do that without a need to specify "top" property for every component. I think Android has something like "gravity" that does something like that, but I'm not really sure (I'm not Android programmer).
We do have internal mechanisms for setting the default horizontal/vertical alignment in views, as the ticket suggests, and we have default vertical alignment of horizontal layout rows coming in TIMOB-8275.
FYI TIMOB-8275 has been completed and merged, so Mobile Web now has wrapping in horizontal views. The screenshots attached to the ticket should probably be updated.
Android and iOS are now match. MobileWeb needs a fix, afaik.
PR is in for Mobile Web.
Closing ticket as fixed.