Java 嵌套的LinearLayouts LayoutTransition动画在移除子对象时跳转

Java 嵌套的LinearLayouts LayoutTransition动画在移除子对象时跳转,java,android,android-layout,android-animation,android-linearlayout,Java,Android,Android Layout,Android Animation,Android Linearlayout,我已经创建了嵌套的LinearLayouts,其中包含子按钮和其他LinearLayouts,wrap_内容和animateLayoutChanges设置为true 代码如下 当我从嵌套线性布局中删除按钮时,动画会播放删除按钮的过程,但随后会再次重复,从而在整个嵌套布局中创建跳跃效果 这似乎是一个发生在API 19和API 25中的错误-可能还有其他错误(尚未测试),但它在API>=27上运行得非常好,所以他们必须为这些版本的Android修复它或更改某些内容,我不知道它是什么 问题是,我希望

我已经创建了嵌套的LinearLayouts,其中包含子按钮和其他LinearLayouts,wrap_内容和animateLayoutChanges设置为true

代码如下

当我从嵌套线性布局中删除按钮时,动画会播放删除按钮的过程,但随后会再次重复,从而在整个嵌套布局中创建跳跃效果

这似乎是一个发生在API 19和API 25中的错误-可能还有其他错误(尚未测试),但它在API>=27上运行得非常好,所以他们必须为这些版本的Android修复它或更改某些内容,我不知道它是什么

问题是,我希望它适用于所有API>=19

是否有任何方法可以解决此问题/错误或代码解决方法,从而使其适用于其他版本的Android 代码示例

单击按钮GR1以在蓝色LinearLayout(id=linearLayoutB)中创建新的子视图(按钮),然后再次单击该按钮以删除该按钮,以查看所提到的任何较低Android API版本上的动画问题

单击按钮R3在灰色线性布局(id=linearLayoutGR)中创建一个新的子按钮,该子按钮不嵌套在任何其他线性布局中,但对于任何支持LayoutTransition的Android版本,可以添加和删除该子按钮,而不会出现任何动画问题

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
tools:context=".MainActivity">

<LinearLayout
    android:id="@+id/linearLayoutGR"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:background="#ddd"
    android:animateLayoutChanges="true"
    android:orientation="horizontal"
    android:padding="5dp">

    <Button
        android:id="@+id/btnGR1"
        android:layout_width="50dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="GR1"/>

    <LinearLayout
        android:id="@+id/linearLayoutR"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="#fdd"
        android:animateLayoutChanges="true"
        android:orientation="vertical"
        android:padding="5dp">

        <Button
            android:id="@+id/btnR1"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="R1"/>

        <Button
            android:id="@+id/btnR2"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="R2"/>

        <Button
            android:id="@+id/btnR3"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="R3"/>

        <LinearLayout
            android:id="@+id/linearLayoutG"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:background="#dfd"
            android:animateLayoutChanges="true"
            android:orientation="vertical"
            android:padding="5dp">

            <Button
                android:id="@+id/btnG1"
                android:layout_width="50dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="G1"/>

            <Button
                android:id="@+id/btnG2"
                android:layout_width="50dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="G2"/>

            <LinearLayout
                android:id="@+id/linearLayoutB"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:background="#ddf"
                android:animateLayoutChanges="true"
                android:orientation="horizontal"
                android:padding="5dp">

                <Button
                    android:id="@+id/btnB1"
                    android:layout_width="50dp"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:text="B1"/>

                <Button
                    android:id="@+id/btnB2"
                    android:layout_width="50dp"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:text="B2"/>

            </LinearLayout>
    </LinearLayout>

        <Button
            android:id="@+id/btnR5"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="R5" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayoutP"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="#fdf"
        android:animateLayoutChanges="true"
        android:orientation="vertical"
        android:padding="5dp">

        <Button
            android:id="@+id/btnP1"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="P1"/>

        <Button
            android:id="@+id/btnP2"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="P2"/>
    </LinearLayout>

    <Button
        android:id="@+id/btnGR4"
        android:layout_width="50dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="GR4"/>
</LinearLayout>

MainActivity.java

import android.animation.LayoutTransition;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

private LinearLayout linearLayoutGR;
private LinearLayout linearLayoutR;
private LinearLayout linearLayoutG;
private LinearLayout linearLayoutB;
private LinearLayout linearLayoutP;

private Button btnGR1, btnR3;

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

    linearLayoutGR = findViewById(R.id.linearLayoutGR);
    linearLayoutR = findViewById(R.id.linearLayoutR);
    linearLayoutG = findViewById(R.id.linearLayoutG);
    linearLayoutB = findViewById(R.id.linearLayoutB);
    linearLayoutP = findViewById(R.id.linearLayoutP);

    linearLayoutGR.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
    linearLayoutR.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
    linearLayoutG.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
    linearLayoutB.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
    linearLayoutP.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);

    btnGR1 = findViewById(R.id.btnGR1);
    btnR3 = findViewById(R.id.btnR3);

    final Button aBtn = new Button(this);

    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(131, LinearLayout.LayoutParams.WRAP_CONTENT);
    params.gravity = Gravity.CENTER;

    aBtn.setLayoutParams(params);
    aBtn.setGravity(Gravity.CENTER);
    aBtn.setText("A");


    final Button bBtn = new Button(this);

    bBtn.setLayoutParams(params);
    bBtn.setGravity(Gravity.CENTER);
    bBtn.setText("B");


    btnGR1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (linearLayoutB.getChildCount() < 3) {
                linearLayoutB.addView(aBtn);
            } else {
                linearLayoutB.removeView(aBtn);
            }
        }
    });

    btnR3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (linearLayoutGR.getChildCount() < 5) {
                linearLayoutGR.addView(bBtn);
            } else {
                linearLayoutGR.removeView(bBtn);
            }
        }
    });
}
}
导入android.animation.LayoutTransition;
导入android.support.v7.app.AppActivity;
导入android.os.Bundle;
导入android.view.Gravity;
导入android.view.view;
导入android.widget.Button;
导入android.widget.LinearLayout;
公共类MainActivity扩展了AppCompatActivity{
私人线路布局线性布局GR;
私人线性布局器线性布局器;
私人线路布局线性布局;
私人线路布局线路布局B;
私人线路布局线性布局输出;
专用按钮btnGR1、btnR3;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linearLayoutGR=findviewbyd(R.id.linearLayoutGR);
linearLayoutR=findViewById(R.id.linearLayoutR);
linearLayoutG=findViewById(R.id.linearLayoutG);
linearLayoutB=findviewbyd(R.id.linearLayoutB);
linearLayoutP=findViewById(R.id.linearLayoutP);
linearLayoutGR.getLayoutTransition().enableTransitionType(LayoutTransition.Changeing);
linearLayoutR.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
linearLayoutG.getLayoutTransition().enableTransitionType(LayoutTransition.Changeing);
linearLayoutB.getLayoutTransition().enableTransitionType(LayoutTransition.Changeing);
linearLayoutP.getLayoutTransition().enableTransitionType(LayoutTransition.Changeing);
btnGR1=findViewById(R.id.btnGR1);
btnR3=findViewById(R.id.btnR3);
最终按钮aBtn=新按钮(本);
LinearLayout.LayoutParams params=新的LinearLayout.LayoutParams(131,LinearLayout.LayoutParams.WRAP_内容);
参数重力=重心;
aBtn.setLayoutParams(参数);
aBtn.setGravity(重心);
aBtn.setText(“A”);
最终按钮bBtn=新按钮(本);
bBtn.setLayoutParams(参数);
设置重力(重心);
bBtn.setText(“B”);
btnGR1.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
if(linearLayoutB.getChildCount()<3){
线性布局。添加视图(aBtn);
}否则{
线性布局B.移除视图(aBtn);
}
}
});
btnR3.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
if(linearLayoutGR.getChildCount()<5){
线性布局图添加视图(bBtn);
}否则{
线性布局图移除视图(bBtn);
}
}
});
}
}

如果有一些解决方法,我仍然希望保持与现在相同的效果/行为,而不存在任何错误,其中任何子视图(按钮和其他线性布局)添加或删除到任何其他嵌套布局中的子视图会导致所有布局使用平滑动画相应调整大小,同时保持所有子视图居中并紧凑在一起

删除子视图的问题似乎是它的动画延迟-在布局中查看设置MChangingIssuearingDelay为默认持续时间为300ms

通过使用代码将LayoutTransition对象的延迟设置为0

layoutTransition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
线性布局似乎又恢复了正常的动画效果

每个LinearLayout都必须有自己唯一的LayoutTransition对象-您不能给它们相同的LayoutTransition对象,因此我在下面为此创建了一个方法

private LayoutTransition createLayoutTransition(){
    LayoutTransition layoutTransition = new LayoutTransition();
    layoutTransition.enableTransitionType(LayoutTransition.CHANGING);

    // the delay fix
    layoutTransition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
    return layoutTransition;
}
然后将每个LinearLayoutTransition设置为上述方法

linearLayoutGR.setLayoutTransition(createLayoutTransition());
linearLayoutR.setLayoutTransition(createLayoutTransition());
linearLayoutG.setLayoutTransition(createLayoutTransition());
linearLayoutB.setLayoutTransition(createLayoutTransition());
linearLayoutP.setLayoutTransition(createLayoutTransition());
将下面的旧代码替换为上面的代码

linearLayoutGR.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
linearLayoutR.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
linearLayoutG.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
linearLayoutB.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
linearLayoutP.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
现在,它似乎适用于所有支持LayoutTransition的API