Android ActionBarSherlock动画移动位置

Android ActionBarSherlock动画移动位置,android,android-animation,actionbarsherlock,Android,Android Animation,Actionbarsherlock,我的Actionbar中有一个菜单选项Sherlock Actionbar可以启动异步任务。我正在尝试在后台任务运行时设置图标的动画。我有它的工作,除了当我点击图标,图标本身将“跳转”到右边的几个像素,它是非常明显的。不确定是什么导致了这种情况 这就是我到目前为止所做的: private MenuItem refreshItem; private void DoRefresh() { final LayoutInflater inflater = (LayoutInflater

我的Actionbar中有一个菜单选项Sherlock Actionbar可以启动异步任务。我正在尝试在后台任务运行时设置图标的动画。我有它的工作,除了当我点击图标,图标本身将“跳转”到右边的几个像素,它是非常明显的。不确定是什么导致了这种情况

这就是我到目前为止所做的:

private MenuItem refreshItem;   

private void DoRefresh() 
{
    final LayoutInflater inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    final ImageView ivRefresh = (ImageView)inflater.inflate(R.layout.refresh_view, null);

    final Animation rotation = AnimationUtils.loadAnimation(activity, R.anim.refresh);
    ImageView ivRefresh.startAnimation(rotation);

    refreshItem.setActionView(ivRefresh);

    //AsyncTask is kicked off here
}

@Override
public boolean onOptionsItemSelected(final MenuItem item) 
{
    if (item.getItemId() == R.id.refresh) {
        refreshItem = item;
        this.DoRefresh();
        return true;
    } else {
        return super.onOptionsItemSelected(item);
    }
}
refresh_view.xml

<?xml version="1.0" encoding="utf-8"?>

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:src="@drawable/refresh"
/>

refresh.xml


更新:


一直在胡闹,运气不好。它与动画无关,因为如果禁用动画,图标仍然会跳到右侧。如果我注释掉
setActionView
,图标不会跳转,因此它与此有关。没有任何线索,让我发疯。

我不知道这是否会有任何影响,但如果您使用
枢轴值,您可能会解决这个问题。可能仅围绕一个轴旋转?

如果菜单选项是一个操作项,则应将样式Widget.Sherlock.ActionButton应用于ImageView以保持一致性。阅读我写的这篇关于如何正确设置动作项目动画的文章

Alex Fu,你的文章很有帮助,但是还有一些改进可以做

每次在onAnimationEnd中重新启动动画都是低效的。相反,请在启动动画之前将其repeatcount设置为无限,然后在动作完成时将repeatcount设置为0。动画将完成当前循环,然后调用onAnimationEnd,您可以在其中调用setActionView(null)

我还遇到了ActionBarSherlock和本机ICS ActionBar的一个问题(至少在emulator中,没有在真实设备上测试,因为我没有),即调用setActionView(null)后,动画的最后几帧与静态按钮重叠。我的解决方案是将正在LinearLayout中设置动画的ImageView包装起来,然后在LinearLayout上调用setVisibility(View.GONE)。如果设置视图的动画,使用setVisibility隐藏视图将不起作用,但隐藏其父视图会起作用

以下是所有相关代码:

layout/actionbar_progress.xml(请注意,我添加了ID,但只有ImageView需要ID):

这只是为了避免每次单击刷新按钮时都执行findItem

在OnOptions ItemSelected中:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {

    ...

        case R.id.menu_refresh:
            refresh();
            break;

    ...

    }
}
刷新方法只是一个虚拟的5秒延迟post;它调用refreshAnim以启动动画,然后在完成时调用refreshAnimEnd以停止动画:

private void refresh() {
    refreshAnim();
    getWindow().getDecorView().postDelayed(
        new Runnable() {
            @Override
            public void run() {
                refreshAnimEnd();
            }
        }, 5000);
}
以下是最重要的部分,并附有评论:

private void refreshAnim() {
    LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    //The inflated layout and loaded animation are put into members to avoid reloading them every time.
    //For convenience, the ImageView is also extracted into a member
    if (mRefreshIndeterminateProgressView == null || mRefreshRotateClockwise == null) {
        mRefreshIndeterminateProgressView = inflater.inflate(R.layout.actionbar_progress, null);
        mRefreshRotateClockwise = AnimationUtils.loadAnimation(this, R.anim.refresh_rotate);
        mRefreshImage = mRefreshIndeterminateProgressView.findViewById(R.id.actionbar_progress_image);
    }
    //reset some stuff - make the animation infinite again,
    //and make the containing view visible
    mRefreshRotateClockwise.setRepeatCount(Animation.INFINITE);
    mRefreshIndeterminateProgressView.setVisibility(View.VISIBLE);
    mRefreshRotateClockwise.setAnimationListener(new AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {}

        @Override
        public void onAnimationRepeat(Animation animation) {}

        @Override
        public void onAnimationEnd(Animation animation) {
            //This is important to avoid the overlapping problem.
            //First hide the animated icon
            //setActionView(null) does NOT hide it!
            //as long as the animation is running, it will be visible
            //hiding an animated view also doesn't work
            //as long as the animation is running
            //but hiding the parent does.
            mRefreshIndeterminateProgressView.setVisibility(View.GONE);
            //make the static button appear again
            mRefreshItem.setActionView(null);
        }
    });
    mRefreshItem.setActionView(mRefreshIndeterminateProgressView);
    //everything is set up, start animating.
    mRefreshImage.startAnimation(mRefreshRotateClockwise);
}

private void refreshAnimEnd() {
    //sanity
    if ( mRefreshImage == null || mRefreshItem == null ) {
        return;
    }
    Animation anim = mRefreshImage.getAnimation();

    //more sanity
    if (anim != null) {
        //let the animation finish nicely
        anim.setRepeatCount(0);
    } else {
        //onAnimationEnd won't run in this case, so restore the static button
        mRefreshItem.setActionView(null);
    }
}

如果您使用的是普通操作栏,只需将其添加到您的img_layout.xml

style="?android:attr/actionButtonStyle"
style="@style/Widget.Sherlock.ActionButton"
或者这是《神探夏洛克行动吧》:

style="?android:attr/actionButtonStyle"
style="@style/Widget.Sherlock.ActionButton"

你应该看看[这里][1]。[1] :我已经创建了图标,并解决了换档问题。如果有人感兴趣:
每次在onAnimationEnd中重新启动动画都是低效的。相反,请在启动动画之前将其repeatcount设置为无限,然后在动作完成时将repeatcount设置为0。动画将完成当前循环,然后调用onAnimationEnd,您可以在其中调用setActionView(null)。
——这是一个好主意,我在写这篇文章时没有想到。谢谢你的评论。
style="?android:attr/actionButtonStyle"
style="@style/Widget.Sherlock.ActionButton"