44

I have an app with several 'normal' activities which can run on either landscape or portrait. They are designed for and mostly used on portrait.

This app has one single activity which uses the camera and is locked on landscape. I 'simulate' this activity is on portrait by rotating images and texts 90 degree, so it looks like the rest of activities.

On some device, such as Samsung Galaxy Tab 7 and Galaxy S3, a rotation animation is shown when going from a normal portrait activity to camera landscape activity and back. This is confusing for user because landscape activity simulates being on portrait.

Is there a way to remove this rotation animation? Ideally I'd like to change to default portrait to portrait animation, but just removing rotation animation would be enough.

I've tried

overridePendingTransition(0, 0);

an other variations of that method without success.

[ADDED]

Following suggestions by @igalarzab, @Georg and @Joe, I've done this (still with no luck):

  • Added android:configChanges="orientation|screenSize" to Manifest
  • Added onConfigurationChanged
  • Created a dummy animation which does nothing and added overridePendingTransition(R.anim.nothing, R.anim.nothing);

I had these results:

  • onConfigurationChanged is called only when rotating same Activity (Activity A on portrait -> Activity A on landscape). But it's not called when going from Activity A on portrait -> Activity B on landscape
  • This prevented Activity from being restarted when rotating, but it did NOT removed rotation animation (tested on Galaxy S3, Galaxy Nexus, Galaxy Tab 7.0 and Galaxy Tab 10.1)
  • overridePendingTransition(R.anim.nothing, R.anim.nothing); removed normal transitions (portrait->portrait and landscape->landscape) but it didn't removed rotation animation (portrait->landscape and vice versa).

[VIDEO]

I've uploaded a video that shows animation I want to disable. This happens when changing from camera activity (locked to landscape) to other activity while holding phone on portrait:

http://youtu.be/T79Q1P_5_Ck

Jorge Cevallos
  • 3,667
  • 3
  • 25
  • 37
  • 1
    Hi, I will certainly be following this question, as we have a similar set up. I have also tried the overridePendingTransition and cannot remove the confusing animation. You may find my question on camera portrait mode reliability interesting (and I would be grateful for any input you may have) http://stackoverflow.com/questions/11638250/android-portrait-camera-reliability – Sam Aug 24 '12 at 17:37
  • I'll add there any input I have Sam. I haven't found any solution yet. – Jorge Cevallos Aug 27 '12 at 15:15
  • How about this http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NO_ANIMATION? – Gaurav Das Aug 29 '12 at 06:29
  • Why are you using iOS-like bottom tabs? Why don't you use the Action Bar? I know this is not related to your question but you should follow the design guidelines, IMHO. – Benoit Duffez Aug 28 '12 at 09:14
  • Thanks @Gaurav, but from my tests it seems to have same effect that overridePendingTransition(). It removes transition animation but not rotation. – Jorge Cevallos Aug 29 '12 at 14:38

10 Answers10

27

Sorry there is no way to control the rotation animation. This is done way outside of your app, deep in the window manager where it takes a screenshot of the current screen, resizes and rebuilds the UI behind it, and then runs a built-in animation to transition from the original screenshot to the new rebuilt UI. There is no way to modify this behavior when the screen rotation changes.

hackbod
  • 90,665
  • 16
  • 140
  • 154
  • Thanks @hackbod. I was afraid this was the case. Yes, it seems it's not possible to do. – Jorge Cevallos Aug 29 '12 at 14:39
  • 16
    @hackbod The native camera app handles orientation configuration changes and makes layout changes, but it doesn't have any lag or show a rotation animation. How is that app able to achieve that? – Jason Robinson Feb 06 '13 at 23:45
  • 5
    I think this answer is outdated now – Dmitry Zaytsev Sep 05 '14 at 11:07
  • @Jason Robinson, you are wrong. The native camera app does NOT change orientation at all, and so it doesn't need to change the rotation animation: it, instead, receives sensor data and process it to detect when orientation should change, then rotates the content view of the activity. You can see this by making the system UI appear by swiping down from the top of the screen: it'll not appear while landscape because it is at left, instead (or right when reverse landscape) – Davide Cannizzo Jan 20 '19 at 22:02
  • Samsung native camera APP can do this seamlessly. You can change status bar position without any animation of your layout. Camera preview stays untouched too. – Michal Zhradnk Nono3551 Dec 07 '21 at 16:07
24

This is the way how the stock camera app disables rotation animation:

private void setRotationAnimation() {
    int rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
    Window win = getWindow();
    WindowManager.LayoutParams winParams = win.getAttributes();
    winParams.rotationAnimation = rotationAnimation;
    win.setAttributes(winParams);
}

Note: According to API Reference and comment below, this only works:

  • On API level 18 or above
  • The FLAG_FULLSCREEN flag is set for WindowManager.LayoutParams of the Activity
  • The Activity is not covered by another window (e.g. the Power Off popup triggered by long pressing the Power button)
TactMayers
  • 884
  • 8
  • 22
martinpelant
  • 2,961
  • 1
  • 30
  • 39
3
android:rotationAnimation="seamless"

add this attribute in activity will reduce animation when rotate. I try to find it when i want to make smooth camera app

thaovd1712
  • 120
  • 1
  • 1
  • 9
2

You can set in the AndroidManifest a property called android:configChanges where you can decide which changes you want to manage in code. In this way, the rotation change animation will be disabled and you can handle it as you want in the method onConfigurationChanged of your Activity.

<activity
    android:name=".MySuperClass"
    android:label="@string/read_qrcode"
    android:screenOrientation="portrait"
    android:configChanges="orientation" />
igalarzab
  • 906
  • 8
  • 8
  • Thanks. However, I've tried this and 1) onConfigurationChanged is not called when going from activity a on landscape to activity b on portrait. It's only called when rotating from activity a on landscape to same activity a on portrait. 2) It seems rotation animation is now disabled, it only avoids activity being restarted, but animation stays (at least on S3, Galaxy Nexus and Galaxy Tab 7 and 10.1). – Jorge Cevallos Aug 27 '12 at 15:08
  • Sorry I'm not sure if I'm understanding correctly your problem... Maybe you can use `getResources().getConfiguration().orientation` to get the orientation of the device to handle the situation correctly and then rotate the images and text (when is necessary) like you said – igalarzab Aug 27 '12 at 19:40
  • I'm already rotating images and text. Only thing left is disabling automatic rotation animation added by Android. I've uploaded a video that shows this animation when changing Activities while holding phone on portrait: youtu.be/T79Q1P_5_Ck – Jorge Cevallos Aug 27 '12 at 19:59
  • Ok! Now I follow you... :) When requesting the camera activity send an extra intent with the screen orientation of the caller (get it with `getResources().getConfiguration().orientation`), and then use `setRequestedOrientation` to set the same orientation (and to avoid the animation). After that, you can decide to rotate the images and text or not depending on the selected orientation. – igalarzab Aug 27 '12 at 20:43
  • Unfortunately, due to some restrictions, I need Camera activity to be always on landscape. So I cannot set it to portrait even if previous activity was on that orientation. – Jorge Cevallos Aug 27 '12 at 20:51
  • I'm sorry, I don't have more ideas :( I search in the Android API but I didn't see anything to control the rotation animation directly... I think you will need to rebuild the idea – igalarzab Aug 28 '12 at 11:25
  • Thanks @igalarzab, it seems what I wanted to do is not possible. But I really appreciate your effort. I've awarded +50 bounty to you. – Jorge Cevallos Aug 30 '12 at 13:31
  • Oh, thank you very much! :) And I'm sorry you didn't find any valid solution... I hope you can do it in other way – igalarzab Aug 30 '12 at 15:21
1

I've put that in the mainActivity and it cancelled the rotation animation:

@Override
    public void setRequestedOrientation(int requestedOrientation) {
        super.setRequestedOrientation(requestedOrientation);

        int rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
        Window win = getWindow();
        WindowManager.LayoutParams winParams = win.getAttributes();
        winParams.rotationAnimation = rotationAnimation;
        win.setAttributes(winParams);

    }

More details here.

M. Sherbeeny
  • 109
  • 2
  • 12
0

You might have tried this already, but just in case:

Try defining a "do nothing" animation and call overridePendingTransition() with its id. Maybe something like:

    <set xmlns:android="http://schemas.android.com/apk/res/android" 
         android:fillAfter="true">
        <translate
            android:fromXDelta="0"
            android:toXDelta="0"
            android:duration="100" />
    </set>

Sorry, I didn't have a Galaxy device to test with :)

Joe
  • 14,039
  • 2
  • 39
  • 49
  • Thanks for your answer. I tried adding overridePendingTransition(R.anim.nothing, R.anim.nothing); after finish();, startActivity();, inside onCreate and onConfigurationChanged but rotation animation was not disabled (at least not on S3, Galaxy Nexus and Galaxy Tab 7 and 10.1). – Jorge Cevallos Aug 27 '12 at 15:15
  • I see. So it is happening on a Galaxy Nexus too? If that is the case, then maybe I can try it out on any AOSP ICS device, maybe even the emulator (since I believe the Galaxy Nexus has a stock AOSP software on it). I'll let you know if I find anything. – Joe Aug 27 '12 at 15:41
  • Yes. It happens on Galaxy Nexus too. It seems this animation is from ICS itself, not added by Samsung. Thanks. – Jorge Cevallos Aug 27 '12 at 16:03
-1

If you want to set your activities in portrait mode only you can do it in your manifest file like this

 <activity
     android:name=".Qosko4Activity"
     android:label="@string/app_name"
     android:screenOrientation="portrait" >
     <intent-filter>
         <action android:name="android.intent.action.MAIN" />
         <category android:name="android.intent.category.LAUNCHER" />
     </intent-filter>
 </activity>
igalarzab
  • 906
  • 8
  • 8
Rcp
  • 41
  • 7
  • Thanks you. However, I've already set my camera activity to landscape only and other activities should not be locked to portrait only. I now need to disable rotation animation. – Jorge Cevallos Aug 16 '12 at 14:48
-1

You can set in the AndroidManifest a property called android:configChanges where you can decide which changes you want to manage in code. In this way, the rotation change animation will be disabled and you can handle it as you want in the method onConfigurationChanged of your Activity.

This should work, but according to this page you should also add screenSize to configChanges by adding android:configChanges="orientation|screenSize" to your Activity Tag.

Georg
  • 960
  • 2
  • 7
  • 22
  • Thank you for your answer. I've tried this adding android:configChanges="keyboard|keyboardHidden|orientation|screenSize" on Manifest and @Override public void onConfigurationChanged(Configuration config) { ... on Java. However, when I go from Camera activity on landscape to other one on portrait, my onConfigurationChanged is not called. It's only called when I change orientation on same activity. – Jorge Cevallos Aug 27 '12 at 15:01
-1

Successfully checked on: Java - Android 9 (Pie) - Android Studio 4.1.3 - Huawei P10

For six months I could not solve this need. The problem was in the unassigned flag "FLAG_FULLSCREEN" in code.

First step MainActivity.java:

public class MainActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    /* getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN); */ // If the animation still is, try applying it.
    setRotationAnimation(); 
  }

  private void setRotationAnimation() {
    int rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
    Window win = getWindow();
    WindowManager.LayoutParams winParams = win.getAttributes();
    winParams.rotationAnimation = rotationAnimation;
    win.setAttributes(winParams); 
  }

  public void Button (View view) {
    // Connected to android:onClick="Button" in XML.
    Intent intent = new Intent(MainActivity.this, MainActivity2.class);
    startActivity(intent);
  }
}

Next step MainActivity2.java:

public class MainActivity2 {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);

    /* getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN); */ // If the animation still is, try applying it.
    setRotationAnimation(); 
  }

  private void setRotationAnimation() {
    int rotationAnimation = 
       WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
    Window win = getWindow();
    WindowManager.LayoutParams winParams = win.getAttributes();
    winParams.rotationAnimation = rotationAnimation;
    win.setAttributes(winParams); 
  }

  public void Button (View view) {
    Intent intent = new Intent(MainActivity2.this, MainActivity.class);
    startActivity(intent);
  }
}

Next step styles.xml:

<resources>
  <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
      <item name="android:windowFullscreen">true</item>
  </style>
</resources>

Simple things I understood: You must first anywhere start "setRotationAnimation()", before running activity2. When start activity2 you have to run in it "setRotationAnimation()". Works incorrectly.

Laytovy
  • 1
  • 2
-2

Against them who said no I say yes it is possible and it is very simple! The first thing may sound stupid but lock your application to the desired orientation! Then keep asking the gyrometer what orientation the device has an last but not least rotate or animate your views to the new orientation!

Edit: you may want to hide the system ui since it won't rotate. Mario

aichingm
  • 738
  • 2
  • 7
  • 15