Ale*_* Fu 91 android android-animation actionbarsherlock
我一直在寻找适合我问题的解决方案,但我似乎找不到一个.我有一个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>
Run Code Online (Sandbox Code Playgroud)
活动:
[...]
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.mymenu, menu);
return true;
}
[...]
Run Code Online (Sandbox Code Playgroud)
ActionItem显示时带有图标而没有文本,但是当用户点击ActionItem时,我希望图标开始动画,更具体地说,是在适当的位置旋转.有问题的图标是刷新图标.
我意识到ActionBar支持使用自定义视图(添加动作视图)但是这个自定义视图被扩展为覆盖ActionBar的整个区域并且实际上阻止了除应用程序图标之外的所有内容,在我的情况下这不是我想要的.
所以我的下一次尝试是尝试使用AnimationDrawable并逐帧定义我的动画,将drawable设置为菜单项的图标,然后在onOptionsItemSelected(MenuItem item)获取图标并开始使用动画((AnimationDrawable)item.getIcon()).start().但这并不成功.有谁知道有任何方法来实现这种效果?
Jak*_*ton 173
你走在正确的轨道上.以下是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" />
Run Code Online (Sandbox Code Playgroud)
现在定义操作视图的布局:
<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" />
Run Code Online (Sandbox Code Playgroud)
我们需要做的就是在点击项目时启用此视图:
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
}
Run Code Online (Sandbox Code Playgroud)
加载完成后,只需停止动画并清除视图:
public void completeRefresh() {
refreshItem.getActionView().clearAnimation();
refreshItem.setActionView(null);
}
Run Code Online (Sandbox Code Playgroud)
而且你已经完成了!
还有一些事要做:
null签到completeRefresh()这是应用程序上的pull请求:https://github.com/github/gauges-android/pull/13/files
Mar*_*era 16
我使用ActionBarSherlock解决了一些问题,我想出了这个:
RES /布局/ 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>
Run Code Online (Sandbox Code Playgroud)
RES /布局-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>
Run Code Online (Sandbox Code Playgroud)
RES /抽拉/ 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>
Run Code Online (Sandbox Code Playgroud)
活动中的代码(我在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);
}
}
Run Code Online (Sandbox Code Playgroud)
在活动中创建菜单项
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();
}
Run Code Online (Sandbox Code Playgroud)
和图标,这是 drawable-xhdpi/ic_menu_navigation_refresh.png

这可以在http://developer.android.com/design/downloads/index.html#action-bar-icon-pack中找到
除了杰克沃顿所说的,你应该做以下工作,以确保动画平稳停止,并在加载完成后不立即跳转.
首先,创建一个新的布尔值(对于整个类):
private boolean isCurrentlyLoading;
Run Code Online (Sandbox Code Playgroud)
找到开始加载的方法.活动开始加载时,将布尔值设置为true.
isCurrentlyLoading = true;
Run Code Online (Sandbox Code Playgroud)
找到加载完成时启动的方法.而不是清除动画,将布尔值设置为false.
isCurrentlyLoading = false;
Run Code Online (Sandbox Code Playgroud)
在动画上设置AnimationListener:
animationRotate.setAnimationListener(new AnimationListener() {
Run Code Online (Sandbox Code Playgroud)
然后,每次动画执行一次,这意味着当您的图标旋转一周时,检查加载状态,如果不再加载,动画将停止.
@Override
public void onAnimationRepeat(Animation animation) {
if(!isCurrentlyLoading) {
refreshItem.getActionView().clearAnimation();
refreshItem.setActionView(null);
}
}
Run Code Online (Sandbox Code Playgroud)
这样,只有当动画已经旋转到结束并且将很快重复并且它不再加载时,才能停止动画.
这至少是我想要实现Jake的想法时所做的.
| 归档时间: |
|
| 查看次数: |
62324 次 |
| 最近记录: |