更改列表元素字体大小

时间:2016-12-27 06:42:55

标签: angular nativescript angular2-nativescript

我正在构建一个NativeScript应用程序,它在ListView中显示文本行。每行(现在)有几个Label字段,一行显示可选行标签,另一行显示文本。我希望字体大小能够根据行的实际宽度自动缩放。我很难让它正常工作。我有三个主要问题,如下所述。这是我到目前为止所做的:

行布局:

<GridLayout columns="*,25">
    <Label #text [text]="row.full.join(' ')" col="0" class="pointed tikkuntext"></Label>
    <Label #label col="1" class="tikkunlabel" *ngIf="row.label">
        <FormattedString>
            <Span #chapter *ngIf="row.label.chapter" [text]="row.label.chapter + ' '" fontSize="11" fontAtttributes="Bold"></Span>
            <Span #verse [text]="row.label.verse.join(',')"></Span>
        </FormattedString>
    </Label>
</GridLayout>

这封装在每行的自定义组件中:

import { Component, ElementRef, Input, AfterViewInit, ViewChild } from '@angular/core';
import { Page } from "ui/page";
import { Label } from "ui/label";
import { Span } from "text/span";

@Component({
    moduleId: module.id,
    selector: "tikkun-row",
    styleUrls: ["tikkun-row.css"],
    templateUrl: "tikkun-row.component.html"
})
export class TikkunRow implements AfterViewInit {
    @Input() row: any;
    @ViewChild("text") textField: ElementRef;
    @ViewChild("label") labelField: ElementRef;
    @ViewChild("chapter") chapterSpan: ElementRef;

    constructor(private page: Page) {}

    ngAfterViewInit() {
        let width = this.page.frame.getActualSize().width;
        width /= 375; // magic number!
        if (width > 0) {
            let textSize = 14 * width; // more magic numbers!
            let verseSize = 9 * width;
            let chapterSize = 11 * width;

            let textField = <Label>this.textField.nativeElement;
            textField.style.fontSize = textSize;
            if (this.labelField) {
                let labelField = <Label>this.labelField.nativeElement;
                labelField.style.fontSize = verseSize;
                if (this.chapterSpan) {
                    let span = <Span>this.chapterSpan.nativeElement
                    span.fontSize = chapterSize;
                }
            }
        }
    }
}

这是ngAfterViewInit()方法,我需要一些帮助。

问题1

我的第一个问题是文本缩放并不总是适用于Android中列表的第一行:

image from Android emulator

这似乎是断断续续的;每隔一段时间第一行就会正确显示,但大部分时间都如上所示。我无法弄清楚它的模式。奇怪的是,如果我每次调用ngAfterViewInit()时都记录宽度,我会在iOS中获得一个控制台输出行,在Android中获得八个输出行(其中第一个是0,其他是相同的正值)。尽管列表有七行!

编辑我已经设法通过修改我探测宽度的方式来消除这个问题(但并不完全)。我没有对getActualSize()进行一次性调用,而是在定时循环中进行。以下是相关的代码更改:

ngAfterViewInit() {
    let width = this.page.frame.getActualSize().width;
    let wait = () => {
        if (width > 0) {
            // the same stuff as before
        } else {
            width = this.page.frame.getActualSize().width;
            setTimeout(wait, 10);
        }
    };
    wait();
}

随着这种变化,间歇性缺乏字体缩放几乎完全消失了。然而,一旦罕见,它仍然出现。也许很重要,当它确实出现时并不总是在列表的第一行。它并不总是整排;有时它只是右侧标签。也许这更像是一个渲染问题?

问题2

在iOS上,每行的两个<Label>元素在文本基线上垂直对齐,如下所示:

image from iOS emulator

在Android上,我无法做到这一点。上面第一张图片中的内容是使用vertical-align: center的效果,这是我能得到的最接近的效果。遗憾的是,NativeScript仅支持topcenterbottomstretch,其中任何一个都不正常。有没有办法(可能通过降低到本机)强制Android中GridLayout行的基线对齐?

问题3

似乎ngAfterViewInit()不是覆盖的正确生命周期方法。它在开始时被调用(一次用于iOS,每行一次[+1额外!]用于Android),但如果我在iOS或Android中更改横向和纵向之间的设备方向,则不会调用它。我已经尝试了所有Angular lifecycle hooks,似乎没有任何工作正常。有没有办法检测行的实际宽度何时发生变化,以便更新文本(和标签)大小?在某个地方我可以订阅一些有用的事件吗?

0 个答案:

没有答案