- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的 Activity 中有一个圆角矩形按钮。单击按钮后,它应该会稍微压缩/收缩(按钮的高度不应改变)并且应该变为圆形。如何使用 XML 中的 anim 文件夹实现此目的?
目前我的代码是:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<scale
android:duration="400"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:toXScale="0.1"
android:toYScale="1" />
<set>
<alpha
android:duration="400"
android:fromAlpha="1"
android:toAlpha="0" />
</set>
</set>
最佳答案
Create MorphingButton class paste below code into;
public class MorphingButton extends Button {
private Padding mPadding;
private int mHeight;
private int mWidth;
private int mColor;
private int mCornerRadius;
private int mStrokeWidth;
private int mStrokeColor;
protected boolean mAnimationInProgress;
private StrokeGradientDrawable mDrawableNormal;
private StrokeGradientDrawable mDrawablePressed;
public MorphingButton(Context context) {
super(context);
initView();
}
public MorphingButton(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public MorphingButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mHeight == 0 && mWidth == 0 && w != 0 && h != 0) {
mHeight = getHeight();
mWidth = getWidth();
}
}
public StrokeGradientDrawable getDrawableNormal() {
return mDrawableNormal;
}
public void morph(@NonNull Params params) {
if (!mAnimationInProgress) {
mDrawablePressed.setColor(params.colorPressed);
mDrawablePressed.setCornerRadius(params.cornerRadius);
mDrawablePressed.setStrokeColor(params.strokeColor);
mDrawablePressed.setStrokeWidth(params.strokeWidth);
if (params.duration == 0) {
morphWithoutAnimation(params);
} else {
morphWithAnimation(params);
}
mColor = params.color;
mCornerRadius = params.cornerRadius;
mStrokeWidth = params.strokeWidth;
mStrokeColor = params.strokeColor;
}
}
private void morphWithAnimation(@NonNull final Params params) {
mAnimationInProgress = true;
setText(null);
setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
setPadding(mPadding.left, mPadding.top, mPadding.right, mPadding.bottom);
MorphingAnimation.Params animationParams = MorphingAnimation.Params.create(this)
.color(mColor, params.color)
.cornerRadius(mCornerRadius, params.cornerRadius)
.strokeWidth(mStrokeWidth, params.strokeWidth)
.strokeColor(mStrokeColor, params.strokeColor)
.height(getHeight(), params.height)
.width(getWidth(), params.width)
.duration(params.duration)
.listener(new MorphingAnimation.Listener() {
@Override
public void onAnimationEnd() {
finalizeMorphing(params);
}
});
MorphingAnimation animation = new MorphingAnimation(animationParams);
animation.start();
}
private void morphWithoutAnimation(@NonNull Params params) {
mDrawableNormal.setColor(params.color);
mDrawableNormal.setCornerRadius(params.cornerRadius);
mDrawableNormal.setStrokeColor(params.strokeColor);
mDrawableNormal.setStrokeWidth(params.strokeWidth);
if(params.width != 0 && params.height !=0) {
ViewGroup.LayoutParams layoutParams = getLayoutParams();
layoutParams.width = params.width;
layoutParams.height = params.height;
setLayoutParams(layoutParams);
}
finalizeMorphing(params);
}
private void finalizeMorphing(@NonNull Params params) {
mAnimationInProgress = false;
if (params.icon != 0 && params.text != null) {
setIconLeft(params.icon);
setText(params.text);
} else if (params.icon != 0) {
setIcon(params.icon);
} else if(params.text != null) {
setText(params.text);
}
if (params.animationListener != null) {
params.animationListener.onAnimationEnd();
}
}
public void blockTouch() {
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
}
public void unblockTouch() {
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
}
private void initView() {
mPadding = new Padding();
mPadding.left = getPaddingLeft();
mPadding.right = getPaddingRight();
mPadding.top = getPaddingTop();
mPadding.bottom = getPaddingBottom();
Resources resources = getResources();
int cornerRadius = (int) resources.getDimension(R.dimen._10sdp);
int primaryColor = resources.getColor(R.color.colorAccent);
int secondaryColor = resources.getColor(R.color.colorPrimary);
StateListDrawable background = new StateListDrawable();
mDrawableNormal = createDrawable(primaryColor, cornerRadius, 0);
mDrawablePressed = createDrawable(secondaryColor, cornerRadius, 0);
mColor = primaryColor;
mStrokeColor = primaryColor;
mCornerRadius = cornerRadius;
background.addState(new int[]{android.R.attr.state_pressed}, mDrawablePressed.getGradientDrawable());
background.addState(StateSet.WILD_CARD, mDrawableNormal.getGradientDrawable());
setBackgroundCompat(background);
}
private StrokeGradientDrawable createDrawable(int color, int cornerRadius, int strokeWidth) {
StrokeGradientDrawable drawable = new StrokeGradientDrawable(new GradientDrawable());
drawable.getGradientDrawable().setShape(GradientDrawable.RECTANGLE);
drawable.setColor(color);
drawable.setCornerRadius(cornerRadius);
drawable.setStrokeColor(color);
drawable.setStrokeWidth(strokeWidth);
return drawable;
}
@SuppressWarnings("deprecation")
private void setBackgroundCompat(@Nullable Drawable drawable) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
setBackgroundDrawable(drawable);
} else {
setBackground(drawable);
}
}
public void setIcon(@DrawableRes final int icon) {
// post is necessary, to make sure getWidth() doesn't return 0
post(new Runnable() {
@Override
public void run() {
Drawable drawable = getResources().getDrawable(icon);
int padding = (getWidth() / 2) - (drawable.getIntrinsicWidth() / 2);
setCompoundDrawablesWithIntrinsicBounds(icon, 0, 0, 0);
setPadding(padding, 0, 0, 0);
}
});
}
public void setIconLeft(@DrawableRes int icon) {
setCompoundDrawablesWithIntrinsicBounds(icon, 0, 0, 0);
}
private class Padding {
public int left;
public int right;
public int top;
public int bottom;
}
public static class Params {
private int cornerRadius;
private int width;
private int height;
private int color;
private int colorPressed;
private int duration;
private int icon;
private int strokeWidth;
private int strokeColor;
private String text;
private MorphingAnimation.Listener animationListener;
private Params() {
}
public static Params create() {
return new Params();
}
public Params text(@NonNull String text) {
this.text = text;
return this;
}
public Params icon(@DrawableRes int icon) {
this.icon = icon;
return this;
}
public Params cornerRadius(int cornerRadius) {
this.cornerRadius = cornerRadius;
return this;
}
public Params width(int width) {
this.width = width;
return this;
}
public Params height(int height) {
this.height = height;
return this;
}
public Params color(int color) {
this.color = color;
return this;
}
public Params colorPressed(int colorPressed) {
this.colorPressed = colorPressed;
return this;
}
public Params duration(int duration) {
this.duration = duration;
return this;
}
public Params strokeWidth(int strokeWidth) {
this.strokeWidth = strokeWidth;
return this;
}
public Params strokeColor(int strokeColor) {
this.strokeColor = strokeColor;
return this;
}
public Params animationListener(MorphingAnimation.Listener animationListener) {
this.animationListener = animationListener;
return this;
}
}
public static class MorphingAnimation {
public interface Listener {
void onAnimationEnd();
}
public static class Params {
private float fromCornerRadius;
private float toCornerRadius;
private int fromHeight;
private int toHeight;
private int fromWidth;
private int toWidth;
private int fromColor;
private int toColor;
private int duration;
private int fromStrokeWidth;
private int toStrokeWidth;
private int fromStrokeColor;
private int toStrokeColor;
private MorphingButton button;
private MorphingAnimation.Listener animationListener;
private Params(@NonNull MorphingButton button) {
this.button = button;
}
public static Params create(@NonNull MorphingButton button) {
return new Params(button);
}
public Params duration(int duration) {
this.duration = duration;
return this;
}
public Params listener(@NonNull MorphingAnimation.Listener animationListener) {
this.animationListener = animationListener;
return this;
}
public Params color(int fromColor, int toColor) {
this.fromColor = fromColor;
this.toColor = toColor;
return this;
}
public Params cornerRadius(int fromCornerRadius, int toCornerRadius) {
this.fromCornerRadius = fromCornerRadius;
this.toCornerRadius = toCornerRadius;
return this;
}
public Params height(int fromHeight, int toHeight) {
this.fromHeight = fromHeight;
this.toHeight = toHeight;
return this;
}
public Params width(int fromWidth, int toWidth) {
this.fromWidth = fromWidth;
this.toWidth = toWidth;
return this;
}
public Params strokeWidth(int fromStrokeWidth, int toStrokeWidth) {
this.fromStrokeWidth = fromStrokeWidth;
this.toStrokeWidth = toStrokeWidth;
return this;
}
public Params strokeColor(int fromStrokeColor, int toStrokeColor) {
this.fromStrokeColor = fromStrokeColor;
this.toStrokeColor = toStrokeColor;
return this;
}
}
private Params mParams;
public MorphingAnimation(@NonNull Params params) {
mParams = params;
}
public void start() {
StrokeGradientDrawable background = mParams.button.getDrawableNormal();
ObjectAnimator cornerAnimation =
ObjectAnimator.ofFloat(background, "cornerRadius", mParams.fromCornerRadius, mParams.toCornerRadius);
ObjectAnimator strokeWidthAnimation =
ObjectAnimator.ofInt(background, "strokeWidth", mParams.fromStrokeWidth, mParams.toStrokeWidth);
ObjectAnimator strokeColorAnimation = ObjectAnimator.ofInt(background, "strokeColor", mParams.fromStrokeColor, mParams.toStrokeColor);
strokeColorAnimation.setEvaluator(new ArgbEvaluator());
ObjectAnimator bgColorAnimation = ObjectAnimator.ofInt(background, "color", mParams.fromColor, mParams.toColor);
bgColorAnimation.setEvaluator(new ArgbEvaluator());
ValueAnimator heightAnimation = ValueAnimator.ofInt(mParams.fromHeight, mParams.toHeight);
heightAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = mParams.button.getLayoutParams();
layoutParams.height = val;
mParams.button.setLayoutParams(layoutParams);
}
});
ValueAnimator widthAnimation = ValueAnimator.ofInt(mParams.fromWidth, mParams.toWidth);
widthAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = mParams.button.getLayoutParams();
layoutParams.width = val;
mParams.button.setLayoutParams(layoutParams);
}
});
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(mParams.duration);
animatorSet.playTogether(strokeWidthAnimation, strokeColorAnimation, cornerAnimation, bgColorAnimation,
heightAnimation, widthAnimation);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (mParams.animationListener != null) {
mParams.animationListener.onAnimationEnd();
}
}
});
animatorSet.start();
}
}
public class StrokeGradientDrawable {
private int mStrokeWidth;
private int mStrokeColor;
private GradientDrawable mGradientDrawable;
private float mRadius;
private int mColor;
public StrokeGradientDrawable(GradientDrawable drawable) {
mGradientDrawable = drawable;
}
public int getStrokeWidth() {
return mStrokeWidth;
}
public void setStrokeWidth(int strokeWidth) {
mStrokeWidth = strokeWidth;
mGradientDrawable.setStroke(strokeWidth, getStrokeColor());
}
public int getStrokeColor() {
return mStrokeColor;
}
public void setStrokeColor(int strokeColor) {
mStrokeColor = strokeColor;
mGradientDrawable.setStroke(getStrokeWidth(), strokeColor);
}
public void setCornerRadius(float radius) {
mRadius = radius;
mGradientDrawable.setCornerRadius(radius);
}
public void setColor(int color) {
mColor = color;
mGradientDrawable.setColor(color);
}
public int getColor() {
return mColor;
}
public float getRadius() {
return mRadius;
}
public GradientDrawable getGradientDrawable() {
return mGradientDrawable;
}
}
}
Add this widget in your layout.xml
<com.test.widgets.MorphingButton
android:id="@+id/btnDone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="DONE"/>
In Activity to animate view onButtonClick
write below code inside `MorphingButton` onClick
MorphingButton.Params circle = MorphingButton.Params.create()//To animate in circle from rect-round
.duration(500)
.cornerRadius((int) getResources().getDimension(R.dimen._100sdp))
.width((int) getResources().getDimension(R.dimen._56sdp))
.height((int) getResources().getDimension(R.dimen._56sdp))
.color(Color.BLUE) // normal state color
.colorPressed(Color.GREEN) // pressed state color
.icon(R.drawable.ic_loader); // icon
btnDone.morph(circle);
//To animate from circle to rect-round to this demo purpose
btnDone.postDelayed(new Runnable() {
@Override
public void run() {
MorphingButton.Params square = MorphingButton.Params.create()
.duration(500)
.cornerRadius((int) getResources().getDimension(R.dimen._100sdp))
.width((int) getResources().getDimension(R.dimen._100sdp))
.height((int) getResources().getDimension(R.dimen._56sdp))
.color(Color.BLUE) // normal state color
.colorPressed(Color.GREEN) // pressed state color
.icon(R.drawable.ic_loader) // icon
.text("DONE");
btnDone.morph(square);
}
}, 5000);
关于android - 如何使用动画将按钮的形状从圆角矩形更改为圆形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40785199/
我最近在/ drawable中添加了一些.gifs,以便可以将它们与按钮一起使用。这个工作正常(没有错误)。现在,当我重建/运行我的应用程序时,出现以下错误: Error: Gradle: Execu
Android 中有返回内部存储数据路径的方法吗? 我有 2 部 Android 智能手机(Samsung s2 和 s7 edge),我在其中安装了一个应用程序。我想使用位于这条路径中的 sqlit
这个问题在这里已经有了答案: What's the difference between "?android:" and "@android:" in an android layout xml f
我只想知道 android 开发手机、android 普通手机和 android root 手机之间的实际区别。 我们不能从实体店或除 android marketplace 以外的其他地方购买开发手
自Gradle更新以来,我正在努力使这个项目达到标准。这是一个团队项目,它使用的是android-apt插件。我已经进行了必要的语法更改(编译->实现和apt->注释处理器),但是编译器仍在告诉我存在
我是android和kotlin的新手,所以请原谅要解决的一个非常简单的问题! 我已经使用导航体系结构组件创建了一个基本应用程序,使用了底部的导航栏和三个导航选项。每个导航选项都指向一个专用片段,该片
我目前正在使用 Facebook official SDK for Android . 我现在正在使用高级示例应用程序,但我不知道如何让它获取应用程序墙/流/状态而不是登录的用户。 这可能吗?在那种情
我在下载文件时遇到问题, 我可以在模拟器中下载文件,但无法在手机上使用。我已经定义了上网和写入 SD 卡的权限。 我在服务器上有一个 doc 文件,如果用户单击下载。它下载文件。这在模拟器中工作正常但
这个问题在这里已经有了答案: What is the difference between gravity and layout_gravity in Android? (22 个答案) 关闭 9
任何人都可以告诉我什么是 android 缓存和应用程序缓存,因为当我们谈论缓存清理应用程序时,它的作用是,缓存清理概念是清理应用程序缓存还是像内存管理一样主存储、RAM、缓存是不同的并且据我所知,缓
假设应用程序 Foo 和 Eggs 在同一台 Android 设备上。任一应用程序都可以获取设备上所有应用程序的列表。一个应用程序是否有可能知道另一个应用程序是否已经运行以及运行了多长时间? 最佳答案
我有点困惑,我只看到了从 android 到 pc 或者从 android 到 pc 的例子。我需要制作一个从两部手机 (android) 连接的 android 应用程序进行视频聊天。我在想,我知道
用于使用 Android 以编程方式锁定屏幕。我从 Stackoverflow 之前关于此的问题中得到了一些好主意,并且我做得很好,但是当我运行该代码时,没有异常和错误。而且,屏幕没有锁定。请在这段代
文档说: android:layout_alignParentStart If true, makes the start edge of this view match the start edge
我不知道这两个属性和高度之间的区别。 以一个TextView为例,如果我将它的layout_width设置为wrap_content,并将它的width设置为50 dip,会发生什么情况? 最佳答案
这两个属性有什么关系?如果我有 android:noHistory="true",那么有 android:finishOnTaskLaunch="true" 有什么意义吗? 最佳答案 假设您的应用中有
我是新手,正在尝试理解以下 XML 代码: 查看 developer.android.com 上的文档,它说“starStyle”是 R.attr 中的常量, public static final
在下面的代码中,为什么当我设置时单选按钮的外观会发生变化 android:layout_width="fill_parent" 和 android:width="fill_parent" 我说的是
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
假设我有一个函数 fun myFunction(name:String, email:String){},当我调用这个函数时 myFunction('Ali', 'ali@test.com ') 如何
我是一名优秀的程序员,十分优秀!