从 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 可见性第一次不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如何从 View.gone 恢复视图。在xml中使用'android:visibility =“gone”'后setVisibility(View.VISIBLE)不起作用