android - 像 Spotify 这样的按钮反馈
问题描述
我想从我的按钮中获得像 Spotify 这样的按钮反馈。这意味着当我单击按钮时,按钮应该小一点,并且应该变成浅灰色。我知道这很容易,但我不知道如何用动画制作。这就是示例按钮:<Button id="SpotifyButton"/>
我期待着得到答案!:)
解决方案
漏洞答案基于Android Geek的答案。
view_press.xml(在 anim res 文件夹中)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:fillAfter="true" android:fillBefore="true">
<scale
android:duration="100"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="70%"
android:pivotY="70%"
android:toXScale="0.95"
android:toYScale="0.95" >
</scale>
</set>
view_release.xml(在 anim res 文件夹中)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:fillAfter="true" android:fillBefore="true">
<scale
android:duration="100"
android:fromXScale="0.95"
android:fromYScale="0.95"
android:pivotX="70%"
android:pivotY="70%"
android:toXScale="1"
android:toYScale="1">
</scale>
</set>
自定义视图
public class SpotifyButton extends AppCompatTextView {
int backgroundColor = ((ColorDrawable) getBackground()).getColor();
GradientDrawable gradientDrawable = getBackgroundShape(backgroundColor);
ValueAnimator defaultAnimator = getDefaultBackgroundAnimator(this);
public SpotifyButton (Context context) {
super(context);
setOnTouchListener();
setBackground(gradientDrawable);
}
public SpotifyButton (Context context, AttributeSet attrs) {
super(context, attrs);
setOnTouchListener();
setBackground(gradientDrawable);
}
public SpotifyButton (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setOnTouchListener();
setBackground(gradientDrawable);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
@Override
public boolean performClick() {
super.performClick();
return true;
}
public static int manipulateColor(int color, float factor) {
int a = Color.alpha(color);
int r = Math.round(Color.red(color) * factor);
int g = Math.round(Color.green(color) * factor);
int b = Math.round(Color.blue(color) * factor);
return Color.argb(a,
Math.min(r, 255),
Math.min(g, 255),
Math.min(b, 255));
}
public ValueAnimator getDefaultBackgroundAnimator(final View view) {
final float[] from = new float[3],
to = new float[3];
Color.colorToHSV(backgroundColor, from);
Color.colorToHSV(manipulateColor(backgroundColor, 0.7f), to);
ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
anim.setDuration(200);
final float[] hsv = new float[3];
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// Transition along each axis of HSV (hue, saturation, value)
hsv[0] = from[0] + (to[0] - from[0]) * animation.getAnimatedFraction();
hsv[1] = from[1] + (to[1] - from[1]) * animation.getAnimatedFraction();
hsv[2] = from[2] + (to[2] - from[2]) * animation.getAnimatedFraction();
gradientDrawable.setColor(Color.HSVToColor(hsv));
view.setBackground(gradientDrawable);
}
});
return anim;
}
public GradientDrawable getBackgroundShape(int color) {
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
gradientDrawable.setCornerRadius(100);
gradientDrawable.setColor(color);
return gradientDrawable;
}
public void setOnTouchListener() {
this.setOnTouchListener(new OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Animation onclick_effect_press = AnimationUtils.loadAnimation(getContext(), R.anim.ui_view_feedback_press);
defaultAnimator.start();
v.startAnimation(onclick_effect_press);
return true;
case MotionEvent.ACTION_UP:
Animation onclick_effect_release = AnimationUtils.loadAnimation(getContext(), R.anim.ui_view_feedback_release);
defaultAnimator.reverse();
v.startAnimation(onclick_effect_release);
if (isMotionEventInsideView(v, event)) {
performClick();
}
return true;
}
return false;
}
});
}
private boolean isMotionEventInsideView(View view, MotionEvent event) {
Rect viewRect = new Rect(
view.getLeft(),
view.getTop(),
view.getRight(),
view.getBottom()
);
return viewRect.contains(
view.getLeft() + (int) event.getX(),
view.getTop() + (int) event.getY()
);
}
}
结果
编码快乐!!
推荐阅读
- powershell - 如何将交换属性同步到本地 AD 对象
- javascript - 如何在 for 循环中映射
- vb.net - 有没有办法避免在 VB 中重复使用公共共享变量?
- php - 如果值存在或等于其中的数组,则禁用按钮 while
- c# - Microsoft.AspNetCore.Authorization.DefaultAuthorizationService - 授权失败
- django - 在 Django Admin 中注册多个模型并排除公共字段
- angular - ViewChild 与 Stepper ExpressionChangedAfterItHasBeenCheckedError Angular 8
- c++ - 为什么这些创建字符串的方法之间存在如此大的差异
- java - OnTouchEvent:我想在屏幕上用另一根手指移动时识别触摸
- tcl - 在 TCL 中,“.list”和“.desc”语法是做什么用的?我在哪里可以了解更多关于它们的信息?