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

Android 汉堡包菜单图标在安卓中交叉动画,android,animation,Android,Animation,我试图用十字图标替换菜单图标,但我不知道比在ImageView中替换源代码更好的解决方案,而且我找不到转换图像的完成库 欢迎提供任何帮助。对于动画,您可以使用以下代码: public static void ImageViewAnimatedChange(Context c, final ImageView v, final Bitmap new_image) { final Animation anim_out = AnimationUtils.loadAnimation(

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


欢迎提供任何帮助。

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

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


祝你好运

安卓系统有一个可在汉堡和箭头之间绘制动画的绘图: 这种可绘制使用非常通用的画布绘制方法。如果您有一些空闲时间并准备好做一些乏味的工作,您可以通过查看此示例来制作几乎所有的动画

例如,这里有一个“汉堡包”可以交叉绘制:

/**
 * 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 = 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)
<?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>
要使可绘制的图形从汉堡变为十字和背面,您需要更改
HamburgerCrossDrawable.progress
(0代表汉堡,1代表十字):


我似乎有点晚了,但我更喜欢一种声明式的方法,带有图标动画的动画选择器。它看起来更清晰,您只需要关心
视图
按钮
的状态

TL;DR:我已经创建了一个包含实现动画所需的所有类的应用程序

下面是一个选择器示例,您可以将其用作可绘制的:

/**
 * 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 = 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)
<?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>


您应该使用互联网上现有的动画矢量绘图。或者你应该用网站上的图标来创建它。我建议你在youtube上观看一个教程,了解这个过程:。

谢谢,但它不是动作栏。它是一个简单的图像视图吗?您想更改图像图标吗?试试这个
iv.setImageResource(R.drawable.cross)我想用动画更改图像资源谢谢,我会在拿到我的电脑后检查,但看起来它会工作的!你是说三点溢出图标吗?任何看起来比替换src更好的动画都会很棒。你能解释一下如何将动画应用到抽屉布局汉堡图标上吗?谢谢看看要点,你有所有需要的文件。您只需使用
asl\u drawer
(asl=AnimatedStateListDrawable)作为src drawable,然后在单击汉堡包图标时更改所选
状态的值。问题是现在有办法将src drawable设置为应用程序栏导航汉堡包按钮。因此,我最终创造了一个自定义按钮,它就像一个魅力。谢谢