Apakah ada cara untuk membuat NativeScript GridLayout dengan rasio aspek tetap?

Pertama-tama, saya ingin meminta maaf jika saya gagal mematuhi aturan SO, karena ini pertanyaan pertama saya.

Apa yang ingin saya capai adalah memiliki gridLayout persegi di halaman saya. Perilaku tersebut harus setara dengan memiliki elemen dengan stretch="aspectFit".

Jika solusi yang disarankan memungkinkan saya menerapkan rasio aspek tertentu dan bukan hanya rasio aspek persegi, ini akan menjadi nilai tambah yang bagus, karena akan memungkinkan saya menyelesaikan berbagai situasi di masa mendatang. Atau kalau bisa diterapkan ke elemen Layout apa pun, alangkah baiknya juga.

Solusinya dapat diretas sesuai keinginan, dan GridLayout dapat disarangkan dengan cara apa pun yang Anda perlukan untuk mencapainya.

Saya sudah mencoba meretasnya seperti ini:

 <GridLayout rows="*,auto,*" columns="*,auto,*" backgroundColor="green">
  <Image row="1" col="1" src="~/Images/1px-black.png" stretch="aspectFit" width="100%"></Image>
  <StackLayout row="1" col="1" orientation="vertical" backgroundColor="lightgray">
    <Label text="Label 1" width="100%" height="25%" backgroundColor="red"></Label>
    <Label text="Label 2" width="100%" height="25%" backgroundColor="green"></Label>
    <Label text="Label 3" width="100%" height="25%" backgroundColor="blue"></Label>
    <Label text="Label 4" width="100%" height="25%" backgroundColor="yellow"></Label>
  </StackLayout>
</GridLayout>

Secara visual tampaknya berfungsi, tetapi isi GridLayout tidak mengisinya dengan tepat

PS: Saya baru memperhatikan pada contoh yang saya pilih, elemen tata letak yang saya coba buat persegi adalah StackLayout bersarang, tetapi idenya sama. Saya memerlukan cara untuk membuat elemen tata letak bersarang menjadi persegi.


person Uka Lpts    schedule 08.07.2016    source sumber
comment
Apakah Anda bersedia memiliki JS yang berjalan pada acara yang dimuat? Jika iya, hal ini merupakan hal yang sepele untuk dilakukan. Jika Anda menginginkannya dalam XML murni, itu tidak mungkin karena tidak ada yang membatasi nilai Y ke X (atau X ke Y) yang ada di dalam grid.   -  person Nathanael    schedule 09.07.2016
comment
@Nathanael Saya terbuka untuk solusi apa pun. Saya sedang dalam tahap awal perkembangan, jadi saya pikir saya bisa mengatasi hampir semua solusi   -  person Uka Lpts    schedule 09.07.2016
comment
@Nathanael Saya juga harus menyatakan bahwa saya sedang mengerjakan aplikasi Angular2. Mungkin peristiwa atau siklus hidup mempengaruhi jawabannya   -  person Uka Lpts    schedule 09.07.2016


Jawaban (3)


Terima kasih kepada @Nathanael karena telah memberi saya wawasan tentang apa yang mungkin bisa saya lakukan.

Saya menemukan solusinya dan ini dia untuk siapa saja yang mungkin membutuhkannya.

Pertama-tama, saya akan menggunakan Template berikut:

<GridLayout rows="2*,3*,*,3*,*,3*,*,3*,2*" columns="2*,3*,*,3*,*,3*,*,3*,2*" backgroundColor="green" #refGrid>
    <Label text="A1" col="1" row="1" backgroundColor="#899bfe"></Label>
    <Label text="A2" col="1" row="3" backgroundColor="#899bfe"></Label>
    <Label text="A3" col="1" row="5" backgroundColor="#899bfe"></Label>
    <Label text="A4" col="1" row="7" backgroundColor="#899bfe"></Label>

    <Label text="B1" col="3" row="1" backgroundColor="#899bfe"></Label>
    <Label text="B2" col="3" row="3" backgroundColor="#899bfe"></Label>
    <Label text="B3" col="3" row="5" backgroundColor="#899bfe"></Label>
    <Label text="B4" col="3" row="7" backgroundColor="#899bfe"></Label>

    <Label text="C1" col="5" row="1" backgroundColor="#899bfe"></Label>
    <Label text="C2" col="5" row="3" backgroundColor="#899bfe"></Label>
    <Label text="C3" col="5" row="5" backgroundColor="#899bfe"></Label>
    <Label text="C4" col="5" row="7" backgroundColor="#899bfe"></Label>

    <Label text="D1" col="7" row="1" backgroundColor="#899bfe"></Label>
    <Label text="D2" col="7" row="3" backgroundColor="#899bfe"></Label>
    <Label text="D3" col="7" row="5" backgroundColor="#899bfe"></Label>
    <Label text="D4" col="7" row="7" backgroundColor="#899bfe"></Label>
</GridLayout>

Tujuan saya adalah membuat GridLayout terlihat persegi dan terpusat di layar, apa pun rasio aspek perangkat atau layarnya. Untuk mencapai hal ini saya melakukan hal berikut dalam JavaScript (atau TypeScript dalam hal ini, karena saya bekerja dengan Angular2 + Nativescript) di dalam Definisi Komponen

ngAfterViewInit() {
    let grid: GridLayout = <GridLayout>this.refGrid.nativeElement;
    var x = grid.getActualSize();

    function wait() {
        if (x.width <= 0) {
            x = grid.getActualSize();
            setTimeout(wait, 10);
        } else {
            grid.width=Math.min(x.width, x.height);
            grid.height=Math.min(x.width, x.height);          
        }
    }
    wait();
}

Dan inilah hasilnya:

Tata Letak Grid Persegi dalam berbagai resolusi layar dan rasio aspek

person Uka Lpts    schedule 10.07.2016

Anda dapat menggunakan properti asli tata letak kisi. Anda perlu memastikan grid Anda memenuhi seluruh layar (dapat dilakukan dengan menargetkannya menggunakan kelas css). Kemudian Anda dapat membuat resolusi yang Anda perlukan dalam baris dan kolom, perhatikan penggunaan x* untuk menentukan lebar relatif, demo pilihan saya memiliki 10, jadi * mewakili 10%.

Anda kemudian dapat menyarangkan tata letak lain di sel kisi jika Anda mau.

<GridLayout rows="*,*,*,*" columns="*,2*,3*,4*">
  <Label row="0" col="0" [colSpan]="4" backgroundColor="lightgray"> // Will be 100% width, height will be 10%
  </Label>
  <Label row="1" col="0" [colSpan]="4" backgroundColor="blue"> // Will be 100% width, height will be 20%
  </Label>
  <Label row="2" col="0" [colSpan]="4" backgroundColor="green"> // Will be 100% width, height will be 30%
  </Label>
  <Label row="3" col="0" [colSpan]="4" backgroundColor="red"> // Will be 100% width, height will be 40%
  </Label>
</GridLayout>

Semoga itu bisa membantu.

person George Edwards    schedule 10.07.2016

Kode di bawah ini berfungsi untuk saya - kode ini menghabiskan seluruh ruang di layar. Anda mungkin menginginkan sesuatu yang berbeda untuk layar yang lebih besar.

<FlexboxLayout flexDirection="row" flexWrap="wrap">
    <GridLayout flexGrow="1" row="*" columns="*" *ngFor="let tile of tiles" [width]="len" [height]="len">
        <StackLayout horizontalAlignment="center" verticalAlignment="center">
            <Label [text]="tile.line"></Label>
        </StackLayout>
    </GridLayout>
</FlexboxLayout>

Nilai len dihitung sebagai berikut:

import {isAndroid, isIOS, screen} from "tns-core-modules/platform";
...
ngAfterViewInit() { 
    this.len = screen.mainScreen.widthDIPs / 2;
}
person Leukipp    schedule 06.01.2020