How to animate background of ActionMode of the ActionBar?

自作多情 提交于 2019-12-06 01:15:09

问题


Background

It's possible to change the background of the actionbar, and even animate between two colors, as such:

public static void animateBetweenColors(final ActionBar actionBar, final int colorFrom, final int colorTo,
        final int durationInMs) {
    final ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
    colorAnimation.addUpdateListener(new AnimatorUpdateListener() {
        ColorDrawable colorDrawable = new ColorDrawable(colorFrom);

        @Override
        public void onAnimationUpdate(final ValueAnimator animator) {
            colorDrawable.setColor((Integer) animator.getAnimatedValue());
            actionBar.setBackgroundDrawable(colorDrawable);
        }
    });
    if (durationInMs >= 0)
        colorAnimation.setDuration(durationInMs);
    colorAnimation.start();
}

The problem

I can't find a way to get the view of the action mode, so that I could change its background on some cases (while it's showing).

What I tried

Only thing I found is a hack-y way which assumes that the id of the action mode will stay the same, and even this would work just for the view of the "done" button (the one that looks like an "V" and is actually more like "cancel").

I also found how to change it via themes, but that's not what I need, since I need to do it programmatically.

The question

How do I get the view of the actionMode, or, more precisely, how can I change its background using an animation?


回答1:


How do I get the view of the actionMode, or, more precisely, how can I change its background using an animation?

You have two choices, unfortunately neither of which involve native ActionMode APIs:

The ActionBarContextView is responsible for controlling the ActionMode

  1. Use Resources.getIdentifier to call Activity.findViewById and pass in the ID the system uses for the ActionBarContextView
  2. Use reflection to access to Field in ActionBarImpl

Here's an example of both:

Using Resources.getIdentifier:

private void animateActionModeViaFindViewById(int colorFrom, int colorTo, int duration) {
    final int amId = getResources().getIdentifier("action_context_bar", "id", "android");
    animateActionMode(findViewById(amId), colorFrom, colorTo, duration);
}

Using reflection:

private void animateActionModeViaReflection(int colorFrom, int colorTo, int duration) {
    final ActionBar actionBar = getActionBar();
    try {
        final Field contextView = actionBar.getClass().getDeclaredField("mContextView");
        animateActionMode((View) contextView.get(actionBar), colorFrom, colorTo, duration);
    } catch (final Exception ignored) {
        // Nothing to do
    }
}

private void animateActionMode(final View actionMode, final int from, int to, int duration) {
    final ValueAnimator va = ValueAnimator.ofObject(new ArgbEvaluator(), from, to);
    final ColorDrawable actionModeBackground = new ColorDrawable(from);
    va.addUpdateListener(new AnimatorUpdateListener() {

        @Override
        public void onAnimationUpdate(final ValueAnimator animator) {
            actionModeBackground.setColor((Integer) animator.getAnimatedValue());
            actionMode.setBackground(actionModeBackground);
        }

    });
    va.setDuration(duration);
    va.start();
}

Results

Here's a gif of the results animating from Color.BLACK to Color.BLUE at a duration of 2500:



来源:https://stackoverflow.com/questions/23457709/how-to-animate-background-of-actionmode-of-the-actionbar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!