在按下时动画地减小按钮大小并在释放时恢复它的大小
Animatedly reduce button size on press and regain it's size on release
我想要创建一个按钮,在按下时改变大小(稍微小一点),再次释放按钮后,大小应该变回正常 size.I 我正在使用 Scale xml 来实现这一点,但即使我不释放按钮,它也会重新定位自己。
按钮这里我指的是imageview。
这是我的源代码:-
imgSpin = (ImageView) findViewById(R.id.iv_spins);
imgSpin.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
imgSpin.startAnimation(mAnimation);
spinslot();
break;
case MotionEvent.ACTION_UP:
imgSpin.clearAnimation();
imgSpin.setEnabled(false);
break;
}
return true;
}
});
我的体重秤Xml:-
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200"
android:fromXScale=".8"
android:fromYScale=".8"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0" >
</scale>
我的XML:-
<LinearLayout
android:id="@+id/layout_status"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".2"
android:orientation="horizontal" >
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5" />
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2.1"
android:background="@drawable/bootser" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2.5"
android:background="@drawable/bet_bg"
android:gravity="center_vertical"
android:orientation="horizontal"
android:weightSum="1" >
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_weight=".2"
android:src="@drawable/leftarrow" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:layout_weight=".6"
android:gravity="center"
android:text="Bet"
android:textColor="@android:color/white" />
<ImageView
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_weight=".2"
android:src="@drawable/rightarrow" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2.5"
android:background="@drawable/container"
android:gravity="center" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="winning"
android:textColor="@android:color/white" />
</LinearLayout>
<ImageView
android:id="@+id/iv_spins"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.9"
android:background="@drawable/spin" />
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5" />
</LinearLayout>
我尝试使用 paramLayout,但是当我在 XML 中设置权重时,它不会给我带来动画效果。
我已经在使用这种方法了:-
case MotionEvent.ACTION_DOWN:
ViewGroup.LayoutParams params = imgSpin.getLayoutParams();
// Button new width
params.width = params.width - (params.width *90/100);
imgSpin.setLayoutParams(params);
break;
params.width 总是 return 我零 所以我试着用重量来做这个,通过使用重量我的视图在点击时出现故障..我想要它平滑所以我更喜欢缩放
第二种方法:-
case MotionEvent.ACTION_DOWN:
LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) imgSpin
.getLayoutParams();
// Button new width
params.weight = 1.7f;
imgSpin.setLayoutParams(params);
// imgSpin.startAnimation(mAnimation);
// spinslot();
break;
case MotionEvent.ACTION_UP:
LinearLayout.LayoutParams params2 = (android.widget.LinearLayout.LayoutParams) imgSpin
.getLayoutParams();
// Button new width
params2.weight = 1.9f;
imgSpin.setLayoutParams(params2);
// imgSpin.clearAnimation();
imgSpin.setEnabled(false);
break;
}
return true;
可以但不流畅
请告诉我怎么做
谢谢
你可以添加 fillafter 属性: android:fillAfter="true"
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200"
android:fromXScale=".8"
android:fromYScale=".8"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="true"
android:toXScale="1.0"
android:toYScale="1.0" >
</scale>
这是你想要的:-
imgSpin.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
ObjectAnimator scaleDownX = ObjectAnimator.ofFloat(imgSpin,
"scaleX", 0.8f);
ObjectAnimator scaleDownY = ObjectAnimator.ofFloat(imgSpin,
"scaleY", 0.8f);
scaleDownX.setDuration(1000);
scaleDownY.setDuration(1000);
AnimatorSet scaleDown = new AnimatorSet();
scaleDown.play(scaleDownX).with(scaleDownY);
scaleDown.start();
spinslot();
break;
case MotionEvent.ACTION_UP:
ObjectAnimator scaleDownX2 = ObjectAnimator.ofFloat(
imgSpin, "scaleX", 1f);
ObjectAnimator scaleDownY2 = ObjectAnimator.ofFloat(
imgSpin, "scaleY", 1f);
scaleDownX2.setDuration(1000);
scaleDownY2.setDuration(1000);
AnimatorSet scaleDown2 = new AnimatorSet();
scaleDown2.play(scaleDownX2).with(scaleDownY2);
scaleDown2.start();
imgSpin.setEnabled(false);
break;
}
return true;
}
});
只需在您的 xml 中进行以下几项更改即可:-
<ImageView
android:id="@+id/iv_spins"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.9"
android:adjustViewBounds="true"
android:background="@drawable/spin"
android:scaleX="1"
android:scaleY="1" />
利用scaleDown.play(scaleDownX).with(scaleDownY),它会保持动画位置,不会恢复到原来的位置
希望它能解决您的问题
干杯
<ImageView
android:id="@+id/iv_spins"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.9"
android:adjustViewBounds="true"
android:background="@drawable/spin"
android:scaleX="1"
android:scaleY="1"
/>
在 /res/animator
中创建两个 XML
reduce_size.xml
<?xml version="1.0" encoding="utf-8"?>
<set android:ordering="sequentially"
xmlns:android="http://schemas.android.com/apk/res/android">
<set>
<objectAnimator
android:propertyName="scaleX"
android:duration="300"
android:valueTo="0.9f"
android:valueType="floatType"/>
<objectAnimator
android:propertyName="scaleY"
android:duration="300"
android:valueTo="0.9f"
android:valueType="floatType"/>
</set>
</set>
regain_size.xml
<?xml version="1.0" encoding="utf-8"?>
<set android:ordering="sequentially"
xmlns:android="http://schemas.android.com/apk/res/android">
<set>
<objectAnimator
android:propertyName="scaleX"
android:duration="1000"
android:valueTo="1f"
android:startOffset="300"
android:valueType="floatType"/>
<objectAnimator
android:propertyName="scaleY"
android:duration="1000"
android:valueTo="1f"
android:startOffset="300"
android:valueType="floatType"/>
</set>
</set>
用法
在 MotionEvent.ACTION_DOWN
AnimatorSet reducer = (AnimatorSet) AnimatorInflater.loadAnimator(mContext,R.animator.squeeze_in);
reducer.setTarget(view);
reducer.start();
在 MotionEvent.ACTION_UP
AnimatorSet regainer = (AnimatorSet) AnimatorInflater.loadAnimator(mContext,R.animator.squeeze_out);
regainer.setTarget(view);
regainer.start();
您可以在 touchlistener 上以编程方式执行此操作,如下所示
new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction == MotionEvent.ACTION_DOWN) {
// scale your value
float reducedvalue = (float)0.7;
v.setScaleX(reducedvalue);
v.setScaleY(reducedvalue);
}
else if (event.getAction == MotionEvent.ACTION_UP) {
v.setScaleX(1);
v.setScaleY(1);
}
}
}
很简单,但是你得知道AndroidAPI是如何处理每个监听器的调用的。
技巧如下:
1- onTouch 方法在 TouchListener 将首先被调用。
1.1- 如果 onTouch 方法 returns 为真,那么 onLongClick(in LongClickListener) 或 onClick(in ClickListener) 将被忽略(两者都不会再被调用)。
2- 如果 onTouch 方法 returns 为假,则检查 onLongClick returns 是否为真所以 onClick 不会被调用,但如果它 returns false 那么 onClick 也会被调用。
这是一个例子:
targetButton.setOnLongClickListener(v -> {
targetButton.animate().scaleX(1.2f).scaleY(1.2f).setDuration(0);
Log.d("Button", "onLong: ");
return true;
});
targetButton.setOnClickListener(v -> {
Log.d("Button", "onClick: ");
});
targetButton.setOnTouchListener((v, event) -> {
Log.d("Button", "onTouch: ");
if (event.getAction() == MotionEvent.ACTION_UP) {
recordButton.animate().scaleX(1.0f).scaleY(1.0f).setDuration(0);
}
// if you want to make it pretty increase the size when click also
/* else if (event.getAction() == MotionEvent.ACTION_DOWN) {
targetButton.animate().scaleX(1.2f).scaleY(1.2f).setDuration(0);
} */
return false;
});
在这个例子中,如果我检测到长按,我试图增加按钮的大小,否则在 onClick 方法中做一些事情,如果用户释放按钮我再次缩小尺寸。
如果您希望每次调用 onLongClick 时调用 onClick,只需使 onLongClick returns 错误;
自 API 21 (Lollipop) 以来,基于 stateListAnimator 属性,可以使用仅 xml 的解决方案。这是一个布局示例,在按下时缩放到其原始大小的 0.9:
<!-- res/layout/my_layout.xml -->
<LinearLayout ...
android:stateListAnimator="@animator/zoom_out_animator">...</layout>
<!-- res/animator/zoom_out_animator -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<set>
<objectAnimator
android:propertyName="scaleX"
android:valueTo="1.0"
android:duration="@android:integer/config_shortAnimTime"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
<objectAnimator
android:propertyName="scaleY"
android:valueTo="1.0"
android:duration="@android:integer/config_shortAnimTime"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</set>
</item>
<item android:state_pressed="true">
<set>
<objectAnimator
android:propertyName="scaleX"
android:valueTo="0.9"
android:duration="@android:integer/config_shortAnimTime"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
<objectAnimator
android:propertyName="scaleY"
android:valueTo="0.9"
android:duration="@android:integer/config_shortAnimTime"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</set>
</item>
</selector>
您还可以在官方 material 示例应用中找到示例 Owl. Take a look at onboarding_topic_item.xml。
几个类似的问题:
- To increase a button's size when it is pressed in Android
我想要创建一个按钮,在按下时改变大小(稍微小一点),再次释放按钮后,大小应该变回正常 size.I 我正在使用 Scale xml 来实现这一点,但即使我不释放按钮,它也会重新定位自己。
按钮这里我指的是imageview。
这是我的源代码:-
imgSpin = (ImageView) findViewById(R.id.iv_spins);
imgSpin.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
imgSpin.startAnimation(mAnimation);
spinslot();
break;
case MotionEvent.ACTION_UP:
imgSpin.clearAnimation();
imgSpin.setEnabled(false);
break;
}
return true;
}
});
我的体重秤Xml:-
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200"
android:fromXScale=".8"
android:fromYScale=".8"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0" >
</scale>
我的XML:-
<LinearLayout
android:id="@+id/layout_status"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".2"
android:orientation="horizontal" >
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5" />
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2.1"
android:background="@drawable/bootser" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2.5"
android:background="@drawable/bet_bg"
android:gravity="center_vertical"
android:orientation="horizontal"
android:weightSum="1" >
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_weight=".2"
android:src="@drawable/leftarrow" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:layout_weight=".6"
android:gravity="center"
android:text="Bet"
android:textColor="@android:color/white" />
<ImageView
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_weight=".2"
android:src="@drawable/rightarrow" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2.5"
android:background="@drawable/container"
android:gravity="center" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="winning"
android:textColor="@android:color/white" />
</LinearLayout>
<ImageView
android:id="@+id/iv_spins"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.9"
android:background="@drawable/spin" />
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5" />
</LinearLayout>
我尝试使用 paramLayout,但是当我在 XML 中设置权重时,它不会给我带来动画效果。
我已经在使用这种方法了:-
case MotionEvent.ACTION_DOWN:
ViewGroup.LayoutParams params = imgSpin.getLayoutParams();
// Button new width
params.width = params.width - (params.width *90/100);
imgSpin.setLayoutParams(params);
break;
params.width 总是 return 我零 所以我试着用重量来做这个,通过使用重量我的视图在点击时出现故障..我想要它平滑所以我更喜欢缩放
第二种方法:-
case MotionEvent.ACTION_DOWN:
LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) imgSpin
.getLayoutParams();
// Button new width
params.weight = 1.7f;
imgSpin.setLayoutParams(params);
// imgSpin.startAnimation(mAnimation);
// spinslot();
break;
case MotionEvent.ACTION_UP:
LinearLayout.LayoutParams params2 = (android.widget.LinearLayout.LayoutParams) imgSpin
.getLayoutParams();
// Button new width
params2.weight = 1.9f;
imgSpin.setLayoutParams(params2);
// imgSpin.clearAnimation();
imgSpin.setEnabled(false);
break;
}
return true;
可以但不流畅
请告诉我怎么做
谢谢
你可以添加 fillafter 属性: android:fillAfter="true"
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200"
android:fromXScale=".8"
android:fromYScale=".8"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="true"
android:toXScale="1.0"
android:toYScale="1.0" >
</scale>
这是你想要的:-
imgSpin.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
ObjectAnimator scaleDownX = ObjectAnimator.ofFloat(imgSpin,
"scaleX", 0.8f);
ObjectAnimator scaleDownY = ObjectAnimator.ofFloat(imgSpin,
"scaleY", 0.8f);
scaleDownX.setDuration(1000);
scaleDownY.setDuration(1000);
AnimatorSet scaleDown = new AnimatorSet();
scaleDown.play(scaleDownX).with(scaleDownY);
scaleDown.start();
spinslot();
break;
case MotionEvent.ACTION_UP:
ObjectAnimator scaleDownX2 = ObjectAnimator.ofFloat(
imgSpin, "scaleX", 1f);
ObjectAnimator scaleDownY2 = ObjectAnimator.ofFloat(
imgSpin, "scaleY", 1f);
scaleDownX2.setDuration(1000);
scaleDownY2.setDuration(1000);
AnimatorSet scaleDown2 = new AnimatorSet();
scaleDown2.play(scaleDownX2).with(scaleDownY2);
scaleDown2.start();
imgSpin.setEnabled(false);
break;
}
return true;
}
});
只需在您的 xml 中进行以下几项更改即可:-
<ImageView
android:id="@+id/iv_spins"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.9"
android:adjustViewBounds="true"
android:background="@drawable/spin"
android:scaleX="1"
android:scaleY="1" />
利用scaleDown.play(scaleDownX).with(scaleDownY),它会保持动画位置,不会恢复到原来的位置
希望它能解决您的问题 干杯
<ImageView
android:id="@+id/iv_spins"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.9"
android:adjustViewBounds="true"
android:background="@drawable/spin"
android:scaleX="1"
android:scaleY="1"
/>
在 /res/animator
中创建两个 XMLreduce_size.xml
<?xml version="1.0" encoding="utf-8"?> <set android:ordering="sequentially" xmlns:android="http://schemas.android.com/apk/res/android"> <set> <objectAnimator android:propertyName="scaleX" android:duration="300" android:valueTo="0.9f" android:valueType="floatType"/> <objectAnimator android:propertyName="scaleY" android:duration="300" android:valueTo="0.9f" android:valueType="floatType"/> </set> </set>
regain_size.xml
<?xml version="1.0" encoding="utf-8"?> <set android:ordering="sequentially" xmlns:android="http://schemas.android.com/apk/res/android"> <set> <objectAnimator android:propertyName="scaleX" android:duration="1000" android:valueTo="1f" android:startOffset="300" android:valueType="floatType"/> <objectAnimator android:propertyName="scaleY" android:duration="1000" android:valueTo="1f" android:startOffset="300" android:valueType="floatType"/> </set> </set>
用法
在
MotionEvent.ACTION_DOWN
AnimatorSet reducer = (AnimatorSet) AnimatorInflater.loadAnimator(mContext,R.animator.squeeze_in); reducer.setTarget(view); reducer.start();
在
MotionEvent.ACTION_UP
AnimatorSet regainer = (AnimatorSet) AnimatorInflater.loadAnimator(mContext,R.animator.squeeze_out); regainer.setTarget(view); regainer.start();
您可以在 touchlistener 上以编程方式执行此操作,如下所示
new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction == MotionEvent.ACTION_DOWN) {
// scale your value
float reducedvalue = (float)0.7;
v.setScaleX(reducedvalue);
v.setScaleY(reducedvalue);
}
else if (event.getAction == MotionEvent.ACTION_UP) {
v.setScaleX(1);
v.setScaleY(1);
}
}
}
很简单,但是你得知道AndroidAPI是如何处理每个监听器的调用的。
技巧如下:
1- onTouch 方法在 TouchListener 将首先被调用。
1.1- 如果 onTouch 方法 returns 为真,那么 onLongClick(in LongClickListener) 或 onClick(in ClickListener) 将被忽略(两者都不会再被调用)。
2- 如果 onTouch 方法 returns 为假,则检查 onLongClick returns 是否为真所以 onClick 不会被调用,但如果它 returns false 那么 onClick 也会被调用。
这是一个例子:
targetButton.setOnLongClickListener(v -> {
targetButton.animate().scaleX(1.2f).scaleY(1.2f).setDuration(0);
Log.d("Button", "onLong: ");
return true;
});
targetButton.setOnClickListener(v -> {
Log.d("Button", "onClick: ");
});
targetButton.setOnTouchListener((v, event) -> {
Log.d("Button", "onTouch: ");
if (event.getAction() == MotionEvent.ACTION_UP) {
recordButton.animate().scaleX(1.0f).scaleY(1.0f).setDuration(0);
}
// if you want to make it pretty increase the size when click also
/* else if (event.getAction() == MotionEvent.ACTION_DOWN) {
targetButton.animate().scaleX(1.2f).scaleY(1.2f).setDuration(0);
} */
return false;
});
在这个例子中,如果我检测到长按,我试图增加按钮的大小,否则在 onClick 方法中做一些事情,如果用户释放按钮我再次缩小尺寸。
如果您希望每次调用 onLongClick 时调用 onClick,只需使 onLongClick returns 错误;
自 API 21 (Lollipop) 以来,基于 stateListAnimator 属性,可以使用仅 xml 的解决方案。这是一个布局示例,在按下时缩放到其原始大小的 0.9:
<!-- res/layout/my_layout.xml -->
<LinearLayout ...
android:stateListAnimator="@animator/zoom_out_animator">...</layout>
<!-- res/animator/zoom_out_animator -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<set>
<objectAnimator
android:propertyName="scaleX"
android:valueTo="1.0"
android:duration="@android:integer/config_shortAnimTime"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
<objectAnimator
android:propertyName="scaleY"
android:valueTo="1.0"
android:duration="@android:integer/config_shortAnimTime"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</set>
</item>
<item android:state_pressed="true">
<set>
<objectAnimator
android:propertyName="scaleX"
android:valueTo="0.9"
android:duration="@android:integer/config_shortAnimTime"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
<objectAnimator
android:propertyName="scaleY"
android:valueTo="0.9"
android:duration="@android:integer/config_shortAnimTime"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</set>
</item>
</selector>
您还可以在官方 material 示例应用中找到示例 Owl. Take a look at onboarding_topic_item.xml。
几个类似的问题:
- To increase a button's size when it is pressed in Android