Nativescript: Feature request: Support percentages for top,left in absolute layout

Created on 1 Mar 2017  路  11Comments  路  Source: NativeScript/NativeScript

For positioning the element at center it requires to write some logic. If it have percentage it will be more easier.

My use case is to position activity indicator always to be at center.


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

feature

Most helpful comment

How do you propose to position a fab button 20% from the bottom and right, over any other content without the abs-layout?

All 11 comments

Hi @Habeeb-mohamed,

Why not using GridLayout instead of AbsoluteLayout and then set horizontalAlignment='center' and verticalAlignment='center' on the Activity indicator?

I am using grid layout inside scrollview. Since it exceeds the height of screen. So it align to center based on total height, but not on screen size.

Hey @Habeeb-mohamed

As a workaround, you can use nativescript-loading-indicator which will always be placed in the visual center of your device screen, Here you can find a sample application demonstrating the basic usage.

Here's a custom module solution:

JS

var absoluteLayout_01 = require("ui/layouts/absolute-layout").AbsoluteLayout;
var absoluteLayoutModule = {};

absoluteLayoutModule.AbsoluteLayout = (function(_super) {
  __extends(AbsoluteLayout, _super);
  function AbsoluteLayout() {
    _super.call(this);
  }

  AbsoluteLayout.prototype.onLoaded = function() {
    _super.prototype.onLoaded.call(this);
    var _this = this;

    setTimeout(function() {
      _this._eachChildView(function(view) {
        if(view.customLeft) _this.setCustomLeft(view, view.customLeft);
        if(view.customTop) _this.setCustomTop(view, view.customTop);
      });
    }, 0);
  };

  AbsoluteLayout.prototype.setCustomLeft = function(view, value) {
    var isPercent = typeof value === "string" && value.indexOf("%") >= 0;
    if(isPercent) absoluteLayout_01.setLeft(view, this.getMeasuredWidth() * (parseFloat(value) / 100));
      else absoluteLayout_01.setLeft(view, value);
  };

  AbsoluteLayout.prototype.setCustomTop = function(view, value) {
    var isPercent = typeof value === "string" && value.indexOf("%") >= 0;
    if(isPercent) absoluteLayout_01.setTop(view, this.getMeasuredHeight() * (parseFloat(value) / 100));
      else absoluteLayout_01.setTop(view, value);
  };

  return AbsoluteLayout;
})(absoluteLayout_01);

module.exports = absoluteLayoutModule;

XML

<Page xmlns:cal="custom-absolute-layout">
  <Page.actionBar>
    <ActionBar title="AbsoluteLayout test" icon="" class="action-bar">
    </ActionBar>
  </Page.actionBar>

  <cal:AbsoluteLayout>
    <Label text="X: 25% - Y: 50%" customLeft="25%" customTop="50%" style="padding: 10; color: #ffffff; background-color: #ba3c4d; font-weight: 700;" />
  </cal:AbsoluteLayout>
</Page>

Example app can be found here: https://github.com/NordlingArt/tns-absolute-layout

How do you propose to position a fab button 20% from the bottom and right, over any other content without the abs-layout?

This can be extremely useful when placing map markers/dots over the image. Setting Top/Left values to percentage would be ideal option as it's relative to the container and would work nicely in both portrait and landscape orientation when image scales up/down but the dot remain in the same spot relative to the map/image.

Is there any plan to implement this feature?

@vahidvdn this looks like a great issue to try and contribute a solution/feature for! At a quick glance, it seems adding the correct calculations to go from % to a devicePixels right to the properties here would be enough: https://github.com/NativeScript/NativeScript/blob/02dd5ac96513d6922b0dcb5c4c189cf1a65c9aae/nativescript-core/ui/layouts/absolute-layout/absolute-layout-common.ts#L50-L71

I am unsure however if calculating the correct percentage value before a first measure pass would be possible - because a percentage has to take into account the laid out width/height of the view. There are ways to solve that, if it turns out to be an issue - with something like the above proposed setCustomLeft and setCustomTop - by delaying the calculations to perhaps a layoutChanged event.

@rigor789 I think that process we should check that everything support percentages values. Like margin and padding? (Even though a bit trickier )

@farfromrefug probably yes - though the issue with percentages is still that they rely on the parent view's measures - and not the device screen size, so calculating them in some cases could be tricky!

@rigor789 we just need to "recalculate of layout event if depending on measured size. Indeed not that easy but very practical.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yclau picture yclau  路  3Comments

rLoka picture rLoka  路  3Comments

NordlingDev picture NordlingDev  路  3Comments

Pourya8366 picture Pourya8366  路  3Comments

Leo-lay picture Leo-lay  路  3Comments