Pla*_*eon 194 android android-layout
我有一个自定义视图,可以将可滚动的位图绘制到屏幕上.为了初始化它,我需要传递父布局对象的像素大小.但是在onCreate和onResume函数期间,尚未绘制布局,因此layout.getMeasuredHeight()返回0.
作为一种解决方法,我添加了一个处理程序等待一秒然后测量.这是有效的,但它很草率,我不知道在布局绘制之前我能在多长时间内缩短时间.
我想知道的是,如何检测布局何时被绘制?有事件或回调吗?
ble*_*enm 381
您可以将树观察器添加到布局中.这应该返回正确的宽度和高度.onCreate()在完成子视图的布局之前调用.所以宽度和高度尚未计算.要获得高度和宽度,请将其放在onCreate()方法上:
final LinearLayout layout = (LinearLayout) findViewById(R.id.YOUR_VIEW_ID);
ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener (new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
layout.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
} else {
layout.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
}
int width = layout.getMeasuredWidth();
int height = layout.getMeasuredHeight();
}
});
Run Code Online (Sandbox Code Playgroud)
Ell*_*ica 63
一个非常简单的方法就是简单地调用post()你的布局.在您的视图创建完成后,这将在下一步运行您的代码.
YOUR_LAYOUT.post( new Runnable() {
@Override
public void run() {
int width = YOUR_LAYOUT.getMeasuredWidth();
int height = YOUR_LAYOUT.getMeasuredHeight();
}
});
Run Code Online (Sandbox Code Playgroud)
小智 21
为避免弃用代码和警告,您可以使用:
view.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
} else {
view.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
}
yourFunctionHere();
}
});
Run Code Online (Sandbox Code Playgroud)
Vin*_*gas 13
androidx.core-ktx 已经有这个
/**
* Performs the given action when this view is next laid out.
*
* The action will only be invoked once on the next layout and then removed.
*
* @see doOnLayout
*/
public inline fun View.doOnNextLayout(crossinline action: (view: View) -> Unit) {
addOnLayoutChangeListener(object : View.OnLayoutChangeListener {
override fun onLayoutChange(
view: View,
left: Int,
top: Int,
right: Int,
bottom: Int,
oldLeft: Int,
oldTop: Int,
oldRight: Int,
oldBottom: Int
) {
view.removeOnLayoutChangeListener(this)
action(view)
}
})
}
/**
* Performs the given action when this view is laid out. If the view has been laid out and it
* has not requested a layout, the action will be performed straight away, otherwise the
* action will be performed after the view is next laid out.
*
* The action will only be invoked once on the next layout and then removed.
*
* @see doOnNextLayout
*/
public inline fun View.doOnLayout(crossinline action: (view: View) -> Unit) {
if (ViewCompat.isLaidOut(this) && !isLayoutRequested) {
action(this)
} else {
doOnNextLayout {
action(it)
}
}
}
Run Code Online (Sandbox Code Playgroud)
Ser*_*gio 12
使用 kotlin 扩展功能更好
inline fun View.waitForLayout(crossinline yourAction: () -> Unit) {
val vto = viewTreeObserver
vto.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
when {
vto.isAlive -> {
vto.removeOnGlobalLayoutListener(this)
yourAction()
}
else -> viewTreeObserver.removeOnGlobalLayoutListener(this)
}
}
})
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
105645 次 |
| 最近记录: |