处理依赖于 View 维度的繁重操作
Handling heavy operations that depend on `View`'s dimensions
我正在实施一个必须从磁盘加载 Bitmap
的自定义 ImageView
。 Bitmap
应该精确缩放,它的宽度必须等于父布局分配给我的 ImageView
的最终宽度,并且计算高度以保持纵横比。
所以,问题是 在 View
生命周期中什么地方适合放置依赖于布局完成后已知的 View
维度的繁重操作?
(但我想保持简单,不使用线程。)
- 很可能将该代码放在
onDraw()
方法中是个坏主意,
因为它应该尽可能高效。另一方面,我的
ImageView
不太可能调整大小,因此它只会杀死
first onDraw()
的表现,不会影响后续
调用 onDraw()
。所以我不确定这个选项。
- 我可以把它放在
onLayout(boolean
changed, int l, int t, int r, int b)
执行我的结尾
重代码 if (changed == true)
。这是个好主意吗?
- 我看到的第三个选项是在
onSizeChanged()
回调中进行。
我唯一关心的是这个回调是否保证
每个实际视图的大小更改仅调用一次。我倾向于使用
这个选项,因为在我的测试中它工作正常。
有人可以对此发表见解吗?
选项 2 和 3 都可以让您获得视图的正确尺寸。
onDraw()
仅在 onLayout()
之后调用。您可以在 onLayout()
中获取尺寸,最好避免在 onDraw()
中做任何不必要的工作。所以我会选择选项 2 或选项 3。
还要注意 onSizeChanged()
有时被称为零。伊恩 in this thread:
Be aware too that onSizeChanged() is sometimes called with parameters
of zero -- check for this case, and return immediately (so you don't
get a divide by zero when calculating your layout, etc.). Some time
later it will be called with the real values.
另一种选择是使用 View.post()
将可运行对象添加到视图的队列中
引用和示例 from this thread:
The UI event queue will process events in order. After
setContentView() is invoked, the event queue will contain a message
asking for a relayout, so anything you post to the queue will happen
after the layout pass
final View view=//smth;
...
view.post(new Runnable() {
@Override
public void run() {
view.getHeight(); //height is ready
}
});
使用这种方法,我们可以确保我们的代码只执行一次。
我正在实施一个必须从磁盘加载 Bitmap
的自定义 ImageView
。 Bitmap
应该精确缩放,它的宽度必须等于父布局分配给我的 ImageView
的最终宽度,并且计算高度以保持纵横比。
所以,问题是 在 View
生命周期中什么地方适合放置依赖于布局完成后已知的 View
维度的繁重操作?
(但我想保持简单,不使用线程。)
- 很可能将该代码放在
onDraw()
方法中是个坏主意, 因为它应该尽可能高效。另一方面,我的ImageView
不太可能调整大小,因此它只会杀死 firstonDraw()
的表现,不会影响后续 调用onDraw()
。所以我不确定这个选项。 - 我可以把它放在
onLayout(boolean changed, int l, int t, int r, int b)
执行我的结尾 重代码if (changed == true)
。这是个好主意吗? - 我看到的第三个选项是在
onSizeChanged()
回调中进行。 我唯一关心的是这个回调是否保证 每个实际视图的大小更改仅调用一次。我倾向于使用 这个选项,因为在我的测试中它工作正常。
有人可以对此发表见解吗?
选项 2 和 3 都可以让您获得视图的正确尺寸。
onDraw()
仅在 onLayout()
之后调用。您可以在 onLayout()
中获取尺寸,最好避免在 onDraw()
中做任何不必要的工作。所以我会选择选项 2 或选项 3。
还要注意 onSizeChanged()
有时被称为零。伊恩 in this thread:
Be aware too that onSizeChanged() is sometimes called with parameters of zero -- check for this case, and return immediately (so you don't get a divide by zero when calculating your layout, etc.). Some time later it will be called with the real values.
另一种选择是使用 View.post()
将可运行对象添加到视图的队列中引用和示例 from this thread:
The UI event queue will process events in order. After setContentView() is invoked, the event queue will contain a message asking for a relayout, so anything you post to the queue will happen after the layout pass
final View view=//smth;
...
view.post(new Runnable() {
@Override
public void run() {
view.getHeight(); //height is ready
}
});
使用这种方法,我们可以确保我们的代码只执行一次。