汉堡菜单图标在Android中交叉动画

时间:2016-03-01 07:17:38

标签: android animation

我正在尝试用十字图标替换菜单图标,但我不知道比在ImageView中替换源更好的解决方案,而且我找不到完成转换图像的库。

Menu icon Cross icon

任何帮助都会有所帮助。

4 个答案:

答案 0 :(得分:0)

对于动画,您可以使用以下代码:

public static void ImageViewAnimatedChange(Context c, final ImageView v, final Bitmap new_image) {
        final Animation anim_out = AnimationUtils.loadAnimation(c, android.R.anim.fade_out);
        final Animation anim_in  = AnimationUtils.loadAnimation(c, android.R.anim.fade_in);
        anim_out.setAnimationListener(new Animation.AnimationListener()
        {
            @Override public void onAnimationStart(Animation animation) {}
            @Override public void onAnimationRepeat(Animation animation) {}
            @Override public void onAnimationEnd(Animation animation)
            {
                v.setImageBitmap(new_image);
                anim_in.setAnimationListener(new Animation.AnimationListener() {
                    @Override public void onAnimationStart(Animation animation) {}
                    @Override public void onAnimationRepeat(Animation animation) {}
                    @Override public void onAnimationEnd(Animation animation) {}
                });
                v.startAnimation(anim_in);
            }
        });
        v.startAnimation(anim_out);
    }

另请查看viewflipper https://stackoverflow.com/a/19635874/5907003

祝你好运!

答案 1 :(得分:0)

Android有一个可绘制的动画,用于在汉堡包和箭头之间进行动画制作:android.support.v7.graphics.drawable.DrawerArrowDrawable 此可绘制对象在画布绘制中使用了非常通用的方法。如果您有空闲时间并准备进行一些乏味的工作,则可以通过查看此示例来制作几乎所有动画。

例如,这是可绘制的十字形“汉堡”:

/**
 * Simple animating drawable between the "hamburger" icon and cross icon
 *
 * Based on [android.support.v7.graphics.drawable.DrawerArrowDrawable]
 */
class HamburgerCrossDrawable(
        /** Width and height of the drawable (the drawable is always square) */
        private val size: Int,
        /** Thickness of each individual line */
        private val barThickness: Float,
        /** The space between bars when they are parallel */
        private val barGap: Float
) : Drawable() {

    private val paint = Paint()
    private val thick2 = barThickness / 2.0f

    init {
        paint.style = Paint.Style.STROKE
        paint.strokeJoin = Paint.Join.MITER
        paint.strokeCap = Paint.Cap.BUTT
        paint.isAntiAlias = true

        paint.strokeWidth = barThickness
    }

    override fun draw(canvas: Canvas) {
        if (progress < 0.5) {
            drawHamburger(canvas)
        } else {
            drawCross(canvas)
        }
    }

    private fun drawHamburger(canvas: Canvas) {
        val bounds = bounds
        val centerY = bounds.exactCenterY()
        val left = bounds.left.toFloat() + thick2
        val right = bounds.right.toFloat() - thick2

        // Draw middle line
        canvas.drawLine(
                left, centerY,
                right, centerY,
                paint)

        // Calculate Y offset to top and bottom lines
        val offsetY = barGap * (2 * (0.5f - progress))

        // Draw top & bottom lines
        canvas.drawLine(
                left, centerY - offsetY,
                right, centerY - offsetY,
                paint)
        canvas.drawLine(
                left, centerY + offsetY,
                right, centerY + offsetY,
                paint)
    }

    private fun drawCross(canvas: Canvas) {
        val bounds = bounds
        val centerX = bounds.exactCenterX()
        val centerY = bounds.exactCenterY()
        val crossHeight = barGap * 2 + barThickness * 3
        val crossHeight2 = crossHeight / 2

        // Calculate current cross position
        val distanceY = crossHeight2 * (2 * (progress - 0.5f))
        val top = centerY - distanceY
        val bottom = centerY + distanceY
        val left = centerX - crossHeight2
        val right = centerX + crossHeight2

        // Draw cross
        canvas.drawLine(
                left, top,
                right, bottom,
                paint)
        canvas.drawLine(
                left, bottom,
                right, top,
                paint)
    }

    override fun setAlpha(alpha: Int) {
        if (alpha != paint.alpha) {
            paint.alpha = alpha
            invalidateSelf()
        }
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
        paint.colorFilter = colorFilter
        invalidateSelf()
    }

    override fun getIntrinsicWidth(): Int {
        return size
    }

    override fun getIntrinsicHeight(): Int {
        return size
    }

    override fun getOpacity(): Int {
        return PixelFormat.TRANSLUCENT
    }

    /**
     * Drawable color
     * Can be animated
     */
    var color: Int = 0xFFFFFFFF.toInt()
        set(value) {
            field = value
            paint.color = value
            invalidateSelf()
        }

    /**
     * Animate this property to transition from hamburger to cross
     * 0 = hamburger
     * 1 = cross
     */
    var progress: Float = 0.0f
        set(value) {
            field = value.coerceIn(0.0f, 1.0f)
            invalidateSelf()
        }

}

您可以像使用其他任何可绘制对象一样使用此可绘制对象,例如,通过将ImageView src设置为此可绘制对象:

imageView = AppCompatImageView(context)
addView(imageView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
hamburgerDrawable = HamburgerCrossDrawable(
        size = dpToPx(20).toInt(),
        barThickness = dpToPx(2),
        barGap = dpToPx(5)
)
hamburgerDrawable.color = hamburgerColor
imageView.setImageDrawable(hamburgerDrawable)

要使可绘制对象实际上从汉堡到十字,您需要更改HamburgerCrossDrawable.progress(0代表汉堡,1代表十字架):

val animator = ValueAnimator.ofFloat(0.0f, 1.0f)
animator.interpolator = AccelerateDecelerateInterpolator()
animator.duration = 300
animator.addUpdateListener {
    val progress = it.animatedValue as Float
    val color = interpolateColor(hamburgerColor, crossColor, progress)
    hamburgerDrawable.color = color
    hamburgerDrawable.progress = progress
}
animator.start()

答案 2 :(得分:0)

我似乎还没来得及上场,但我更喜欢采用声明式方法,并为图标动画设置了动画选择器。似乎更清楚了,您唯一需要关心的是ViewButton的状态。

TL; DR::我已经创建了一个gist,其中包含实现动画所需的所有类。

以下是您用作可绘制对象的选择器示例:

<?xml version="1.0" encoding="utf-8"?>
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/open"
        android:drawable="@drawable/ic_drawer_closed"
        android:state_selected="true"/>

    <item
        android:id="@+id/closed"
        android:drawable="@drawable/ic_drawer"/>

    <transition
        android:drawable="@drawable/avd_drawer_close"
        android:fromId="@id/open"
        android:toId="@id/closed"/>

    <transition
        android:drawable="@drawable/avd_drawer_open"
        android:fromId="@id/closed"
        android:toId="@id/open"/>

</animated-selector>

这是动画本身: Drawer (≡) to close (x) animated vector drawable

答案 3 :(得分:0)

您应该使用 Internet 上现有的 AnimatedVectorDrawable。或者您应该使用 Shape Shifter 网站上的图标创建它。我建议您在 youtube 上观看有关此过程的教程:ShapeShifter Tutorial