在Android中旋转一个视图

76

我有一个按钮,想要将它放在45度角上。但是不知道为什么我做不到。

有没有人能够提供代码来实现这个效果?


一个简单的解决方案,由@Michale回答,效果非常好 :) 一行XML代码 <View android:rotation="45" ... /> - Muahmmad Tayyib
你说得对,@Muahmmad。但是它只能帮助我们在xml中实现这个目标,如果我们想要动态地在按钮点击时执行它,那么它将无法起作用。 - Vivek Thummar
13个回答

74

3
setRotation() 是要使用的方法,并且本身就是答案。该链接只是为了方便而提供的。 - Jens Zalzala

60

您可以创建一个动画并将其应用于按钮视图。例如:

    // Locate view
    ImageView diskView = (ImageView) findViewById(R.id.imageView3);

    // Create an animation instance
    Animation an = new RotateAnimation(0.0f, 360.0f, pivotX, pivotY);

    // Set the animation's parameters
    an.setDuration(10000);               // duration in ms
    an.setRepeatCount(0);                // -1 = infinite repeated
    an.setRepeatMode(Animation.REVERSE); // reverses each repeat
    an.setFillAfter(true);               // keep rotation after animation

    // Aply animation to image view
    diskView.setAnimation(an);

很高兴看到通过动画和setFillAfter(true)可以实现无法通过定义布局完成的事情。 - Andras Balázs Lajtha
这将旋转视图,但按钮不会旋转其功能。对我来说并不是圣杯 :) - Warpzit
1
事实证明,没有任何方法可以旋转按钮的功能。最终,我根据屏幕被触摸的位置将事件转发到按钮。 - Warpzit

47

扩展TextView类并覆盖onDraw()方法。确保父视图足够大,能够处理旋转按钮而不会将其裁剪。

@Override
protected void onDraw(Canvas canvas) {
     canvas.save();
     canvas.rotate(45,<appropriate x pivot value>,<appropriate y pivot value>);
     super.onDraw(canvas);
     canvas.restore();

} 

好的,这有点完成了我的要求。我希望整个视图本身呈45度角。只是里面的文本不要倾斜。但还是谢谢你回答我的问题。 - Matthew
3
如果您想旋转整个视图(包括其背景),则应该覆盖draw()而不是onDraw()。 - Alexey
好的,如果使用draw()方法旋转整个按钮,但不能正确绘制视图。 - Kailash Dabhi
不需要保存整个画布状态,canvas.save(Canvas.MATRIX_SAVE_FLAG)就足够了。 - Denis Gladkiy

30

我只是在我的代码中使用了简单的一行代码,它起作用了:

myCusstomView.setRotation(45);

希望它能对你有用。

4
注:此方法自 API 11(蜂巢)起可用。 - nicopico
旋转视图(ImageView)后,是否可以保存带有该旋转的图像? - user512

27

XML中的一行


<View
    android:rotation="45"
    ... />

23

应用旋转动画(没有持续时间,因此没有动画效果)比调用View.setRotation()或覆盖View.onDraw方法更简单。

// substitude deltaDegrees for whatever you want
RotateAnimation rotate = new RotateAnimation(0f, deltaDegrees, 
    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);  

// prevents View from restoring to original direction. 
rotate.setFillAfter(true); 

someButton.startAnimation(rotate);

7
使用rotate()旋转视图不会影响视图的测量大小。结果是,旋转的视图可能被裁剪或不适合父布局。然而,这个库可以解决这个问题:https://github.com/rongi/rotate-layoutenter image description here

这是很好的工作,但如果控件比屏幕尺寸更宽怎么办?如何使其适应屏幕? - Alp Altunel

6

结合 @Rudi 和 @Pete 的回答,我创建了一个旋转动画,保持按钮功能在旋转后仍然可用。

setRotation() 方法可以保留按钮的功能。

代码示例:

Animation an = new RotateAnimation(0.0f, 180.0f, mainLayout.getWidth()/2, mainLayout.getHeight()/2);

    an.setDuration(1000);              
    an.setRepeatCount(0);                     
    an.setFillAfter(false);              // DO NOT keep rotation after animation
    an.setFillEnabled(true);             // Make smooth ending of Animation
    an.setAnimationListener(new AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {}

        @Override
        public void onAnimationRepeat(Animation animation) {}

        @Override
        public void onAnimationEnd(Animation animation) {
                mainLayout.setRotation(180.0f);      // Make instant rotation when Animation is finished
            }
            }); 

mainLayout.startAnimation(an);

mainLayout是一个(LinearLayout)字段。


3

如前所述,最简单的方法是使用API 11及以上版本提供的rotation

android:rotation="90"    // in XML layout

view.rotation = 90f      // programatically

您还可以更改旋转的轴心,默认情况下设置为视图的中心。这需要通过编程进行更改:
// top left
view.pivotX = 0f
view.pivotY = 0f

// bottom right
view.pivotX = width.toFloat()
view.pivotY = height.toFloat()

...

在Activity的onCreate()或Fragment的onCreateView(...)中,宽度和高度都等于0,因为视图尚未被测量。您可以使用Android KTXdoOnPreDraw扩展来访问它,例如:
view.apply {
    doOnPreDraw {
        pivotX = width.toFloat()
        pivotY = height.toFloat()
    }
}

2

如果您希望通过动画使其动态化:

view.animate()
    .rotation(180)
    .start();

这就是它


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