刷新菜单项动画ActionBarSherlock菜单项、动画、ActionBarSherlock

2023-09-06 14:41:55 作者:阳光下 ╮硪独自泪流满面

 公共布尔onOptionsItemSelected(菜单项项){
    开关(item.getItemId()){

    案例android.R.id.home:
        返回true;

    案例R.id.searchIcon:
        返回true;

    案例R.id.startRefresh:
        refreshItem =项目;
        刷新();
        返回true;
    案例R.id.sto prefresh:

        如果(refreshItem = NULL和放大器;!&安培;!refreshItem.getActionView()= NULL){
            。refreshItem.getActionView()clearAnimation();
            refreshItem.setActionView(空);
        }
        返回true;
    默认:
        返回super.onOptionsItemSelected(项目);
    }
}


公共无效刷新(){
    如果(FeedActivity.this!= NULL){
        / *
         *附加​​一个旋转的ImageView来刷新项目作为而ActionView
         * /
        LayoutInflater充气=(LayoutInflater)FeedActivity.this
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ImageView的IV =(ImageView的)inflater.inflate(
                R.layout.refresh_action_view,NULL);
        动画旋转= AnimationUtils.loadAnimation(
                FeedActivity.this,R.anim.clockwise_refresh);
        rotation.setRepeatCount(Animation.INFINITE);
        iv.startAnimation(旋转);
        refreshItem.setActionView(ⅳ);
    }
}
 

前点击:

点击后:

下面的图标进行动画(旋转)。

问题:

为什么它向左移动?

一旦转移到左侧,图标变得不点击的,奇怪的是设备后退按钮也不起作用

编辑:

Windows10家庭版系统关闭怎么自动更新

在下面这个回答评论:

Animated图标ActionItem

杰克·沃顿说,如果你正在使用的菜单项方和正确尺寸的图标,你不会得到这个怪异的行为,以谁的人有同样的问题。

不过,我使用的是32×32的图像,它使用MDPI可绘制的设备上。这是说要有工作:(

感谢您

编辑:

refresh_action_view.xml

 < XML版本=1.0编码=UTF-8&GT?;
< ImageView的的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    风格=@风格/ Widget.Sherlock.ActionButton
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:SRC =@可绘制/ ic_refresh/>
 

自定义样式我在我的应用程序中使用

 <样式名称=My_solid_ActionBar父=@风格/ Widget.Sherlock.Light.ActionBar.Solid.Inverse>
    <项目名称=背景> @可绘制/ ab_solid_My< /项目>
    <项目名称=backgroundStacked> @可绘制/ ab_stacked_solid_My< /项目>
    <项目名称=backgroundSplit> @可绘制/ ab_bottom_solid_My< /项目>
    <项目名称=progressBarStyle> @风格/ My_ProgressBar< /项目>
    <项目名称=机器人:背景> @可绘制/ ab_solid_My< /项目>
    <项目名称=机器人:backgroundStacked> @可绘制/ ab_stacked_solid_My< /项目>
    <项目名称=机器人:backgroundSplit> @可绘制/ ab_bottom_solid_My< /项目>
    <项目名称=机器人:progressBarStyle> @风格/ My_ProgressBar< /项目>
< /风格>
 

解决方案

问题是,你不处理所有菜单通胀 onCreateOptionsMenu()。对于动作条刷新动画片我见过的开源应用程序使用的基本逻辑,例如的 Andlytics (也用自己的项目),是实施布尔标志 onCreateOptionsMenu()来决定是否显示刷新动画。

您可以实现它是这样的:当你的刷新()方法被调用,它集布尔 isRefreshing 标志设置为true,并调用 inValidateOptionsMenu()这幕后调用 onCreateOptionsMenu() 启动动画:

在充气 onCreateOptionsMenu(...)菜单:

  @覆盖
公共无效onCreateOptionsMenu(功能菜单,MenuInflater充气){
    menu.clear();
    super.onCreateOptionsMenu(菜单,充气);
    //膨胀的菜单,显示了非动画刷新图标
    inflater.inflate(R.menu.my_ab_menu,菜单);

    如果(isRefreshing){
        //如果我们刷新,显示动画
        菜单项项= menu.findItem(R.id.refreshMenuItem);
        item.setActionView(R.layout.action_bar_indeterminate_progress);
        。ImageView的IV =(ImageView的)item.getActionView()findViewById(R.id.loadingImageView);
        ((AnimationDrawable)iv.getDrawable())开始()。
    }
}
 

开机动画,像这样:

 公共无效刷新(){
        isRefreshing = TRUE;
        inValidateOptionsMenu();
    }
 

如果你希望用户时,他水龙头刷新图标来启动动画,像这样的 onOptionsItemSelected()

 案例R.id.refreshMenuItem:
    isRefreshing = TRUE;
    item.setActionView(R.layout.action_bar_indeterminate_progress);
    。ImageView的IV =(ImageView的)item.getActionView()findViewById(R.id.loadingImageView);
    ((AnimationDrawable)iv.getDrawable())开始()。
    // ...
 

要停止动画电话:

  isRefreshing = FALSE;
invalidateOptionsMenu();
 

这code是一个片段,所以你可能需要调整,如果一个活动,但我认为它传达的基本思路。

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

    case android.R.id.home:
        return true;

    case R.id.searchIcon:
        return true;

    case R.id.startRefresh:
        refreshItem = item;
        refresh();
        return true;
    case R.id.stopRefresh:

        if (refreshItem != null && refreshItem.getActionView() != null) {
            refreshItem.getActionView().clearAnimation();
            refreshItem.setActionView(null);
        }
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}


public void refresh() {
    if (FeedActivity.this != null) {
        /*
         * Attach a rotating ImageView to the refresh item as an ActionView
         */
        LayoutInflater inflater = (LayoutInflater) FeedActivity.this
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ImageView iv = (ImageView) inflater.inflate(
                R.layout.refresh_action_view, null);
        Animation rotation = AnimationUtils.loadAnimation(
                FeedActivity.this, R.anim.clockwise_refresh);
        rotation.setRepeatCount(Animation.INFINITE);
        iv.startAnimation(rotation);
        refreshItem.setActionView(iv);
    }
}

Before Clicking:

After Clicking:

Here the icon is being animated(rotating).

Problem:

why is it shifting to the left?

once it shifts to the left, the icon becomes non clickable and strangely the device back button also doesn't work

EDIT:

In comments below this answer:

Animated Icon for ActionItem

Jake Warton says if you are using a square and correct sized icon for the menu item, you wont get this weird behaviour, to someone who has the same problem.

But i am using a 32x32 image on a device which uses mdpi drawables. Which as stated there must work :(

Thank You

EDIT:

refresh_action_view.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/Widget.Sherlock.ActionButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_refresh" />

Custom Style i use in my app

<style name="My_solid_ActionBar" parent="@style/Widget.Sherlock.Light.ActionBar.Solid.Inverse">
    <item name="background">@drawable/ab_solid_My</item>
    <item name="backgroundStacked">@drawable/ab_stacked_solid_My</item>
    <item name="backgroundSplit">@drawable/ab_bottom_solid_My</item>
    <item name="progressBarStyle">@style/My_ProgressBar</item>
    <item name="android:background">@drawable/ab_solid_My</item>
    <item name="android:backgroundStacked">@drawable/ab_stacked_solid_My</item>
    <item name="android:backgroundSplit">@drawable/ab_bottom_solid_My</item>
    <item name="android:progressBarStyle">@style/My_ProgressBar</item>
</style>

解决方案

The issue is that you're not handling all menu inflation in onCreateOptionsMenu(). The basic logic for an ActionBar refresh animation I've seen used in apps with open source , for example Andlytics (and also used myself in projects), is to implement a boolean flag in onCreateOptionsMenu() to decide whether to show the refresh animation.

You can implement it like this: When your refresh() method is called, it sets the boolean isRefreshing flag to true and calls inValidateOptionsMenu() which 'behind the scene' calls onCreateOptionsMenu() to start the animation:

Inflate the menu in onCreateOptionsMenu(...):

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    menu.clear();
    super.onCreateOptionsMenu(menu, inflater);
    //inflate a menu which shows the non-animated refresh icon
    inflater.inflate(R.menu.my_ab_menu, menu);

    if (isRefreshing) {
        //if we're refreshing, show the animation
        MenuItem item = menu.findItem(R.id.refreshMenuItem);
        item.setActionView(R.layout.action_bar_indeterminate_progress);
        ImageView iv = (ImageView) item.getActionView().findViewById(R.id.loadingImageView);
        ((AnimationDrawable) iv.getDrawable()).start();
    }
}

Start animation like so:

 public void refresh(){
        isRefreshing = true;
        inValidateOptionsMenu();
    }

If you want the user to start the animation when he taps the refresh icon, do like this in onOptionsItemSelected():

case R.id.refreshMenuItem:
    isRefreshing = true;
    item.setActionView(R.layout.action_bar_indeterminate_progress);
    ImageView iv = (ImageView) item.getActionView().findViewById(R.id.loadingImageView);
    ((AnimationDrawable) iv.getDrawable()).start();
    //...

To stop the animation call:

isRefreshing = false;
invalidateOptionsMenu();

This code is from a Fragment so you may have to tweak if for an Activity, but I think it communicates the basic idea.