有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Android第一个动画事件的行为有所不同

在我的应用程序中创建一个简单的动画时,我遇到了一些问题,为此我苦苦挣扎了几个小时

我有一个线性布局,里面有隐藏在图像视图后面的元素,应该在单击事件中显示(通过在布局宽度上设置动画)。如果我从LinearLayout内部删除元素,所有内容都会运行良好,但由于布局的子级正在推送其宽度(这意味着即使布局宽度设置为0,内部元素仍会将其推送至宽度+/-100dp),我在隐藏布局时遇到问题

但是,当执行动画时,情况并非如此-当我将布局设置为宽度0时,它会正确地裁剪子对象。但动画一完成,布局就由孩子们推动。我有一个想法,让布局裁剪默认为其子项,但我尝试了多种解决方案,但没有一种奏效。然后我想也许我会在动画完成后隐藏元素(可见性消失)。它“有点”解决了这个问题,但我仍然有一个问题,第一次出现的“显示”动画

我正在做的是-开始时,我将布局宽度设置为0,并将其与其子项一起隐藏(将其可见性设置为“消失”)。然后在“显示”动画中,我使布局及其子级在onAnimationStart方法中可见,然后动画将布局宽度从0增加到156dp。“隐藏”动画被还原-我将版面宽度减小为0,而onAnimationEnd则隐藏版面及其内容。问题是,由于某种原因,在调用第一次显示动画时,我正在使布局和视图在onAnimationStart中可见,这段代码与动画实际开始的时刻之间存在差距,这使得视图在动画开始前的一瞬间可见

这就是它的样子: hiddenshown。下面是它的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) 个答案

  1. # 1 楼答案

    过了一会儿,我终于找到了一个“解决方案”,它不需要对视图可见性进行任何操作。事实证明,如果布局宽度为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);
    }