Android:通过角度旋转ImageView中的图像

190

我正在使用以下代码旋转ImageView中的图像角度。 是否有更简单和不那么复杂的方法可用。

ImageView iv = (ImageView)findViewById(imageviewid);
TextView tv = (TextView)findViewById(txtViewsid);
Matrix mat = new Matrix();
Bitmap bMap = BitmapFactory.decodeResource(getResources(),imageid);
mat.postRotate(Integer.parseInt(degree));===>angle to be rotated
Bitmap bMapRotate = Bitmap.createBitmap(bMap, 0, 0,bMap.getWidth(),bMap.getHeight(), mat, true);
iv.setImageBitmap(bMapRotate);

6
对于2014年的PS版本,在Android Studio中,似乎可以直接在XML中设置“rotation”属性。(如果你不想使用“Text”布局,甚至可以直接点击右侧的“高级属性”按钮!) - Fattie
在这里找到答案。 - Geet Thakur
28个回答

3
我有一个解决方案。 实际上,它是解决旋转后矩形图像不适合ImagView而产生的问题的解决方案,但它也可以解决你的问题。 虽然这个解决方案包含动画,好的或者不好的。
    int h,w;
    Boolean safe=true;

在活动初始化时获取imageView的参数是不可能的。 要这样做,请参考这个解决方案 或者在单击按钮时设置尺寸,像这样

    rotateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(imageView.getRotation()/90%2==0){
                h=imageView.getHeight();
                w=imageView.getWidth();

            }
        .
        .//Insert the code Snippet below here 
       }

当我们需要旋转ImageView时要运行的代码

if(safe)     
imageView.animate().rotationBy(90).scaleX(imageView.getRotation()/90%2==0?(w*1.0f/h):1).scaleY(imageView.getRotation()/90%2==0?(w*1.0f/h):1).setDuration(2000).setInterpolator(new LinearInterpolator()).setListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {
                      safe=false;
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                      safe=true;

                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            }).start();
        }
    });

这个解决方案足以解决上述问题。虽然它会使imageView缩小,即使这并不必要(当高度小于宽度时)。如果这困扰了您,您可以在scaleX/scaleY内再添加一个三元运算符。

3
我认为这是最好的方法 :)
int angle = 0;
imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            angle = angle + 90;
            imageView.setRotation(angle);
        }
    });

我们可以在旋转时设置锚点吗? - gumuruh

3
你可以简单地使用 ImageView 的旋转属性。 下面是 Android 源代码中包含详细信息的 ImageView 属性。
<!-- rotation of the view, in degrees. -->
<attr name="rotation" format="float" />

2

回答有点晚了,但希望对某些人有用。我遇到了这样一种情况:需要在第一个ClickListener事件中通过一定的angle来使ImageView旋转动画,然后在第二个ClickListener事件中将图像rotate回原始角度。以下是实现这个魔法的方法:

fun rotateAnim(imageView: ImageView,angle : Float){
    imageView.isEnabled = false
    Log.i(TAG, "onCreate: ${imageView.rotation}")
    val rotation = imageView.animate().rotationBy(angle)
    rotation.interpolator = FastOutSlowInInterpolator()
    rotation.startDelay = 200
    rotation.setListener(object : Animator.AnimatorListener{
        override fun onAnimationEnd(animation: Animator?) {
           imageView.isEnabled = true
        }
        override fun onAnimationStart(animation: Animator?) {}
        override fun onAnimationCancel(animation: Animator?) {}
        override fun onAnimationRepeat(animation: Animator?) {}

    })
    rotation.start()
}

实现就像这样

holder.itemView.setOnClickListener {
    val rotation = imageView.rotation
    if(rotation == 180F){
         rotateAnim(imageView,90F)
    }else{
         rotateAnim(imageView,-90F)
    }
}

2
这里有一个不错的解决方案,可以为imageView添加旋转的可绘制对象:
Drawable getRotateDrawable(final Bitmap b, final float angle) {
    final BitmapDrawable drawable = new BitmapDrawable(getResources(), b) {
        @Override
        public void draw(final Canvas canvas) {
            canvas.save();
            canvas.rotate(angle, b.getWidth() / 2, b.getHeight() / 2);
            super.draw(canvas);
            canvas.restore();
        }
    };
    return drawable;
}

使用方法:

Bitmap b=...
float angle=...
final Drawable rotatedDrawable = getRotateDrawable(b,angle);
root.setImageDrawable(rotatedDrawable);

另一个选择:
private Drawable getRotateDrawable(final Drawable d, final float angle) {
    final Drawable[] arD = { d };
    return new LayerDrawable(arD) {
        @Override
        public void draw(final Canvas canvas) {
            canvas.save();
            canvas.rotate(angle, d.getBounds().width() / 2, d.getBounds().height() / 2);
            super.draw(canvas);
            canvas.restore();
        }
    };
}

此外,如果您希望旋转位图,但担心OOM(内存溢出),您可以使用我制作的一个NDK解决方案在这里


1

如果你只想在视觉上旋转视图,可以使用:

iv.setRotation(float)

1
很遗憾,我认为没有。无论是旋转、缩小/放大、扭曲等所有图像操作都由Matrix类负责。

http://developer.android.com/reference/android/graphics/Matrix.html

非常抱歉,我想不出其他的替代方案。也许其他人能够想到,但是在我需要操作图像的时候,我通常使用矩阵。

祝你好运!


1

使用 Kotlin:

imageView.rotation = degrees.toFloat()

1

在自定义视图上尝试这个

public class DrawView extends View {


    public DrawView(Context context,AttributeSet attributeSet){
        super(context, attributeSet);
    }

    @Override
    public void onDraw(Canvas canvas) {
        /*Canvas c=new Canvas(BitmapFactory.decodeResource(getResources(), R.drawable.new_minute1)    );

        c.rotate(45);*/

        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.new_minute1), 0, 0, null);
        canvas.rotate(45);
    }
}


1
如果您想将图像旋转180度,则在imageview标记中添加这两个值:
android:scaleX="-1"
android:scaleY="-1"

解释:scaleX = 1 和 scaleY = 1 表示它的正常状态,但如果我们在 scaleX/scaleY 属性上放置 -1,则会将其旋转180度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接