java Android第一个动画事件的行为有所不同
在我的应用程序中创建一个简单的动画时,我遇到了一些问题,为此我苦苦挣扎了几个小时
我有一个线性布局,里面有隐藏在图像视图后面的元素,应该在单击事件中显示(通过在布局宽度上设置动画)。如果我从LinearLayout内部删除元素,所有内容都会运行良好,但由于布局的子级正在推送其宽度(这意味着即使布局宽度设置为0,内部元素仍会将其推送至宽度+/-100dp),我在隐藏布局时遇到问题
但是,当执行动画时,情况并非如此-当我将布局设置为宽度0时,它会正确地裁剪子对象。但动画一完成,布局就由孩子们推动。我有一个想法,让布局裁剪默认为其子项,但我尝试了多种解决方案,但没有一种奏效。然后我想也许我会在动画完成后隐藏元素(可见性消失)。它“有点”解决了这个问题,但我仍然有一个问题,第一次出现的“显示”动画
我正在做的是-开始时,我将布局宽度设置为0,并将其与其子项一起隐藏(将其可见性设置为“消失”)。然后在“显示”动画中,我使布局及其子级在onAnimationStart方法中可见,然后动画将布局宽度从0增加到156dp。“隐藏”动画被还原-我将版面宽度减小为0,而onAnimationEnd则隐藏版面及其内容。问题是,由于某种原因,在调用第一次显示动画时,我正在使布局和视图在onAnimationStart中可见,这段代码与动画实际开始的时刻之间存在差距,这使得视图在动画开始前的一瞬间可见
这就是它的样子: hidden,shown。下面是它的xml代码:
<LinearLayout
安卓:id="@+id/linSettingsPopup"
安卓:layout_width="156dp"
安卓:layout_height="56dp"
app:layout_constraintTop_toTopOf="@id/imgProfilePicture"
app:layout_constraintBottom_toBottomOf="@id/imgProfilePicture"
app:layout_constraintRight_toRightOf="@id/imgProfilePicture"
安卓:layout_marginEnd="24dp"
安卓:background="@drawable/settings_popup_container"
安卓:orientation="horizontal"
安卓:gravity="center|start"
安卓:visibility="visible">
<ImageButton
安卓:id="@+id/btnLogout"
安卓:layout_width="32dp"
安卓:layout_height="32dp"
安卓:layout_marginStart="24dp"
安卓:layout_marginEnd="22dp"
安卓:background="@drawable/logout"
安卓:visibility="visible">
</ImageButton>
<ImageButton
安卓:id="@+id/btnSettings"
安卓:layout_width="32dp"
安卓:layout_height="32dp"
安卓:background="@drawable/settings"
安卓:visibility="visible">
</ImageButton>
</LinearLayout>
为了更好地理解正在发生的事情,下面是所有事情的代码。 在onCreate方法期间设置视图(当然,此时视图被指定给变量):
private void initializeSettingsPopup()
{
settingsPopupWidth = linSettingsPopup.getLayoutParams().width;
linSettingsPopup.getLayoutParams().width = 0;
linSettingsPopup.requestLayout();
btnLogout.setVisibility(View.GONE);
btnSettings.setVisibility(View.GONE);
linSettingsPopup.setVisibility(View.GONE);
}
动画:
public class ResizeWidthAnimation extends Animation {
private int mWidth;
private int mStartWidth;
private View mView;
public ResizeWidthAnimation(View view, int width) {
mView = view;
mWidth = width;
mStartWidth = view.getWidth();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
int newWidth = mStartWidth + (int) ((mWidth - mStartWidth) * interpolatedTime);
mView.getLayoutParams().width = newWidth;
mView.requestLayout();
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
@Override
public boolean willChangeBounds() {
return true;
}
}
调用动画:
private void showSettingsPopup()
{
linSettingsPopup.setVisibility(View.INVISIBLE);
settingsPopupShown = true;
ResizeWidthAnimation resizeAnimation = new ResizeWidthAnimation(linSettingsPopup, settingsPopupWidth);
resizeAnimation.setDuration(350);
resizeAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
linSettingsPopup.setVisibility(View.VISIBLE);
btnLogout.setVisibility(View.VISIBLE);
btnSettings.setVisibility(View.VISIBLE);
}
});
linSettingsPopup.startAnimation(resizeAnimation);
}
private void hideSettingsPopup()
{
settingsPopupShown = false;
ResizeWidthAnimation resizeAnimation = new ResizeWidthAnimation(linSettingsPopup, 0);
resizeAnimation.setDuration(350);
resizeAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
linSettingsPopup.setVisibility(View.GONE);
btnLogout.setVisibility(View.GONE);
btnSettings.setVisibility(View.GONE);
}
});
linSettingsPopup.startAnimation(resizeAnimation);
}
我还要补充一点,我通过延迟“显示”动画的onAnimationStart方法中的代码来解决这个问题。然而,这感觉更像是避免问题而不是解决问题,所以我希望有人能指出我做错了什么,并对我如何解决这个问题有一些好的想法
# 1 楼答案
过了一会儿,我终于找到了一个“解决方案”,它不需要对视图可见性进行任何操作。事实证明,如果布局宽度为0dp,内部视图将继续推动它,从而使布局尽可能宽以适合其子级。但如果我将布局宽度设置为1dp,它实际上会剪切其中的视图。因此,我没有在隐藏时将版面宽度从156dp设置为0dp,而是将其从156dp设置为1dp,效果很好,没有任何问题。以下是它的工作代码: