Android-第一个动画出现的行为有所不同

问题描述 投票:0回答:1

我在自己的应用中创建简单的动画时遇到了一些问题,需要花费数小时的时间。

我有一个LinearLayout,其中的元素隐藏在Image View的后面,应该在click事件中显示(通过对布局宽度进行动画处理)。如果我从LinearLayout内部删除元素,一切都会很好,但是由于布局的子级正在推动其宽度(这意味着,即使布局的width设置为0,其内部的元素仍会将其推入宽度+/- 100dp)我在隐藏布局时遇到问题。

但是执行动画不是这种情况-当我将布局动画设置为宽度0时,它将正确裁剪子代。但是,一旦动画完成,布局就会被孩子们推动。我有一个想法,使布局默认情况下裁剪其子级,但是我尝试了多种解决方案,但没有一个起作用。然后我想也许动画结束后我只会隐藏元素(可见性消失了)。它“有点”解决了这个问题-但我还是第一次出现“显示”动画时遇到了问题。

[我正在做的-在一开始,我将布局宽度设置为0,并将其及其子项隐藏(将其可见性设置为隐藏)。然后在“显示”动画上,我通过onAnimationStart方法使布局及其子级可见,然后动画将布局宽度从0增加到156dp。 “隐藏”动画将还原-我将布局宽度减小为0,而onAnimationEnd我隐藏了布局及其内容。问题是由于某种原因,第一次调用显示动画,并且我在onAnimationStart中使布局和视图可见,因此这段代码与动画实际开始的时间之间存在间隙,从而使视图在一秒钟之前可见动画开始。

外观如下:hiddenshown。这是它的xml代码:

<LinearLayout
    android:id="@+id/linSettingsPopup"
    android:layout_width="156dp"
    android:layout_height="56dp"
    app:layout_constraintTop_toTopOf="@id/imgProfilePicture"
    app:layout_constraintBottom_toBottomOf="@id/imgProfilePicture"
    app:layout_constraintRight_toRightOf="@id/imgProfilePicture"
    android:layout_marginEnd="24dp"
    android:background="@drawable/settings_popup_container"
    android:orientation="horizontal"
    android:gravity="center|start"
    android:visibility="visible">

    <ImageButton
        android:id="@+id/btnLogout"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="22dp"
        android:background="@drawable/logout"
        android:visibility="visible">

    </ImageButton>

    <ImageButton
        android:id="@+id/btnSettings"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:background="@drawable/settings"
        android: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方法内的代码设法解决了这个问题。但是,感觉起来比解决问题更像是避免问题,因此我希望有人可以指出我做错了什么,并对如何解决这个问题有一些好主意。

java android android-layout android-animation
1个回答
0
投票

一段时间后,我终于找到了不需要对视图可见性进行任何操作的“解决方案”。事实证明,如果布局宽度为0dp,则内部视图将继续推动它,这将使布局达到适合其子级所需的宽度。但是,如果我将布局宽度设置为1dp,则实际上会切掉其中的视图。因此,我没有在皮革上设置从156dp到0dp的布局宽度动画,而是对其从156dp到1dp进行了动画处理,并且工作正常,没有任何问题。这是它的工作代码:

private static final int SETTINGS_POPUP_ANIM_DURATION = 350;
private static final int SETTINGS_POPUP_HIDDEN_WIDTH = 1;

private void initializeSettingsPopup()
{
    settingsPopupWidth = linSettingsPopup.getLayoutParams().width;
    linSettingsPopup.getLayoutParams().width = SETTINGS_POPUP_HIDDEN_WIDTH;
    linSettingsPopup.requestLayout();
}

private void showSettingsPopup()
{
    settingsPopupShown = true;
    ResizeWidthAnimation resizeAnimation = new ResizeWidthAnimation(linSettingsPopup, settingsPopupWidth);
    resizeAnimation.setDuration(SETTINGS_POPUP_ANIM_DURATION);
    linSettingsPopup.startAnimation(resizeAnimation);
}

private void hideSettingsPopup()
{
    settingsPopupShown = false;
    ResizeWidthAnimation resizeAnimation = new ResizeWidthAnimation(linSettingsPopup, SETTINGS_POPUP_HIDDEN_WIDTH);
    resizeAnimation.setDuration(SETTINGS_POPUP_ANIM_DURATION);
    linSettingsPopup.startAnimation(resizeAnimation);
}
© www.soinside.com 2019 - 2024. All rights reserved.