Android:ImageView旋转动画-保持比例类型适合中心 [英] Android: ImageView rotation animation - keep scale type fit center
问题描述
我有一个ImageView,其中有 android:scaleType = fitCenter
I have an ImageView that has android:scaleType="fitCenter"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="at.lukle.picturerotation.MainActivity">
<ImageView
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:src="@drawable/android"/>
<Button
android:id="@+id/btn_rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="rotate"/>
</RelativeLayout>
它看起来像这样:
< a href = https://i.stack.imgur.com/5FzuZ.png rel = nofollow noreferrer>
单击按钮时,我会应用旋转动画:
When the Button gets clicked, I apply a rotation animation:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnRotate = (Button) findViewById(R.id.btn_rotate);
final ImageView iv = (ImageView) findViewById(R.id.iv);
btnRotate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
iv.animate().rotationBy(90f).start();
}
});
}
}
现在看起来像这样:
图像在侧面被切割。我希望scaleType也适用于旋转的图像,以便ImageView不仅可以旋转,而且可以缩放以适合宽度。我想我也需要缩放动画,但是我不知道该怎么做。
The image gets cut on the side. I want that the scaleType is also applied on the rotated image, so that the ImageView not just gets rotated, but also scaled to fit the width. I guess I need a scaling animation too, but I have no idea how to do that.
我也尝试只使用 iv.setRotation( 90)
,但我在这里也遇到同样的问题...
I also tried to just use iv.setRotation(90)
, but I have the same problem here...
推荐答案
为此,请按照以下步骤操作步骤:
To do this follow these steps:
- 将
scaleType
设置为矩阵:
- set
scaleType
to matrix:
<ImageView ...
android:scaleType="matrix"/>
- 在onCreate,将图像加载到imageview并设置onClick侦听器的旋转按钮:
imageView.post(new Runnable() {
@Override
public void run() {
Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.dummy);
imageView.setImageBitmap(bitmap);
if (bitmap.getWidth() > 0) {
float scale = ((float)imageView.getMeasuredWidth())/((float)imageView.getDrawable().getIntrinsicWidth());
imageView.getLayoutParams().height = (int)(scale * imageView.getDrawable().getIntrinsicHeight());
imageView.setImageMatrix(scaleMatrix(scale, scale));
}
}
});
和
btnRotate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
animateImageHeight(imageView,btnRotate);
}
});
- 在活动中添加animateImageHeight方法:
void animateImageHeight(最终ImageView imageView,最终按钮btnRotate){
void animateImageHeight(final ImageView imageView, final Button btnRotate){
final float drawableWidth = imageView.getDrawable().getIntrinsicWidth();
final float drawableHeight = imageView.getDrawable().getIntrinsicHeight();
float viewWidth = imageView.getMeasuredWidth();
final float viewHeight = imageView.getMeasuredHeight();
final int rotation = imageRotation % 360;
final int newRotation = (rotation + 90);
final int newViewHeight;
final float imageScale;
final float newImageScale;
if (rotation==0 || rotation==180)
{
imageScale = viewWidth / drawableWidth;
newImageScale = viewWidth / drawableHeight;
newViewHeight = (int)(drawableWidth * newImageScale);
}
else if (rotation==90 || rotation==270){
imageScale = viewWidth / drawableHeight;
newImageScale = viewWidth / drawableWidth;
newViewHeight = (int)(drawableHeight * newImageScale);
}
else{
throw new UnsupportedOperationException("rotation can 0, 90, 180 or 270. ${rotation} is unsupported");
}
ValueAnimator animator= ValueAnimator.ofFloat(0f,1f) .setDuration(1000L);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
btnRotate.setEnabled(false);
}
@Override
public void onAnimationEnd(Animator animator) {
imageRotation = newRotation % 360;
btnRotate.setEnabled(true);
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float animVal = (float)animation.getAnimatedValue();
float complementaryAnimVal = 1 - animVal;
int animatedHeight =
(int)(complementaryAnimVal * viewHeight + animVal * newViewHeight);
float animatedScale =
(complementaryAnimVal * imageScale + animVal * newImageScale);
float animatedRotation =
(complementaryAnimVal * rotation + animVal * newRotation);
imageView.getLayoutParams().height=animatedHeight;
Matrix matrix=
rotationMatrix(
animatedRotation,
drawableWidth / 2,
drawableHeight / 2
);
matrix.postScale(
animatedScale,
animatedScale,
drawableWidth / 2,
drawableHeight / 2);
matrix.postTranslate(-(drawableWidth - imageView.getMeasuredWidth())/2, -(drawableHeight - imageView.getMeasuredHeight())/2);
imageView.setImageMatrix(matrix);
imageView.requestLayout();
}
});
animator.start();
}
您可以找到kotlin版本和完整的演示此处。
You can find the kotlin version and the complete demonstration here.
这篇关于Android:ImageView旋转动画-保持比例类型适合中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!