从 GONE 到 VISIBLE 的 Android 可见性第一次不起作用

Posted

技术标签:

【中文标题】从 GONE 到 VISIBLE 的 Android 可见性第一次不起作用【英文标题】:Android Visibility from GONE to VISIBLE doesn't work first time 【发布时间】:2014-12-14 17:28:35 【问题描述】:

您好,我尝试制作的动画有问题。

我使用这个库androidViewAnimations。

这是我的布局 xml 代码:

    <Button
         android:id="@+id/buttonDetails"
         style="@style/Button_Details"/>

    <LinearLayout
        android:id="@+id/linearLayoutDetails"
        android:visibility="gone"
        style="@style/LinearLayout_Details">

        <CheckBox
            android:layout_
            android:layout_
            android:text="@string/checkbox_clmn_text"
            android:checked="true"/>
        <CheckBox
            android:layout_
            android:layout_
            android:text="@string/checkbox_clme_text"
            android:checked="true"/>
        <CheckBox
            android:layout_
            android:layout_
            android:text="@string/checkbox_clmn_text"
            android:checked="true"/>
        <CheckBox
            android:layout_
            android:layout_
            android:text="@string/checkbox_clmn_text"
            android:checked="true"/>
        <CheckBox
            android:layout_
            android:layout_
            android:text="@string/checkbox_clmn_text"
            android:checked="true"/>
        <CheckBox
            android:layout_
            android:layout_
            android:text="@string/checkbox_clmn_text"
            android:checked="true"/>

    </LinearLayout>

这里是我的 java 代码:

// Declare Variables
@ViewById
LinearLayout linearLayoutDetails;

@Click
void buttonDetails() 
    // Checks Linear Layout Visibility
    if (linearLayoutDetails.getVisibility() == View.GONE) 
        // Sets linearLayoutDetails Visibility to VISIBLE
        linearLayoutDetails.setVisibility(View.VISIBLE);
        // Makes Appear Animation
        YoYo.with(Techniques.SlideInDown)
                .duration(700)
                .playOn(linearLayoutDetails);
     else 
        linearLayoutDetails.setVisibility(View.GONE);
    

现在的问题是我第一次按下按钮时动画不工作,但之后每隔一次工作。

我做了一些研究,发现问题是我将可见性设置为消失了,如果我将其设置为不可见,它从第一次开始就可以正常工作。问题是我不希望可见性不可见而是消失,因为我不希望线性布局在隐藏时占用空间。

有什么想法吗?

【问题讨论】:

我不是一个期望,但在做动画之前尝试在你的线性布局上调用 requestLayout()。你有YoYo的代码吗?能看到真实的代码就好了。 是的,我已经尝试过 requestLayout() 但它没有用 【参考方案1】:

几分钟前我刚刚使用 ViewTreeObserver 解决了问题。在下面的示例中,变量currentMode 是我想要动画进出的视图。它的默认值是“gone”,我遇到了与您完全相同的问题。

我是这样解决的:

ViewTreeObserver vto = currentMode.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() 
    @Override
    public void onGlobalLayout() 
        if(currentMode.isShown()) 
            YoYo.with(Techniques.SlideInDown).duration(250).playOn(currentMode);
        
    
);
currentMode.setVisibility(mShouldShowMode ? View.VISIBLE : View.GONE);

使用 ViewTreeObserver 我们可以观察 UI 的全局变化,然后做出反应。 View.isShown() 方法检查它是否可见。如果是这样,然后我开始动画。这对我很有用。

然后对于退出动画,您必须像这样将侦听器附加到退出动画:

YoYo.with(Techniques.SlideOutUp).duration(250).withListener(new Animator.AnimatorListener() 
    @Override
    public void onAnimationStart(Animator animation) 

    

    @Override
    public void onAnimationEnd(Animator animation) 
        currentMode.setVisibility(View.GONE);
    

    @Override
    public void onAnimationCancel(Animator animation) 

    

    @Override
    public void onAnimationRepeat(Animator animation) 

    
).playOn(currentMode);

【讨论】:

【参考方案2】:

解决方法:

boolean firstTIme = true;

(...)

@Click
void buttonDetails() 
    // Checks Linear Layout Visibility
    if (linearLayoutDetails.getVisibility() == View.GONE || firstTIme) 
        firstTIme = false;
        linearLayoutDetails.setVisibility(View.VISIBLE);
        YoYo.with(Techniques.SlideInDown)
                .duration(700)
                .playOn(linearLayoutDetails);
     else 
        linearLayoutDetails.setVisibility(View.GONE);
    

【讨论】:

很抱歉,这有什么帮助?您只需进行布尔检查,其余代码与地雷相同 你说除了第一次跑步外一切正常。我的布尔检查克服了这一点:firstTIme 将在启动时为真,因此 if 语句中的代码无论如何都会运行,之后它会返回到对可见性的简单检查 好的,我现在明白误会发生在哪里了。问题不在于代码没有启动。代码总是被执行,但是如果线性布局可见性设置为消失,则第一次发生这种情况动画不起作用(因为我认为由于可见性消失,它没有得到渲染,如果我将可见性设置为不可见动画作品从第一次开始就很好,因为线性布局正在渲染,但我不希望这样,因为线性布局占用空间)【参考方案3】:

如果您使用的是 YoYo 库,那么试试这个。

            YoYo.with(Techniques.SlideInDown)
            .duration(400)
            .withListener(new Animator.AnimatorListener() 
                @Override
                public void onAnimationStart(Animator animation) 

                

                @Override
                public void onAnimationEnd(Animator animation) 
                        //this will do the trick
                        YoYo.with(Techniques.Landing)
                            .duration(1)
                            .playOn(view);
                

                @Override
                public void onAnimationCancel(Animator animation) 

                

                @Override
                public void onAnimationRepeat(Animator animation) 

                
            )
            .playOn(view);

您也可以将其用于任何视图对象上的连续动画。

【讨论】:

【参考方案4】:

我遇到了类似的问题,即使答案被接受,我也无法正常工作。所以我这样做了

TransitionInflater inflater = TransitionInflater.from(context);
Transition transition = inflater.inflateTransition(R.transition.yoyo_transition);
transition.addListener(new Transition.TransitionListener() 
         ...  
        @Override
        public void onTransitionEnd(Transition transition) 
            do_stuff_with_yoyo();
        
        ...
    );

TransitionManager.beginDelayedTransition((ViewGroup) getRootView(), transition);
yoyo.setVisibility(View.VISIBLE);

yoyo_transition.xml

<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">

    <changeBounds android:duration="0">
        <targets>
            <target android:targetId="@+id/yoyo_id"></target>
        </targets>
    </changeBounds>

    <fade android:duration="0">
        <targets>
            <target android:targetId="@+id/yoyo_id"></target>
        </targets>
    </fade>

</transitionSet>

【讨论】:

以上是关于从 GONE 到 VISIBLE 的 Android 可见性第一次不起作用的主要内容,如果未能解决你的问题,请参考以下文章

动画可见性模式,GONE 和 VISIBLE

如何从 View.gone 恢复视图。在xml中使用'android:visibility =“gone”'后setVisibility(View.VISIBLE)不起作用

如何在 ANDROID 中为 View.GONE 到 View.VISIBLE 的视图设置动画

visible,invisible,gone区别

。翻转手机时,.GONE和.VISIBLE会重置

setvisibility(view.visible)在setvisibility(view.gone)之后不起作用