我一直在到处寻找我的问题的适当解决方案,但我似乎还找不到。我有一个ActionBar (ActionBarSherlock),它的菜单是从XML文件放大的,该菜单包含一项,并且这一项显示为ActionItem。
菜单:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menu_refresh"
android:icon="@drawable/ic_menu_refresh"
android:showAsAction="ifRoom"
android:title="Refresh"/>
</menu>
活动:
[...]
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.mymenu, menu);
return true;
}
[...]
当用户单击ActionItem时,我希望图标开始动画,更具体地说,是在适当的位置旋转。有问题的图标是刷新图标。
我意识到ActionBar支持使用自定义视图(Adding an Action View),但是这个自定义视图被扩展到覆盖整个ActionBar区域,并且实际上阻止了除应用程序图标之外的所有东西,在我的例子中,这不是我想要的。
因此,我的下一个尝试是尝试使用AnimationDrawable并逐帧定义我的动画,将可绘制设置为菜单项的图标,然后在onOptionsItemSelected(MenuItem item)
中获取图标并开始使用((AnimationDrawable)item.getIcon()).start()
进行动画。然而,这并不成功。有没有人知道有什么方法可以达到这个效果?
发布于 2012-03-16 13:09:54
你在正确的轨道上。以下是GitHub Gaug.es应用程序将如何实现它。
首先,他们定义了一个动画XML:
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000"
android:interpolator="@android:anim/linear_interpolator" />
现在为操作视图定义一个布局:
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_refresh"
style="@style/Widget.Sherlock.ActionButton" />
我们所需要做的就是在单击该项目时启用此视图:
public void refresh() {
/* Attach a rotating ImageView to the refresh item as an ActionView */
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ImageView iv = (ImageView) inflater.inflate(R.layout.refresh_action_view, null);
Animation rotation = AnimationUtils.loadAnimation(getActivity(), R.anim.clockwise_refresh);
rotation.setRepeatCount(Animation.INFINITE);
iv.startAnimation(rotation);
refreshItem.setActionView(iv);
//TODO trigger loading
}
加载完成后,只需停止动画并清除视图:
public void completeRefresh() {
refreshItem.getActionView().clearAnimation();
refreshItem.setActionView(null);
}
你就完事了!
以下是要做的其他事情:
completeRefresh()
中添加null
校验
下面是应用程序的拉取请求:https://github.com/github/gauges-android/pull/13/files
发布于 2013-01-16 22:45:00
我在使用ActionBarSherlock的解决方案上做了一些工作,我想出了这个:
res/layout/indeterminate_progress_action.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingRight="12dp" >
<ProgressBar
style="@style/Widget.Sherlock.ProgressBar"
android:layout_width="44dp"
android:layout_height="32dp"
android:layout_gravity="left"
android:layout_marginLeft="12dp"
android:indeterminate="true"
android:indeterminateDrawable="@drawable/rotation_refresh"
android:paddingRight="12dp" />
</FrameLayout>
res/layout-v11/indeterminate_progress_action.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center" >
<ProgressBar
style="@style/Widget.Sherlock.ProgressBar"
android:layout_width="32dp"
android:layout_gravity="left"
android:layout_marginRight="12dp"
android:layout_marginLeft="12dp"
android:layout_height="32dp"
android:indeterminateDrawable="@drawable/rotation_refresh"
android:indeterminate="true" />
</FrameLayout>
res/drawable/rotation_refresh.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:pivotX="50%"
android:pivotY="50%"
android:drawable="@drawable/ic_menu_navigation_refresh"
android:repeatCount="infinite" >
</rotate>
活动中的代码(我将其放在ActivityWithRefresh父类中)
// Helper methods
protected MenuItem refreshItem = null;
protected void setRefreshItem(MenuItem item) {
refreshItem = item;
}
protected void stopRefresh() {
if (refreshItem != null) {
refreshItem.setActionView(null);
}
}
protected void runRefresh() {
if (refreshItem != null) {
refreshItem.setActionView(R.layout.indeterminate_progress_action);
}
}
活动创建菜单项中的
private static final int MENU_REFRESH = 1;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(Menu.NONE, MENU_REFRESH, Menu.NONE, "Refresh data")
.setIcon(R.drawable.ic_menu_navigation_refresh)
.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
setRefreshItem(menu.findItem(MENU_REFRESH));
refreshData();
return super.onCreateOptionsMenu(menu);
}
private void refreshData(){
runRefresh();
// work with your data
// for animation to work properly, make AsyncTask to refresh your data
// or delegate work anyhow to another thread
// If you'll have work at UI thread, animation might not work at all
stopRefresh();
}
和图标,this is drawable-xhdpi/ic_menu_navigation_refresh.png
这可以在http://developer.android.com/design/downloads/index.html#action-bar-icon-pack中找到
发布于 2014-02-20 00:08:55
除了杰克·沃顿所说的之外,您还应该执行以下操作,以确保动画平滑停止,并且不会在加载完成后立即跳过。
首先,创建一个新的布尔值(用于整个类):
private boolean isCurrentlyLoading;
找到启动加载的方法。当活动开始加载时,将布尔值设置为true。
isCurrentlyLoading = true;
找到加载完成时启动的方法。将布尔值设置为false,而不是清除动画。
isCurrentlyLoading = false;
在动画上设置AnimationListener:
animationRotate.setAnimationListener(new AnimationListener() {
然后,每次动画执行一次,这意味着当你的图标旋转一次时,检查加载状态,如果不再加载,动画将停止。
@Override
public void onAnimationRepeat(Animation animation) {
if(!isCurrentlyLoading) {
refreshItem.getActionView().clearAnimation();
refreshItem.setActionView(null);
}
}
这样,动画只有在已经旋转到结束时才能停止,并且将在短时间内重复,并且不再加载。
这至少是我在想要实现杰克的想法时所做的。
https://stackoverflow.com/questions/9731602
复制相似问题