Android如何在设备旋转时保持视图方向恒定

3
有许多Stack Overflow的问题涉及如何保持活动在一个固定的方向上,建议设置android:screenOrientation(或这个)或手动处理配置更改。然而,如果想让大多数视图自动布局的同时保持一个视图的方向不变,则这些答案无法解决该问题。例如,我有一个主要的内容视图(位图)和可选的几个“工具栏”。当设备从纵向旋转到横向时,我希望工具栏能够自动重新布局。另一方面,主要内容视图具有位图,并且应随设备旋转。以下是我在onDraw中使用的简单代码:
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Bitmap bm = ... // code to get a bitmap
        if (bm != null) {
            canvas.drawBitmap(bm,0,0,mPaint);
        }
    }

当设备方向改变时,视图重新布局并且其坐标系相对于物理设备旋转90度,因此这显然不能按预期工作。一种解决方法是使用Matrix对象来绘制具有90度旋转的位图,如果设备方向已更改。但是,输入坐标也必须更改以保持视图输入点和位图上的点对应,否则无法实现预期效果。
因此,我的问题在于:我能否使视图保持其相对于设备的坐标系在方向更改时不旋转?
下面是一个表达我想要的内容和我当前获得的内容的图片(也说明了视图的xy坐标系)。 enter image description here

1
使用两个布局xml文件,一个用于竖屏,一个用于横屏。为了提高效率,将工具栏作为单独的布局,并将其余部分放在片段中。这样,您只需要将带有工具栏的xml文件作为两个文件即可。 - ngesh
@HYS 如果你已经解决了问题,那很好。如果没有,你可以分享一下错误信息 :) - Subhalaxmi
@subhalaxminayak android:screenOrientation="portrait"不是解决方案,因为它似乎将整个屏幕保持在纵向模式。我希望其他视图能够重新布局以适应横向模式,只有位图视图保持纵向。谢谢。 - HYS
@HYS 你想要保持图像不变吗? - Subhalaxmi
@subhalaxminayak 是的,那是我的愿望。如果问题太冗长或不清楚,我很抱歉,因为许多答案似乎没有理解这一点。 - HYS
显示剩余3条评论
5个回答

2

在你的清单xml文件中,使用screen orientation属性,并将其设置为portrait值。

例如:

 <activity
        android:name=".YourActivityName"
        android:screenOrientation="portrait" >
    </activity>

通常情况下,它会像您的屏幕截图一样工作,如果不是这种情况,我们将尝试其他方法。 - Wajdi Hh
你能解释一下你的答案吗? - Sanket Shah
在您的清单文件中,您声明了这个包含工具栏和图像的活动,所以只需在此声明中添加此属性 android:screenOrientation="portrait" 以修复屏幕方向。可以吗? - Wajdi Hh
@Andrain 请先尝试再发表评论。没有测试怎么能说它不起作用呢?根据这里提出的问题,上面的答案是完美的... 测试后再发表评论 :) - Subhalaxmi
ngesh 是正确的。我已经测试过了。最好在发布前先测试您的答案。@subhalaxminayak - Sanket Shah
看到这个答案时,我为自己以前没有尝试过而感到遗憾。但不幸的是,尝试后我发现这不是一个好的解决方案。这只会将整个屏幕锁定在一个方向上。我希望它能这么简单 ;) - HYS

1
我不确定,但您应该尝试以下步骤:
1. 将一个XML文件放入布局文件夹,指示纵向布局。
2. 创建一个名为layout-land的文件夹。
3. 在layout文件夹中使用相同的名称放置指示横向布局的XML文件。
Android会自动从land-layout中获取布局,当您将屏幕旋转到横向时。
另一种方法是:
当方向更改时,Activity将被重新启动,因此请为该Activity制作两个布局,并根据方向设置布局。
if (getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE)
{
   setContentView(R.layout.landscape_layout);
}
else
{
   setContentView(R.layout.portrait_layout);
}

希望它能对你有所帮助。

0

您可以在方向更改后检查方向并重新绘制您的视图

if (getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE)
{
//...
}
else
{
//...
}

0
在你的Manifest文件中使用这段代码。
<uses-permission android:name="android.permission.SET_ORIENTATION"/>
<activity
        android:name="com.package.MyActivity"
        android:configChanges="keyboardHidden|orientation"
        android:screenOrientation="portrait" >
    </activity>

0
首先,您不需要两个布局。 只需创建一个带有图像视图和布局的xml,该布局具有属性align parent bottom设置为true。
现在根据您提供的图像,当您的设备处于横向时,您想将图像逆时针旋转。为此,您可以使用我的图像旋转代码:-
您始终可以使用Matrix检查图像的旋转情况,并相应地旋转它。
以下代码放在onCreate中-> 下面的代码是用于从相机或库中拍摄图像时旋转图像的代码。您可以根据需要进行修改。我已经放置了注释以简化理解。
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inPurgeable = true;

            Bitmap cameraBitmap = BitmapFactory.decodeFile(filePath);//You convert your image view image here in a bitmap
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            cameraBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);


            ExifInterface exif = new ExifInterface(filePath);
            float rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);  
            System.out.println(rotation);

            float rotationInDegrees = exifToDegrees(rotation);


            System.out.println(rotationInDegrees);
            //These three lines below set the rotation. 
            //Put an if condition here to check device rotation and set the rotation of image view as per the device rotation.
//The line below will help you get device rotation.    
//getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE
                Matrix matrix = new Matrix();
                matrix.postRotate(rotationInDegrees);//Here you set the rotation value in which you want your image view to be rotated
            //If ends here

            Bitmap scaledBitmap = Bitmap.createBitmap(cameraBitmap);
            Bitmap rotatedBitmap = Bitmap.createBitmap(cameraBitmap , 0, 0, scaledBitmap .getWidth(), scaledBitmap .getHeight(), matrix, true);
            FileOutputStream fos=new FileOutputStream(filePath);
            rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
                        //this rotatedbitmap you can set in your image view

//onCreate Code Ends here.

//This function below is used to get rotation:-

        private static float exifToDegrees(float exifOrientation) {        
        if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; } 
        else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {  return 180; } 
        else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {  return 270; }            
        return 0;    
     }

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