我有一个项目列表的活动,当您单击一个项目时,我希望该项目从屏幕底部滑动并变得可见。我为幻灯片和滑行弹片定义了一个动画集,它们可以工作。我已经在活动中设置了AnimationListener,并在Animation OnClick的一个项目中开始了幻灯片。我的问题是,我第一次运行应用程序时,当我单击一个项目时,执行了onclick回调,但是动画不会发生。我第二次单击,动画中的幻灯片发生,但没有幻灯片。第三次也是随后的时间,它可以按预期工作。这是我的动画集。

vm_slide_in.xml

    <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" 
           android:fillAfter="true">
    <translate
        android:fromYDelta="800"
        android:toYDelta="0"
        android:duration="600" />
</set>

vm_slide_out.xml

    <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" 
           android:fillAfter="true">
    <translate
        android:fromYDelta="0"
        android:toYDelta="800"
        android:duration="600" />
</set>

这是我的活动布局

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/AppBG">
    <RelativeLayout 
        style="@style/LogoBar" 
        android:id="@+id/logo_bar"      
        android:layout_alignParentTop="true">
        <include layout="@layout/logobar"></include>
    </RelativeLayout>
    <RelativeLayout 
        style="@style/TitleBar" 
        android:id="@+id/title_bar"     
        android:layout_below="@+id/logo_bar">
        <include layout="@layout/titlebar"></include>"
        <Button style="@style/TitleBarButton"
            android:id="@+id/vm_speaker_btn"
            android:text="@string/vm_speaker_btn_label" 
            android:layout_alignParentLeft="true"
            android:layout_margin="4dp">
        </Button>
        <Button style="@style/TitleBarButton"
            android:id="@+id/vm_edit_btn"
            android:text="@string/vm_edit_btn_label" 
            android:layout_alignParentRight="true"
            android:layout_margin="4dp">
        </Button>
    </RelativeLayout>
    <ListView
        android:id="@+id/@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/title_bar"/>
    <RelativeLayout
        android:id="@+id/vm_control_panel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/footer"
        android:visibility="gone">
        <include layout="@layout/vm_control"/>
    </RelativeLayout>
    <RelativeLayout
        android:id="@+id/footer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">
        <include layout="@layout/taskbar"/>
    </RelativeLayout>
</RelativeLayout>

这是包含控件的布局

    <?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <RelativeLayout 
        android:id="@+id/vm_control"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/dark_grey">
        <TextView
            android:id="@+id/vm_ctl_branding"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="5dp"
            android:text="@string/branding"
            android:textColor="@color/white">
        </TextView>
        <TextView style="@style/TimeMark"
            android:id="@+id/vm_timestamp"
            android:layout_toLeftOf="@+id/vm_progress"
            android:layout_below="@+id/vm_ctl_branding"
            android:layout_marginRight="3dp"
            android:text="0:00">
        </TextView>
        <SeekBar
            android:id="@+id/vm_progress"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_below="@+id/vm_ctl_branding"
            android:layout_centerHorizontal="true">
        </SeekBar>
        <TextView style="@style/TimeMark"
            android:id="@+id/vm_timeleft"
            android:layout_toRightOf="@+id/vm_progress"
            android:layout_below="@+id/vm_ctl_branding"
            android:layout_marginLeft="3dp"
            android:text="-0:00">
        </TextView>
        <LinearLayout
            android:id="@+id/vm_action_button_layout"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/vm_timestamp"
            android:layout_alignRight="@+id/vm_timeleft"
            android:orientation="horizontal"
            android:layout_below="@+id/vm_progress">
            <TextView style="@style/Vm_Action_Button"
                android:background="@drawable/vm_action_btn_call"
                android:id="@+id/vm_callback_btn"
                android:layout_marginRight="5dp"
                android:text="@string/vm_action_btn_callback">
            </TextView>
            <TextView style="@style/Vm_Action_Button"
                android:background="@drawable/vm_action_btn_delete"
                android:id="@+id/vm_delete_btn"
                android:layout_marginLeft="5dp"
                android:text="@string/vm_action_btn_delete">
            </TextView>
        </LinearLayout>
    </RelativeLayout>
</merge>

从我的征服方法...

// Handle list item selections
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        final Voicemail vmItem = (Voicemail) vmla.getItem(position);
        Toast.makeText(ctx, "Name: " + vmItem.getCallerName() + " Position: " + position, Toast.LENGTH_SHORT)
                .show();
        vVm_controls.startAnimation(mSlideIn);
    }
});

和我的动画回调...

@Override
public void onAnimationStart(Animation animation) {
    vm_controls_in = !vm_controls_in;
    if (vm_controls_in) {
        vVm_controls.setVisibility(View.GONE);
    } else {
        vVm_controls.setVisibility(View.VISIBLE);
        // vVm_controls.bringToFront();
    }
}

@Override
public void onAnimationEnd(Animation animation) {
    if (!vm_controls_in) {
        try {
            Thread.sleep(1000);
            vVm_controls.startAnimation(mSlideOut);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

@Override
public void onAnimationRepeat(Animation animation) {
    // TODO Auto-generated method stub

}
有帮助吗?

解决方案

正如您发现的那样,问题是可见性。当最初将视图设置为XML文件中的视图时,Android不会渲染布局,直到可见性或隐形性更改为可见性或不可见为止。如果您尝试在尚未呈现的视图上进行动画化,则动画将在没有布局的情况下进行。动画完成后,它将渲染它,突然间,视图将在没有动画的情况下出现。它之后的时间是因为即使设置为消失,该视图也具有布局。

关键是将可见性设置为不可见的,而不是在XML文件中消失,以便将其渲染但隐藏。当动画发生时,该视图首次出现并将按预期移动。

其他提示

当然,发布此问题不到20分钟,我发现了我的问题。由于我将布局的可见性设置为“消失”,当我尝试启动动画时,它并没有触发第一次。不确定为什么要进行第二次和后续时间,但是如果我在开始动画之前将可见性设置为“可见”,则它将解决问题。这是我更改它的代码...

// Handle list item selections
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        final Voicemail vmItem = (Voicemail) vmla.getItem(position);
        Toast.makeText(ctx, "Name: " + vmItem.getCallerName() + " Position: " + position, Toast.LENGTH_SHORT)
                .show();
        vVm_controls.setVisibility(View.VISIBLE);
        vVm_controls.startAnimation(mSlideIn);
    }
});

我不知道它是否仍然是最新的,但是是的,这是可见性的问题。因此,我将XML文件中的可见性设置为不可见,并在您的视图初始化的位置进行调用:

view.post(new Runnable() {
    @Override
    public void run() {
        view.animate().translationY(view.getHeight());
    }
};

现在打电话

view.animate().translationY(0).setListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationStart(Animator animation) {
        super.onAnimationStart(animation);
        view.setVisibility(View.VISIBLE);
    }
}

也是第一次作品。

即使在动画开始中可以看到视图,也有完全相同的问题。我遵循了Brockoli的建议,并在开始动画之前将其设置为可见,它像魅力一样工作。

前:

Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.slide_left);
animation.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) {
        view.setVisibility(View.VISIBLE);
    }

    @Override
    public void onAnimationEnd(Animation animation) { }

    @Override
    public void onAnimationRepeat(Animation animation) {       }
);
view.startAnimation(animation);

后:

Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.slide_left);
view.setVisibility(View.VISIBLE);
view.startAnimation(animation);

如果可见性是问题,您只需要在渲染之后延迟动画。

vVm_controls.setVisibility(View.INVISIBLE);
vVm_controls.post(() -> vVm_controls.startAnimation(mSlideIn));

我在Android 4.4.3中也有类似的问题。我尝试了大多数建议的解决方案,但是只有一种解决方案对我来说很好。窗口完成渲染后,您可以运行动画,最好的方法是在内部运行它 OnWindowFocuschanged. 。不要使用可运行的延迟,因为它会影响您在高速手机中的应用程序性能。

@Override
public void onWindowFocusChanged (boolean hasFocus) {
   super.onWindowFocusChanged(hasFocus);
   if (hasFocus)
      yourView.startAnimation(anim);
}

可以在这篇文章中找到更多信息:https://damianflannery.wordpress.com/2011/06/08/start-animation-in-on-oncreate-or-onresume-onresume-on-android/

我遇到了完全相同的问题,但是使用 ViewPropertyAnimator. 。例如,您声明 GridViewmGridView. 。您现在要做的就是致电 mGridView.animate() 随着您所需的更改。

我的动画 GridView 被触发了,但由于未知情况,没有可见的实际动画。我也改变了一切 View.GONEView.VISIBLE, ,但没有改变任何事情。就我而言,我想知道,我只需要删除 android:requiresFadingEdge="vertical" 在我的XML中 GridView. 。可能不可能将褪色的边缘与 ViewPropertyAnimator.

我知道这个问题是旧的,但我的回答可能会对其他人有所帮助。当我们需要动画视图时,但是默认情况下它的可见性已经消失,请为我的情况设置XML中的所有属性隐藏代码,我使用了translationy和java文件中的alpha。我做了简单的事情来第一次解决问题。然后在代码中使用的XML中添加所有属性。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top