Android 汉堡包菜单图标在安卓中交叉动画
我试图用十字图标替换菜单图标,但我不知道比在ImageView中替换源代码更好的解决方案,而且我找不到转换图像的完成库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(
欢迎提供任何帮助。对于动画,您可以使用以下代码:
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设置为应用程序栏导航汉堡包按钮。因此,我最终创造了一个自定义按钮,它就像一个魅力。谢谢