0

Strange behavior when rotating a layout (e.g. a FrameLayout) with an image view inside, on different Android versions.

Take a look at the following piece of XML layout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000" >

    <FrameLayout
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:background="#ffffff"
        android:layout_gravity="center"
        android:rotation="15" >

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@drawable/bg" />

    </FrameLayout>

</FrameLayout>

The following will display good results on Android 4.3 and 4.4, but strange result on Android 4.2, 4.1, 4.0.3.

On Android 4.2 (bad result)

enter image description here

on Android 4.3 (good result)

enter image description here

Anyone knows why this happens prior to Android 4.3 and how to fix it ?

Thanks !

  • Try to switch to property-based animations (http://developer.android.com/guide/topics/graphics/prop-animation.html) from view animations (http://developer.android.com/guide/topics/graphics/view-animation.html). I had a somewhat similar issue and it was resolved by this switch. – aga Oct 05 '14 at 19:36
  • Thanks, but this is not animation related. Its just a static layout that I want to rotate everything within. – The Great Descartes Oct 06 '14 at 06:11
  • @TheGreatDescartes Have you tried it on a real device? could be an emulator problem. Have you also tried to set it via code, or actually ditch the inner FrameLayout and just rotate the imageView instead (or its content) ? Here are some ways to rotate things: http://stackoverflow.com/questions/1930963/rotating-a-view-in-android . BTW, about animations, starting with Honeycomb, this is actually how animation works : the value of the rotation field changes as the animation runs, and they are both sync-ed . – android developer Oct 08 '14 at 11:43
  • @androiddeveloper Yes, the problem occur on real device. I tried on an emulator to see if its a device problem or not and test for earlier versions. I need it inside a frame layout because I put additional layers and want to rotate everything together. I can try doing it by code but from my experience it always have some performance impacts. If I could atleast find the issue itself on Google, I may be able to take a peek at the source and see what was fixed... However I cannot find it. – The Great Descartes Oct 08 '14 at 19:00
  • @TheGreatDescartes using code is just a single line, and it's very easy. just use "setRotation" on the view/layout you wish to set its rotation: http://developer.android.com/reference/android/view/View.html#setRotation(float) . it should be equivalent to using XML. – android developer Oct 08 '14 at 22:24
  • @TheGreatDescartes OK, I've just made an exact copy of your layout, and I've ran it on a 4.0 emulator, and it works fine. Maybe you forgot to post some other useful information? have you tried making a totally new project and put this layout inside of it? Here's what I see when launching it: http://postimg.org/image/vpvnypu1l/ . Maybe you didn't set the "targetSdkVersion" to the latest version (currently 19), including in the "project.properties" file? – android developer Oct 08 '14 at 22:39

1 Answers1

0

Seems like I couldn't reproduce the problem since I didn't enable "use GPU host".

Anyway, here's a way to overcome this, even if this feature its enabled :

set android:layerType="software" for the imageView .

I hope you don't need to animate, since this attribute affects the performance.

In order to make it work better (at least for newer Android versions), I suggest making a resource that will be "software" for up to the problematic version (including), and "hardware" from above it.

I've tried other methods of handling it, but they don't work well.

You might be able to reset the layerType at runtime, so you'll get it working well after all. For me it worked.

just call:

  @Override
  protected void onCreate(final Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViewById(R.id.imageView1).setLayerType(View.LAYER_TYPE_HARDWARE,null);
    }
android developer
  • 114,585
  • 152
  • 739
  • 1,270