Android:在渲染之前测量视图的大小

Cor*_*der 5 android view measure

我有一个TextView,显示更改和运行时间的文本.我想使用View.getLineCount()方法来查看TextView占用多少行并相应地执行不同的功能.问题是我需要确定TextView在相同方法中占用的行数,需要知道它占用了多少行.我试过在两次调用之间调用View.invalidate(),但似乎没有解决任何问题.如果可能的话,我想测量行数而不渲染视图,但如果我必须渲染它,我也会愿意这样做.如果这不够具体,请告诉我,我会尝试更具体.谢谢!

Sam*_*udd 1

这实际上是 Android 中一个非常复杂的问题。如果您需要知道设置文本的时间(即在渲染视图之前或接近渲染视图之前),那么您唯一真正的选择是使用 StaticLayout。如果您可以等到接近渲染时间,则可以使用 viewTreeObserver:

yourTextView.getViewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout(){
        yourTextView.getLineCount();
    }
}
Run Code Online (Sandbox Code Playgroud)

onGlobalLayout 可以被多次调用,有时(无论出于什么原因)我发现视图实际上还没有布局,所以你应该做一些日志记录,看看是否能找到一种方法来确保你实际得到的结果有道理(即行数> 0)。

StaticLayouts 是一个更复杂的替代方案,它应该能够为您提供视图的大小和行数。它们可能需要一些调整才能正常工作,并确保您使用要测量的视图中的油漆:

yourTextView.setText(newText);
//the last boolean should be true if you're using padding on your view
StaticLayout measure = new StaticLayout(yourTextView.getText(), yourTextView.getPaint(), 
    maxAvailableWidthForYourTextView, Layout.Alignment.ALIGN_NORMAL, 1.0f, 1.0f, false)

int numberOfLines = measure.getLineCount();
Run Code Online (Sandbox Code Playgroud)

如果您愿意(或已经拥有)子类化 TextView,则可以重写 onSizeChanged 或 onMeasure 并尝试获取其中的行数。同样,与视图树观察器一样,有时可以在实际测量视图之前调用这些方法,因此您可能必须检查以确保在这些方法中获得的任何值都有意义。