gpt4 book ai didi

android - forceLayout() 在 Android 中是如何工作的

转载 作者:行者123 更新时间:2023-12-03 13:24:45 28 4
gpt4 key购买 nike

this answer我写

forceLayout()

Call forceLayout() if you only want to relayout your own view's content, but don't need to trigger remeasuring of the entire view tree (all the parent views). If you had a custom ViewGroup that wasn't changing its own size but needed to remeasure and relayout its children, this would be an appropriate situation to call forceLayout().

Basically, calling requestLayout() results in a call to parent.requestLayout(), but calling forceLayout() doesn't.



我记得我是通过阅读 documentation 来写我的答案的。和 source code .但是,我没有体验使用 forceLayout .某用户 commented它不像我描述的那样工作。

测试力布局

我终于开始研究造成这种情况的原因。我和祖 parent 建立了一个简单的项目 ViewGroup , 家长 ViewGroup和一个 child View .我为每个 View 都使用了自定义 View ,以便我可以查看 onMeasure 中的日志语句。 , onLayout , 和 onDraw .

当第一次从 xml 创建布局时,我得到以下日志:
ViewGroupGrandparent onMeasure called
ViewGroupParent onMeasure called
MyChildView onMeasure called
ViewGroupGrandparent onMeasure called
ViewGroupParent onMeasure called
MyChildView onMeasure called
ViewGroupGrandparent onLayout called
ViewGroupParent onLayout called
MyChildView onLayout called
MyChildView onDraw called

强制布局

这看起来是合理的输出。然而,当我随后拨打 forceLayout单独对任何意见我一无所获。如果我一次调用它们,那么 subview 的 onDraw被调用。

child
childView.forceLayout();
// (no log output)

parent
viewGroupParent.forceLayout();
// (no log output)

祖 parent
viewGroupGrandparent.forceLayout();
// (no log output)

全部一起
childView.forceLayout();
viewGroupParent.forceLayout();
viewGroupGrandparent.forceLayout();

// MyChildView onDraw called

请求布局

另一方面,拨打 requestLayout有更大的影响。

child
childView.requestLayout();

// ViewGroupGrandparent onMeasure called
// ViewGroupParent onMeasure called
// MyChildView onMeasure called
// ViewGroupGrandparent onLayout called
// ViewGroupParent onLayout called
// MyChildView onLayout called
// MyChildView onDraw called

parent
viewGroupParent.requestLayout();

// ViewGroupGrandparent onMeasure called
// ViewGroupParent onMeasure called
// ViewGroupGrandparent onLayout called
// ViewGroupParent onLayout called

祖 parent
viewGroupGrandparent.requestLayout();

// ViewGroupGrandparent onMeasure called
// ViewGroupGrandparent onLayout called



什么时候开始 forceLayout有什么作用吗?为什么它似乎不像我上面的例子那样工作?

补充代码

这是我用来进行上述测试的代码。

Activity _main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.forcelayout.MainActivity">

<com.example.forcelayout.ViewGroupGrandparent
android:id="@+id/view_group_grandparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<com.example.forcelayout.ViewGroupParent
android:id="@+id/view_group_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<com.example.forcelayout.MyChildView
android:id="@+id/child_view"
android:layout_width="100dp"
android:layout_height="100dp"/>
</com.example.forcelayout.ViewGroupParent>
</com.example.forcelayout.ViewGroupGrandparent>

<Button
android:text="Click me"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="buttonClick"/>

</LinearLayout>

主 Activity .java
public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

public void buttonClick(View view) {
Log.i("TAG", "buttonClick: ");

ViewGroupGrandparent viewGroupGrandparent = (ViewGroupGrandparent) findViewById(R.id.view_group_grandparent);
ViewGroupParent viewGroupParent = (ViewGroupParent) findViewById(R.id.view_group_parent);
MyChildView childView = (MyChildView) findViewById(R.id.child_view);


childView.forceLayout();
//viewGroupParent.forceLayout();
//viewGroupGrandparent.forceLayout();

//childView.requestLayout();
//viewGroupParent.requestLayout();
//viewGroupGrandparent.requestLayout();
}
}

ViewGroupGrandparent.java
public class ViewGroupGrandparent extends LinearLayout {

public ViewGroupGrandparent(Context context) {
super(context);
}

public ViewGroupGrandparent(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public ViewGroupGrandparent(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.i("TAG", "ViewGroupGrandparent onMeasure called");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.i("TAG", "ViewGroupGrandparent onLayout called");
super.onLayout(changed, l, t, r, b);
}

@Override
protected void onDraw(Canvas canvas) {
Log.i("TAG", "ViewGroupGrandparent onDraw called");
super.onDraw(canvas);
}
}

ViewGroupParent.java
public class ViewGroupParent extends LinearLayout {

public ViewGroupParent(Context context) {
super(context);
}

public ViewGroupParent(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public ViewGroupParent(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.i("TAG", "ViewGroupParent onMeasure called");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.i("TAG", "ViewGroupParent onLayout called");
super.onLayout(changed, l, t, r, b);
}

@Override
protected void onDraw(Canvas canvas) {
Log.i("TAG", "ViewGroupParent onDraw called");
super.onDraw(canvas);
}
}

MyChildView.java
public class MyChildView extends View {

public MyChildView(Context context) {
super(context);
}

public MyChildView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public MyChildView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.i("TAG", "MyChildView onMeasure called");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
Log.i("TAG", "MyChildView onLayout called");
super.onLayout(changed, left, top, right, bottom);
}

@Override
protected void onDraw(Canvas canvas) {
Log.i("TAG", "MyChildView onDraw called");
super.onDraw(canvas);
}
}

最佳答案

TL;DR 考虑 TableLayout 中的以下代码:

public void requestLayout() {
if (mInitialized) {
int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).forceLayout();
}
}

super.requestLayout();
}

在这里,TableLayout 的每个子项都将被标记为在 future 的布局传递中通过调用 forceLayout() 进行测量。 .如果 requestLayout() 也会发生类似的处理每个 child 都被调用,但是 requestLayout()通过 View 层次结构冒泡,所以 requestLayout() TableLayout 的子级将调用其父级的 requestLayout() .这将建立一个无限循环,TableLayout 和它的 child 互相调用。 forceLayout()力测量没有无限递归的威胁。

forceLayout() 不打电话 requestLayout()如上所述,但清除 View 的缓存并设置几个标志。
public void forceLayout() {
if (mMeasureCache != null) mMeasureCache.clear();
mPrivateFlags |= PFLAG_FORCE_LAYOUT;
mPrivateFlags |= PFLAG_INVALIDATED;
}

requestLayout() 清除缓存并将这些相同的标志设置为 forceLayout()但也可以拨打 requestLayout()在 parent 身上。
public void requestLayout() {
if (mMeasureCache != null) mMeasureCache.clear();
...
mPrivateFlags |= PFLAG_FORCE_LAYOUT;
mPrivateFlags |= PFLAG_INVALIDATED;

if (mParent != null && !mParent.isLayoutRequested()) {
mParent.requestLayout();
}
...
}
requestLayout()应该在整个层次结构中冒泡。

那么, forceLayout() 是什么意思?其实呢?为了研究这个问题,我使用了提供的应用程序并对其进行了修改以跟踪对 onMeasure() 的调用。 , onLayout()onDraw()对于两个 View 组(祖父和父)和 subview 。我在第一个 child 中添加了一个 sibling ,以比较他们两个的情况。我还使用调试器跟踪对 measure() 的调用和 requestLayout() .输出是在 logcat 中捕获的,并且从 logcat 生成了一个总结操作的电子表格。 (此答案中的源代码和文档引用编目于 this GitHub project

测试应用调用 forceLayout()requestLayout()对于所有可能组合的两个 View 组和 subview - 总共 64 个。 (其中许多组合在现实世界中并不现实,但出于完整性考虑将其包括在内。)下面的电子表格总结了要讨论的关键领域。完整的工作表可以在 GitHub 存储库中找到。

enter image description here

A部分 - 在本节中, forceLayout()被称为三观。正如Suragch 所指出的,除了 onDraw() 之外,没有其他任何事情发生。在 forceLayout() 时调用在所有 View 上调用。这是A部分的日志:

I/MainActivity: 1*******************************************
I/MainActivity: 2*******************************************
I/MainActivity: 3*******************************************
I/MainActivity: 4*******************************************
I/MainActivity: 5*******************************************
I/MainActivity: 6*******************************************
I/MainActivity: 7*******************************************
I/MyChildView: onDraw called (1)



“1****...”对应于电子表格中的行。像“I/MyChildView: onDraw called (1)”这样的行标识 View (“MyChildView”), View 方法(“onDraw”)和“(x)”对于第一个 subview 将是“(1)”,“(2)"用于第二个 subview ,而 "(null)"用于其他非 subview 。

鉴于该方法的名称,这是一个意想不到的结果: forceLayout() .

B区 - 8号线, requestLayout()在 subview 上调用并预期结果:对所有 View 进行测量、布局和绘图过程。第 9 行添加一个调用到 forceLayout()给 child ,但结果是一样的。这是B部分的日志:

/MainActivity: 8*******************************************
I/requestLayout: MyChildView (1)
I/requestLayout: MyChildView isLayoutRequested=false (1)
I/requestLayout: ViewGroupParent (null)
I/requestLayout: ViewGroupParent isLayoutRequested=false (null)
I/requestLayout: ViewGroupGrandparent (null)
I/requestLayout: ViewGroupGrandparent isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: ContentFrameLayout (null)
I/requestLayout: ContentFrameLayout isLayoutRequested=false (null)
I/requestLayout: ActionBarOverlayLayout (null)
I/requestLayout: ActionBarOverlayLayout isLayoutRequested=false (null)
I/requestLayout: FrameLayout (null)
I/requestLayout: FrameLayout isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: DecorView (null)
I/requestLayout: DecorView isLayoutRequested=false (null)
I/measure: ViewGroupGrandparent (null)
I/ViewGroupGrandparent: onMeasure called
I/measure: ViewGroupParent (null)
I/ViewGroupParent: onMeasure called
I/measure: MyChildView (1)
I/MyChildView: onMeasure called (1)
I/measure: MyChildView (2)
I/ViewGroupGrandparent: onLayout called
I/ViewGroupParent: onLayout called
I/MyChildView: onLayout called (1)
I/MyChildView: onDraw called (1)
I/MainActivity: 9*******************************************
I/requestLayout: MyChildView (1)
I/requestLayout: MyChildView isLayoutRequested=false (1)
I/requestLayout: ViewGroupParent (null)
I/requestLayout: ViewGroupParent isLayoutRequested=false (null)
I/requestLayout: ViewGroupGrandparent (null)
I/requestLayout: ViewGroupGrandparent isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: ContentFrameLayout (null)
I/requestLayout: ContentFrameLayout isLayoutRequested=false (null)
I/requestLayout: ActionBarOverlayLayout (null)
I/requestLayout: ActionBarOverlayLayout isLayoutRequested=false (null)
I/requestLayout: FrameLayout (null)
I/requestLayout: FrameLayout isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: DecorView (null)
I/requestLayout: DecorView isLayoutRequested=false (null)
I/measure: ViewGroupGrandparent (null)
I/ViewGroupGrandparent: onMeasure called
I/measure: ViewGroupParent (null)
I/ViewGroupParent: onMeasure called
I/measure: MyChildView (1)
I/MyChildView: onMeasure called (1)
I/measure: MyChildView (2)
I/ViewGroupGrandparent: onLayout called
I/ViewGroupParent: onLayout called
I/MyChildView: onLayout called (1)
I/MyChildView: onDraw called (1)



C区 - 这就是事情变得有趣的地方。对于第 10 行和第 11 行, requestLayout()在 subview 和 forceLayout() 上调用在 child 的父 View 上调用。结果是我们在 B 部分看到的后续测量/布局/绘制 channel 不会发生。我相信这就是流体声波说 forceLayout() 的原因被打破。见 https://stackoverflow.com/a/44781500/6287910 .

其实 subview 考虑调用 requestLayout()在父级上,但发现已经在父级上请求了布局。 ( mParent != null && !mParent.isLayoutRequested() )。这是一个 linkisLayoutRequested() 的代码.
public boolean isLayoutRequested() {
return (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
}

请记住 forceLayout()设置 PFLAG_FORCE_LAYOUT旗帜。这就是为什么 requestLayout()链在父节点处停止。这可能是一个问题或只是滥用 forceLayout() .

继续 C 部分的其余部分,我们最多可以“强制”调用 child 的 onDraw() .

这是 C 部分的日志:

I/MainActivity: 10*******************************************
I/requestLayout: MyChildView (1)
I/requestLayout: MyChildView isLayoutRequested=true (1)
I/MainActivity: 11*******************************************
I/requestLayout: MyChildView (1)
I/requestLayout: MyChildView isLayoutRequested=true (1)
I/MainActivity: 12*******************************************
I/requestLayout: MyChildView (1)
I/requestLayout: MyChildView isLayoutRequested=false (1)
I/requestLayout: ViewGroupParent (null)
I/requestLayout: ViewGroupParent isLayoutRequested=true (null)
I/MyChildView: onDraw called (1)
I/MainActivity: 13*******************************************
I/requestLayout: MyChildView (1)
I/requestLayout: MyChildView isLayoutRequested=false (1)
I/requestLayout: ViewGroupParent (null)
I/requestLayout: ViewGroupParent isLayoutRequested=true (null)
I/MyChildView: onDraw called (1)
I/MainActivity: 14*******************************************
I/requestLayout: MyChildView (1)
I/requestLayout: MyChildView isLayoutRequested=true (1)
I/MyChildView: onDraw called (1)
I/MainActivity: 15*******************************************
I/requestLayout: MyChildView (1)
I/requestLayout: MyChildView isLayoutRequested=true (1)
I/MyChildView: onDraw called (1)



D区 - 此部分可能包含 forceLayout() 的 secret .在第 16 行,拨打 requestLayout()在父级上会导致父级和祖父级的测量/布局通过,但不是子级。如果拨打 forceLayout()是在 child 身上制作的,然后 child 被包括在内。其实是打给 child 的 onMeasure()而不会调用其兄弟的 onMeasure() .这是由于拨打了 forceLayout()在 child 身上。所以,似乎,这里 forceLayout()被用来强制框架测量通常不会被测量的 child 。我会注意到这似乎只发生在 forceLayout()requestLayout() 的目标 View 的 _direct 后代上调用.

这种类型的处理的一个例子是在 TableLayout 中。在 requestLayout()在 TableLayout 中覆盖, forceLayout()每个 child 都被召唤。这将避免拨打 requestLayout()在每个 child 和相关的开销上(虽然可能很小)。它也将避免灾难性的递归,因为 child 的 requestLayout()可调用家长的 requestLayout()这将称为 child 的......你明白了。这是 code from TableLayout :
public void requestLayout() {
if (mInitialized) {
int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).forceLayout();
}
}

super.requestLayout();
}

在ListView.java中,需要重新测量一个child再重用查看代码 here . forceLayout()在这里工作是为了让 child 重新测量。
// Since this view was measured directly aginst the parent measure
// spec, we must measure it again before reuse.
child.forceLayout();

这是 D 部分的日志:

I/MainActivity: 16*******************************************
I/requestLayout: ViewGroupParent (null)
I/requestLayout: ViewGroupParent isLayoutRequested=false (null)
I/requestLayout: ViewGroupGrandparent (null)
I/requestLayout: ViewGroupGrandparent isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: ContentFrameLayout (null)
I/requestLayout: ContentFrameLayout isLayoutRequested=false (null)
I/requestLayout: ActionBarOverlayLayout (null)
I/requestLayout: ActionBarOverlayLayout isLayoutRequested=false (null)
I/requestLayout: FrameLayout (null)
I/requestLayout: FrameLayout isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: DecorView (null)
I/requestLayout: DecorView isLayoutRequested=false (null)
I/measure: ViewGroupGrandparent (null)
I/ViewGroupGrandparent: onMeasure called
I/measure: ViewGroupParent (null)
I/ViewGroupParent: onMeasure called
I/measure: MyChildView (1)
I/measure: MyChildView (2)
I/ViewGroupGrandparent: onLayout called
I/ViewGroupParent: onLayout called
I/MainActivity: 17*******************************************
I/requestLayout: ViewGroupParent (null)
I/requestLayout: ViewGroupParent isLayoutRequested=false (null)
I/requestLayout: ViewGroupGrandparent (null)
I/requestLayout: ViewGroupGrandparent isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: ContentFrameLayout (null)
I/requestLayout: ContentFrameLayout isLayoutRequested=false (null)
I/requestLayout: ActionBarOverlayLayout (null)
I/requestLayout: ActionBarOverlayLayout isLayoutRequested=false (null)
I/requestLayout: FrameLayout (null)
I/requestLayout: FrameLayout isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: DecorView (null)
I/requestLayout: DecorView isLayoutRequested=false (null)
I/measure: ViewGroupGrandparent (null)
I/ViewGroupGrandparent: onMeasure called
I/measure: ViewGroupParent (null)
I/ViewGroupParent: onMeasure called
I/measure: MyChildView (1)
I/MyChildView: onMeasure called (1)
I/measure: MyChildView (2)
I/ViewGroupGrandparent: onLayout called
I/ViewGroupParent: onLayout called
I/MyChildView: onLayout called (1)
I/MyChildView: onDraw called (1)



E段 - 本节进一步说明只有对 requestLayout() 的调用的目标 View 的直接后代似乎参与触发布局传递。第 34 和 35 行似乎表明嵌套 View 可以链接。

这是 E 部分的日志:

I/MainActivity: 32*******************************************
I/requestLayout: ViewGroupGrandparent (null)
I/requestLayout: ViewGroupGrandparent isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: ContentFrameLayout (null)
I/requestLayout: ContentFrameLayout isLayoutRequested=false (null)
I/requestLayout: ActionBarOverlayLayout (null)
I/requestLayout: ActionBarOverlayLayout isLayoutRequested=false (null)
I/requestLayout: FrameLayout (null)
I/requestLayout: FrameLayout isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: DecorView (null)
I/requestLayout: DecorView isLayoutRequested=false (null)
I/measure: ViewGroupGrandparent (null)
I/ViewGroupGrandparent: onMeasure called
I/measure: ViewGroupParent (null)
I/ViewGroupGrandparent: onLayout called
I/MainActivity: 33*******************************************
I/requestLayout: ViewGroupGrandparent (null)
I/requestLayout: ViewGroupGrandparent isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: ContentFrameLayout (null)
I/requestLayout: ContentFrameLayout isLayoutRequested=false (null)
I/requestLayout: ActionBarOverlayLayout (null)
I/requestLayout: ActionBarOverlayLayout isLayoutRequested=false (null)
I/requestLayout: FrameLayout (null)
I/requestLayout: FrameLayout isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: DecorView (null)
I/requestLayout: DecorView isLayoutRequested=false (null)
I/measure: ViewGroupGrandparent (null)
I/ViewGroupGrandparent: onMeasure called
I/measure: ViewGroupParent (null)
I/ViewGroupGrandparent: onLayout called
I/MainActivity: 34*******************************************
I/requestLayout: ViewGroupGrandparent (null)
I/requestLayout: ViewGroupGrandparent isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: ContentFrameLayout (null)
I/requestLayout: ContentFrameLayout isLayoutRequested=false (null)
I/requestLayout: ActionBarOverlayLayout (null)
I/requestLayout: ActionBarOverlayLayout isLayoutRequested=false (null)
I/requestLayout: FrameLayout (null)
I/requestLayout: FrameLayout isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: DecorView (null)
I/requestLayout: DecorView isLayoutRequested=false (null)
I/measure: ViewGroupGrandparent (null)
I/ViewGroupGrandparent: onMeasure called
I/measure: ViewGroupParent (null)
I/ViewGroupParent: onMeasure called
I/measure: MyChildView (1)
I/measure: MyChildView (2)
I/ViewGroupGrandparent: onLayout called
I/ViewGroupParent: onLayout called
I/MainActivity: 35*******************************************
I/requestLayout: ViewGroupGrandparent (null)
I/requestLayout: ViewGroupGrandparent isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: ContentFrameLayout (null)
I/requestLayout: ContentFrameLayout isLayoutRequested=false (null)
I/requestLayout: ActionBarOverlayLayout (null)
I/requestLayout: ActionBarOverlayLayout isLayoutRequested=false (null)
I/requestLayout: FrameLayout (null)
I/requestLayout: FrameLayout isLayoutRequested=false (null)
I/requestLayout: LinearLayout (null)
I/requestLayout: LinearLayout isLayoutRequested=false (null)
I/requestLayout: DecorView (null)
I/requestLayout: DecorView isLayoutRequested=false (null)
I/measure: ViewGroupGrandparent (null)
I/ViewGroupGrandparent: onMeasure called
I/measure: ViewGroupParent (null)
I/ViewGroupParent: onMeasure called
I/measure: MyChildView (1)
I/MyChildView: onMeasure called (1)
I/measure: MyChildView (2)
I/ViewGroupGrandparent: onLayout called
I/ViewGroupParent: onLayout called
I/MyChildView: onLayout called (1)
I/MyChildView: onDraw called (1)



所以这是我对 forceLayout() 的总结: 当有需要重新测量的子元素时使用它,例如在 TableLayout 中并且您不想调用 requestLayout()每个 child - forceLayout()重量更轻,将避免递归。 (请参阅 C 部分中的注释。) forceLayout()也可用于在需要时强制重新测量特定的直接子级,而它们通常不会被测量。 forceLayout()不能单独工作,必须与对 requestLayout() 的适当调用配对

关于android - forceLayout() 在 Android 中是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45383948/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com