3

There are several stack overflow questions that deal with keeping the activity in a constant orientation, suggesting either to set android:screenOrientation (or this) or to deal with the configuration changes manually.

However, these answers do not solve the problem if one wants to keep the benefits of automatic layout for most of the views, but to keep one view in a constant orientation. For example I have one main view for the content (a bitmap) and optionally several "toolbars". When the device is rotated from portrait to landscape, I want the toolbars to re-layout automatically. On the other hand, the main content view has a bitmap, and this should rotate with the device. Here is a simple code I use in my 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);
        }
    }

This obviously does not work as intended because when the device orientation changes, the view is relayout and its coordinate system rotates in this orientation change by 90 degrees with respect to the physical device. One way to compensate for that would be to use a Matrix-object to draw the bitmap with 90 degrees rotation if the device orientation has changed. However, then also the input coordinates would have to be changed in order to keep the view input points and the point on the bitmap in correspondence.

Therefore my question after this long explanation is: can I keep the view so that its coordinate system with respect to the device is not rotated when the orientation changes.

Here is a picture that expresses what I want and what I currently get (xy coordinate system for the view also illustrated).

enter image description here

Community
  • 1
  • 1
HYS
  • 771
  • 6
  • 11
  • 1
    Use 2 layout xmls .. One for Portarait and one for landscape.. To make it effecient use just the toolbar as a different layout and the rest in a Fragment. That way you only need the xml with the toolbar as 2 files.. – ngesh Dec 25 '13 at 10:21
  • just add android:screenOrientation="portrait" in that perticular activity in manifest.xml. You will get what you want. :) – Subhalaxmi Dec 25 '13 at 10:29
  • @HYS if you got your solution , its gud . If not you can share the error :) – Subhalaxmi Dec 25 '13 at 10:54
  • @subhalaxminayak The android:screenOrientation="portrait" is not a solution, because it seems to keep the whole screen in the portrait mode. I want the other views to be re-layout for the landscape, only the bitmap view to keep in portrait. Thanks. – HYS Dec 25 '13 at 11:03
  • @HYS You want to keep constant the image only ?? – Subhalaxmi Dec 25 '13 at 12:14
  • @subhalaxminayak Yes, that is my wish. I am sorry if the question perhaps is too long winded or unclear, as many answers did not seem to get this point. – HYS Dec 25 '13 at 12:41
  • @HYS Did you solve this problem? – Yuliya Tarasenko May 28 '14 at 09:13
  • @YuliyaTarasenko Not solved in a clean way. Currently I keep track of the orientation, then do the bitmap blitting with proper rotation (0, 90, 180 or 270 degrees), and likewise recalculate the input coordinates. This is a mess, and I do not feel comfortable with it. I will change the behaviour so that at every orientation change I will recalculate the bitmap, so that it can always be blitted with 0 degrees rotation. Then the input coordinates at least will be easier to handle. – HYS May 29 '14 at 12:12

5 Answers5

2

Inside your activity in manifest xml use the screen orientation attribut with portrait value

Like

 <activity
        android:name=".YourActivityName"
        android:screenOrientation="portrait" >
    </activity>
Wajdi Hh
  • 785
  • 3
  • 9
  • Normally it will work like your screen shot , if not the case , we will try other think – Wajdi Hh Dec 25 '13 at 10:28
  • can you explain your answer?? – Sanket Shah Dec 25 '13 at 10:31
  • in your manifest , you declared this activity that's contain this toolbar and image, so juste in this declaration add this attribut android:screenOrientation="portrait" ti fix the screen orientation. It's okay ? – Wajdi Hh Dec 25 '13 at 10:33
  • @Andrain Try and than post comment. Without testing how you can say it will not work. As per the Question Asked here this above answer is perfect..test and post comment :) – Subhalaxmi Dec 25 '13 at 10:52
  • ngesh is right. i have tested it. better is that test your answer before post. @subhalaxminayak – Sanket Shah Dec 25 '13 at 10:56
  • When seeing this answer, I was beating myself for not having tried it before. But unfortunately after trying it I see that this is not the good solution. This will just lock the whole screen into one orientation. I wish it would have been this easy ;) – HYS Dec 25 '13 at 11:07
1

I am not sure but you should try following

  1. put one xml in layout folder which indicate portrait layout
  2. create one folder named it layout-land
  3. put xml which indicate landscape layout with same name as in layout folder

Android automatically take that layout from land-layout when you will rotate your screen to landscape.

Another way

Activity will be restarted when orientation is changed so make to layout for that activity and you can set layout to your activity as per orientation.

if (getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE)
{
   setContentView(R.layout.landscape_layout);
}
else
{
   setContentView(R.layout.portrait_layout);
}

Hope it will help you.

Sanket Shah
  • 4,352
  • 3
  • 21
  • 41
0

You can check the orientation and redraw your View after orientation will be changed

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

Use this code in your Manifest

<uses-permission android:name="android.permission.SET_ORIENTATION"/>
<activity
        android:name="com.package.MyActivity"
        android:configChanges="keyboardHidden|orientation"
        android:screenOrientation="portrait" >
    </activity>
learner
  • 3,092
  • 2
  • 21
  • 33
0

Well, first of all, you will not need two layouts. Create only one xml with an image view and a layout which has property align parent bottom set to true.

Now as per the images you have provided, you want to rotate the image anticlockwise when your device is in landscape. For that , you can use my image rotation code :-

You can always check the rotation of the image using Matrix and rotate it accordingly.

This code goes in onCreate--> The code below is to rotate the image when taken from camera or gallery. You can modify according to your needs. I have put comments below to simplify understanding.

        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;    
     }
Rahul Gupta
  • 5,275
  • 8
  • 35
  • 66