不同 Android 版本上的奇怪行为约束布局动画
Strange behaviour Constraint Layout Animation on differente Android versions
我制作了一个动画来表示我的 Android 应用程序中的玩家数量(2 名玩家 = 2 瓶等..)。
我对结果非常满意,但它无法在我的 Android 5.0 上的旧设备上运行。
应用最低SDK版本为21,应该没问题。
我想制作这样的动画:Correct animation on Android 10.0. But in Android 5.0 we have for some values (eg from 3 to 4 but not from 5 to 4) this behaviour: Wrong animation on Android 5.0。
我尝试了不同的布局、资源等等,但我无法让它在 Android 5.0 上 100% 正确工作。
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.transition.ChangeBounds;
import android.transition.TransitionManager;
import android.view.View;
import android.view.animation.AnticipateInterpolator;
import android.widget.Button;
import android.widget.TextView;
import android.widget.VideoView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
public class PickNbrPlayersScreen extends AppCompatActivity {
private ConstraintLayout layout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu_pick_nbr_players_2);
layout = findViewById(R.id.bottles_2);
nbrPlayers = findViewById(R.id.currentPlayerCountTextView);
}
public void decreasePlayerNbr(View view) {
nbrOfPlayers--;
if (nbrOfPlayers < 2) {
nbrOfPlayers = 8;
}
nbrPlayers.setText(String.valueOf(nbrOfPlayers));
playAnimation(nbrOfPlayers);
}
public void increasePlayerNbr(View view) {
nbrOfPlayers = Math.max(2, (nbrOfPlayers + 1) % 9);
nbrPlayers.setText(String.valueOf(nbrOfPlayers));
playAnimation(nbrOfPlayers);
}
private void playAnimation(int nbrOfPlayers) {
ConstraintSet constraintSet = new ConstraintSet();
int currentLayoutId = getCorrectLayout(nbrOfPlayers);
constraintSet.clone(this, currentLayoutId);
ChangeBounds transition = new ChangeBounds();
transition.setInterpolator(new AnticipateInterpolator(1.0f));
transition.setDuration(500);
TransitionManager.beginDelayedTransition(layout, transition);
constraintSet.applyTo(layout);
}
private int getCorrectLayout(int nbrOfPlayers) {
int layoutId;
switch (nbrOfPlayers) {
case 2:
layoutId = R.layout.menu_pick_nbr_players_2;
break;
case 3:
layoutId = R.layout.menu_pick_nbr_players_3;
break;
case 4:
layoutId = R.layout.menu_pick_nbr_players_4;
break;
case 5:
layoutId = R.layout.menu_pick_nbr_players_5;
break;
case 6:
layoutId = R.layout.menu_pick_nbr_players_6;
break;
case 7:
layoutId = R.layout.menu_pick_nbr_players_7;
break;
case 8:
layoutId = R.layout.menu_pick_nbr_players_8;
break;
default:
throw new IllegalStateException("Unexpected value: " + nbrOfPlayers);
}
return layoutId;
}
}
例如我的布局之一:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/bottles_2"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".menuScreens.PickNbrPlayersScreen">
<ImageView
android:id="@+id/bgImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/nbrplayersback" />
<!-- Beer Bottles -->
<ImageView
android:id="@+id/beerBottle_2"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintBottom_toTopOf="@+id/increasePlayerNbrButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.551"
app:layout_constraintStart_toEndOf="@+id/beerBottle_1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.545"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_1"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintBottom_toTopOf="@+id/decreasePlayerButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.231"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.145"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_8"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintStart_toStartOf="@+id/beerBottle_4"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_7"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintEnd_toEndOf="@+id/beerBottle_3"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_6"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_5"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_4"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_3"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/beerbottle" />
<!-- Buttons and TextViews -->
<Button
android:id="@+id/decreasePlayerButton"
style="@style/RoundButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="decreasePlayerNbr"
android:text="@string/minusSign"
android:textSize="@dimen/menu_decrease_textSize"
app:layout_constraintBottom_toBottomOf="@+id/currentPlayerCountTextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.25"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/currentPlayerCountTextView"
app:layout_constraintVertical_bias="0.5" />
<Button
android:id="@+id/increasePlayerNbrButton"
style="@style/RoundButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="increasePlayerNbr"
android:text="@string/plusSign"
android:textSize="@dimen/menu_decrease_textSize"
app:layout_constraintBottom_toBottomOf="@+id/currentPlayerCountTextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.75"
app:layout_constraintStart_toStartOf="@+id/bgImage"
app:layout_constraintTop_toTopOf="@+id/currentPlayerCountTextView" />
<TextView
android:id="@+id/currentPlayerCountTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="2"
android:textColor="@color/colorNormalText"
android:textSize="@dimen/menu_nbr_of_players_textSize"
app:layout_constraintBottom_toTopOf="@+id/continueButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1" />
<Button
android:id="@+id/continueButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/menu_button_margin_bottom"
android:onClick="nextMenu"
android:text="@string/Continue"
app:layout_constraintBottom_toTopOf="@+id/subtitle_textView"
app:layout_constraintEnd_toEndOf="@+id/subtitle_textView"
app:layout_constraintStart_toStartOf="@+id/subtitle_textView"
app:layout_constraintTop_toTopOf="@+id/videoView"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="@+id/subtitle_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/menu_subtext_margin_bottom"
android:text="@string/subtitle_NbrPlayers"
android:textColor="@color/colorNormalButton"
android:textSize="@dimen/menu_subtext_textSize"
app:layout_constraintBottom_toBottomOf="@+id/videoView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
有什么办法可以解决这种奇怪的行为吗?还是版本问题?
感谢您的帮助和时间,祝您有愉快的一天!
我无法观看动画,因为链接已损坏。顺便说一句,我建议使用 androidx
包中的转换 类。我的意思是使用 this
import androidx.transition.ChangeBounds;
import androidx.transition.TransitionManager;
而不是这个:
import android.transition.ChangeBounds;
import android.transition.TransitionManager;
android.transition
类 内置于平台中,它们可能包含永远无法修复的错误。
我制作了一个动画来表示我的 Android 应用程序中的玩家数量(2 名玩家 = 2 瓶等..)。 我对结果非常满意,但它无法在我的 Android 5.0 上的旧设备上运行。 应用最低SDK版本为21,应该没问题。
我想制作这样的动画:Correct animation on Android 10.0. But in Android 5.0 we have for some values (eg from 3 to 4 but not from 5 to 4) this behaviour: Wrong animation on Android 5.0。
我尝试了不同的布局、资源等等,但我无法让它在 Android 5.0 上 100% 正确工作。
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.transition.ChangeBounds;
import android.transition.TransitionManager;
import android.view.View;
import android.view.animation.AnticipateInterpolator;
import android.widget.Button;
import android.widget.TextView;
import android.widget.VideoView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
public class PickNbrPlayersScreen extends AppCompatActivity {
private ConstraintLayout layout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu_pick_nbr_players_2);
layout = findViewById(R.id.bottles_2);
nbrPlayers = findViewById(R.id.currentPlayerCountTextView);
}
public void decreasePlayerNbr(View view) {
nbrOfPlayers--;
if (nbrOfPlayers < 2) {
nbrOfPlayers = 8;
}
nbrPlayers.setText(String.valueOf(nbrOfPlayers));
playAnimation(nbrOfPlayers);
}
public void increasePlayerNbr(View view) {
nbrOfPlayers = Math.max(2, (nbrOfPlayers + 1) % 9);
nbrPlayers.setText(String.valueOf(nbrOfPlayers));
playAnimation(nbrOfPlayers);
}
private void playAnimation(int nbrOfPlayers) {
ConstraintSet constraintSet = new ConstraintSet();
int currentLayoutId = getCorrectLayout(nbrOfPlayers);
constraintSet.clone(this, currentLayoutId);
ChangeBounds transition = new ChangeBounds();
transition.setInterpolator(new AnticipateInterpolator(1.0f));
transition.setDuration(500);
TransitionManager.beginDelayedTransition(layout, transition);
constraintSet.applyTo(layout);
}
private int getCorrectLayout(int nbrOfPlayers) {
int layoutId;
switch (nbrOfPlayers) {
case 2:
layoutId = R.layout.menu_pick_nbr_players_2;
break;
case 3:
layoutId = R.layout.menu_pick_nbr_players_3;
break;
case 4:
layoutId = R.layout.menu_pick_nbr_players_4;
break;
case 5:
layoutId = R.layout.menu_pick_nbr_players_5;
break;
case 6:
layoutId = R.layout.menu_pick_nbr_players_6;
break;
case 7:
layoutId = R.layout.menu_pick_nbr_players_7;
break;
case 8:
layoutId = R.layout.menu_pick_nbr_players_8;
break;
default:
throw new IllegalStateException("Unexpected value: " + nbrOfPlayers);
}
return layoutId;
}
}
例如我的布局之一:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/bottles_2"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".menuScreens.PickNbrPlayersScreen">
<ImageView
android:id="@+id/bgImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/nbrplayersback" />
<!-- Beer Bottles -->
<ImageView
android:id="@+id/beerBottle_2"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintBottom_toTopOf="@+id/increasePlayerNbrButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.551"
app:layout_constraintStart_toEndOf="@+id/beerBottle_1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.545"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_1"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintBottom_toTopOf="@+id/decreasePlayerButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.231"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.145"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_8"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintStart_toStartOf="@+id/beerBottle_4"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_7"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintEnd_toEndOf="@+id/beerBottle_3"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_6"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_5"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_4"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/beerbottle" />
<ImageView
android:id="@+id/beerBottle_3"
android:layout_width="@dimen/beerBottle_width"
android:layout_height="@dimen/beerBottle_height"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/beerbottle" />
<!-- Buttons and TextViews -->
<Button
android:id="@+id/decreasePlayerButton"
style="@style/RoundButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="decreasePlayerNbr"
android:text="@string/minusSign"
android:textSize="@dimen/menu_decrease_textSize"
app:layout_constraintBottom_toBottomOf="@+id/currentPlayerCountTextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.25"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/currentPlayerCountTextView"
app:layout_constraintVertical_bias="0.5" />
<Button
android:id="@+id/increasePlayerNbrButton"
style="@style/RoundButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="increasePlayerNbr"
android:text="@string/plusSign"
android:textSize="@dimen/menu_decrease_textSize"
app:layout_constraintBottom_toBottomOf="@+id/currentPlayerCountTextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.75"
app:layout_constraintStart_toStartOf="@+id/bgImage"
app:layout_constraintTop_toTopOf="@+id/currentPlayerCountTextView" />
<TextView
android:id="@+id/currentPlayerCountTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="2"
android:textColor="@color/colorNormalText"
android:textSize="@dimen/menu_nbr_of_players_textSize"
app:layout_constraintBottom_toTopOf="@+id/continueButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1" />
<Button
android:id="@+id/continueButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/menu_button_margin_bottom"
android:onClick="nextMenu"
android:text="@string/Continue"
app:layout_constraintBottom_toTopOf="@+id/subtitle_textView"
app:layout_constraintEnd_toEndOf="@+id/subtitle_textView"
app:layout_constraintStart_toStartOf="@+id/subtitle_textView"
app:layout_constraintTop_toTopOf="@+id/videoView"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="@+id/subtitle_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/menu_subtext_margin_bottom"
android:text="@string/subtitle_NbrPlayers"
android:textColor="@color/colorNormalButton"
android:textSize="@dimen/menu_subtext_textSize"
app:layout_constraintBottom_toBottomOf="@+id/videoView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
有什么办法可以解决这种奇怪的行为吗?还是版本问题?
感谢您的帮助和时间,祝您有愉快的一天!
我无法观看动画,因为链接已损坏。顺便说一句,我建议使用 androidx
包中的转换 类。我的意思是使用 this
import androidx.transition.ChangeBounds;
import androidx.transition.TransitionManager;
而不是这个:
import android.transition.ChangeBounds;
import android.transition.TransitionManager;
android.transition
类 内置于平台中,它们可能包含永远无法修复的错误。