我有两个LinearLayout视图,其中包含许多编辑文本和复选框,用于输入用户信息(名称,电子邮件地址等)。当其中一个字段的验证失败时,会显示一条消失的文本视图,显示验证错误。
我在ViewSwitcher中包含了两个布局,并使用ObjectAnimator类在两个视图之间进行动画处理。 (由于代码需要支持旧版本的Android,我实际上使用的是nineoldandroids向后兼容库。)
大部分工作都是在我的switchToChild方法中执行的。
如果我将视图翻转两次以上,那么我就会遇到奇怪的错误。
首先,虽然显示了视图动画师的正确子视图,但似乎另一个视图具有焦点,我可以单击当前视图下方的视图。我通过在第一个动画结束时添加一个viewSwitcher.bringChildToFront解决了这个问题。
当我这样做并在第二个视图上执行验证时,我现在设置为可见的“已消失”视图不会显示(就好像线性布局永远不会被重新测量一样)。以下是XML文件的子集:
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/TitleBar"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarStyle="outsideOverlay"
android:scrollbars="vertical" >
<ViewSwitcher
android:id="@+id/switcher"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="@+id/page_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- Lots of subviews here -->
<LinearLayout
android:id="@+id/page_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
这是在视图之间翻转的主要方法:
private void switchToChild(final int child) {
final ViewSwitcher viewSwitcher = (ViewSwitcher) findViewById(R.id.switcher);
if (viewSwitcher.getDisplayedChild() != child) {
final Interpolator accelerator = new AccelerateInterpolator();
final Interpolator decelerator = new DecelerateInterpolator();
final View visibleView;
final View invisibleView;
switch (child) {
case 0:
visibleView = findViewById(R.id.page_2);
invisibleView = findViewById(R.id.page_1);
findViewById(R.id.next).setVisibility(View.VISIBLE);
findViewById(R.id.back).setVisibility(View.GONE);
break;
case 1:
default:
visibleView = findViewById(R.id.page_1);
invisibleView = findViewById(R.id.page_2);
findViewById(R.id.back).setVisibility(View.VISIBLE);
findViewById(R.id.next).setVisibility(View.GONE);
break;
}
final ObjectAnimator visToInvis = ObjectAnimator.ofFloat(visibleView, "rotationY", 0f, 90f).setDuration(250);
visToInvis.setInterpolator(accelerator);
final ObjectAnimator invisToVis = ObjectAnimator.ofFloat(invisibleView, "rotationY", -90f, 0f).setDuration(250);
invisToVis.setInterpolator(decelerator);
visToInvis.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator anim) {
viewSwitcher.showNext();
invisToVis.start();
viewSwitcher.bringChildToFront(invisibleView); // If I don't do this the old view can have focus
}
});
visToInvis.start();
}
}
有没有人有任何想法?这让我很困惑!
答案 0 :(得分:0)
看起来最好的解决方案是不使用视图切换器,而是通过在两个页面周围声明FrameLayout并将第二页的可见性设置为消失来有效地创建我自己的视频切换器。
switchToChild方法(我应该重命名以切换到页面并实际传入1或2值)只是将相应的视图设置为在动画期间可见:
private void switchToChild(final int child) {
final Interpolator accelerator = new AccelerateInterpolator();
final Interpolator decelerator = new DecelerateInterpolator();
final View visibleView;
final View invisibleView;
switch (child) {
case 0:
visibleView = findViewById(R.id.page_2);
invisibleView = findViewById(R.id.page_1);
findViewById(R.id.next).setVisibility(View.VISIBLE);
findViewById(R.id.back).setVisibility(View.GONE);
break;
case 1:
default:
visibleView = findViewById(R.id.page_1);
invisibleView = findViewById(R.id.page_2);
findViewById(R.id.back).setVisibility(View.VISIBLE);
findViewById(R.id.next).setVisibility(View.GONE);
break;
}
if (invisibleView.getVisibility() != View.VISIBLE) {
final ObjectAnimator visToInvis = ObjectAnimator.ofFloat(visibleView, "rotationY", 0f, 90f).setDuration(250);
visToInvis.setInterpolator(accelerator);
final ObjectAnimator invisToVis = ObjectAnimator.ofFloat(invisibleView, "rotationY", -90f, 0f).setDuration(250);
invisToVis.setInterpolator(decelerator);
visToInvis.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator anim) {
visibleView.setVisibility(View.GONE);
invisibleView.setVisibility(View.VISIBLE);
invisToVis.start();
}
});
visToInvis.start();
}
}