i.brod
i.brod

Reputation: 4623

Nativescript: How to position an element in the center of the viewport, regardless of other content?

I want to position an ActivityIndicator element in the center of the phone(both vertically and horizontally). I have a page that looks something like that:

<Page class="page">
    <ActionBar class="action-bar">
      <Label class="action-bar-title" text="Image backup"></Label>
    </ActionBar>
    <TabView :selectedIndex="selectedIndex" @selectedIndexChange="indexChange">
      <TabViewItem title="Add images">
        <StackLayout>
          <Button @tap="takePicture" text="Take picture"></Button>...
          <StackLayout v-if="newImages.length" orientation="horizontal">...</StackLayout>
          <RadListView layout="grid" ref="newImages" for="image in newImages">
            <v-template>
              ...
            </v-template>
          </RadListView>
        </StackLayout>
      </TabViewItem>
      <TabViewItem title="Backedup images">
        <StackLayout>
          <Button @tap="fetchAllBackedupImages" text="Get all backedup images"></Button>
          <StackLayout v-if="backedupImages.length" orientation="horizontal">
            ...
          </StackLayout>
          <RadListView layout="grid" ref="backedupImages" for="image in sortedBackedupImages">
            <v-template>...</v-template>
          </RadListView>
        </StackLayout>
      </TabViewItem>
    </TabView>
  </Page>

All i want is to show/hide the ActivityIndicator , exactly in the middle of the page. It should be the Android equivalent of this CSS:

.centered {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

How can this be done?

Upvotes: 0

Views: 818

Answers (1)

Manoj
Manoj

Reputation: 21908

Just wrap the whole content with a GridLayout and add ActivityIndicator as second child on the same layout. Something like,

<Page class="page">
    <ActionBar class="action-bar">
        <Label class="action-bar-title" text="Image backup"></Label>
    </ActionBar>
    <GridLayout>
        <TabView :selectedIndex="selectedIndex" @selectedIndexChange="indexChange">
            <TabViewItem title="Add images">
                <StackLayout>
                    <Button @tap="takePicture" text="Take picture"></Button>...
                    <StackLayout v-if="newImages.length" orientation="horizontal">...</StackLayout>
                    <RadListView layout="grid" ref="newImages" for="image in newImages">
                        <v-template>
                            ...
                        </v-template>
                    </RadListView>
                </StackLayout>
            </TabViewItem>
            <TabViewItem title="Backedup images">
                <StackLayout>
                    <Button @tap="fetchAllBackedupImages" text="Get all backedup images"></Button>
                    <StackLayout v-if="backedupImages.length" orientation="horizontal">
                        ...
                    </StackLayout>
                    <RadListView layout="grid" ref="backedupImages" for="image in sortedBackedupImages">
                        <v-template>...</v-template>
                    </RadListView>
                </StackLayout>
            </TabViewItem>
        </TabView>
        <ActivityIndicator></ActivityIndicator>
    </GridLayout>
</Page>

Then you could simply toggle the busy attribute whenever you want to show / hide indicator. If adding ActivityIndicator to every Page is too much, then you could wrap your root Frame with GridLayout and similarly add ActivityIndicator there, so you will not have to add it on every Page.

While this approach works, I would recommend using a progress dialog instead, so you can actually block user from accessing the UI if you like to, Here is Playground Sample for similar approach.

Upvotes: 1

Related Questions