это демонстрирует, почему TableLayout вызывает forceLayout () для своих дочерних элементов. Смотрите комментарии в MainActivity.java для описания. Надеюсь, это поможет немного прояснить ситуацию.

т ответ я написалВызов

forceLayout()

 если вы хотите только ретранслировать содержимое своего собственного представления, но не должны запускать повторное измерение всего дерева представлений (всех родительских представлений). Если у вас был обычайforceLayout() который не изменял свой собственный размер, но должен был переизмерить и ретранслировать своих детей, это была бы подходящая ситуация для вызоваViewGroupВ основном звонитforceLayout().

 приводит к звонкуrequestLayout(), но зоветparent.requestLayout() не делает.forceLayout()Насколько я помню, я написал свой ответ, прочитав

документация а такжеисходный код, Тем не менее, я не испытывал использование, ПользовательforceLayoutпрокомментировал что это не работает, как я описал.Тестирование forceLayout

Я наконец дошел до исследования причины этого. Я создал простой проект с бабушкой и дедушкой

, родительViewGroupи ребенокViewGroup, Я использовал настраиваемые представления для каждого из них, чтобы можно было просматривать операторы журнала вView, а такжеonMeasure, onLayoutКогда макет впервые создается из XML, я получаю следующий журнал:onDraw.

forceLayout

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 вызывается.onDrawребенок

родитель

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

бабушка или дедушка

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

все вместе

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

requestLayout

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

// MyChildView onDraw called
С другой стороны, звонит

 имеет гораздо больший эффект.requestLayoutребенок

родитель

childView.requestLayout();

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

бабушка или дедушка

viewGroupParent.requestLayout();

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

Вопрос

viewGroupGrandparent.requestLayout();

// ViewGroupGrandparent onMeasure called
// ViewGroupGrandparent onLayout called
Когда делает

 есть какой-либо эффект? Почему это не работает так, как предполагается в моих примерах выше?forceLayoutДополнительный код

Вот код, который я использовал для тестирования выше.

activity_main.xml

MainActivity.java

<?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>

ViewGroupGrandparent.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();
    }
}

ViewGroupParent.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);
    }
}

MyChildView.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);
    }
}

 Я немного запутался с этим выводом, потому что, как

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);
    }
}

Ответы на вопрос(0)

Ваш ответ на вопрос