user2999943
user2999943

Reputation: 2519

Google maps v2 fragment view flickers when changing it's width

My app contains Google maps v2 API fragment view. On button click I want to change it's width from left to right side like this: Google map taking half screen --> Google map taking full screen.

It works, But I see strange black area on the right side of the screen during width transition. I have read that it's Google bug and that they released fix for this but it only works since Android 4.1 version. I am using Android 4.0

Also I checked some workarounds mentioned by another people but all of them focuses on tasks such like scrolling, etc. Nobody is mentioning google maps view width change.

Anybody can help me?

My xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/mainLayout"     
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<fragment
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="510dp"       
    android:layout_height="match_parent"
    android:layout_marginLeft="10dp"           
    android:layout_marginTop="10dp" />

<ImageView
    android:id="@+id/mapExpandButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    android:layout_marginBottom="25dp"
    android:layout_marginRight="510dp"
    android:background="@drawable/map_expand" />

<ImageView
    android:id="@+id/mapCloseButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="25dp"
    android:layout_marginLeft="15dp"
    android:background="@drawable/map_close" />

Google maps init:

        mapFragment = (SupportMapFragment)getActivity().getSupportFragmentManager().findFragmentById(R.id.map);
        map = mapFragment.getMap ();
        map.getUiSettings().setRotateGesturesEnabled(false);    // disable rotation         
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(54.6873439, 25.2770559) , 16.0f));  // set initial position         
        map.getUiSettings().setZoomControlsEnabled(false);

On "expand" button click, I am expanding google map like this:

ResizeWidthAnimation anim = new ResizeWidthAnimation(mapFragment.getView (), width);
anim.setDuration(400);
mapFragment.getView ().startAnimation(anim);

Animation class:

 public class ResizeWidthAnimation extends Animation
 {
  private int mWidth;
  private int mStartWidth;
  private View mView;

public ResizeWidthAnimation(View view, int width)
{
    mView = view;
    mWidth = width;
    mStartWidth = view.getWidth();
}

@Override
protected void applyTransformation(float interpolatedTime, Transformation t)
{
    int newWidth = mStartWidth + (int) ((mWidth - mStartWidth) * interpolatedTime);

    mView.getLayoutParams().width = newWidth;
    mView.requestLayout();

}

@Override
public void initialize(int width, int height, int parentWidth, int parentHeight)
{
    super.initialize(width, height, parentWidth, parentHeight);
}

@Override
public boolean willChangeBounds()
{
    return true;
}
}

Upvotes: 5

Views: 2221

Answers (2)

user2999943
user2999943

Reputation: 2519

We solved this issue by adding a view on top of the map and animating this view width change. Nothing else worked.

Tips to avoid Google map flickering bug:

  1. Don't do "add" or "replace" operations with the fragment which contains Google map fragment inside. Instead, use show/hide operations with fragment view. This will not recreate already created fragment when you use these operations. For example:

    FragmentManager manager = getSupportFragmentManager();  
    FragmentTransaction ft1 = manager.beginTransaction();
    ft1.show (someFragment);
    ft1.hide (someFragment2);
    ft1.commit();   
    
  2. During app execution, don't try to change google map fragment dimension parameters (width, height, margin, etc.) at all. Search workarounds by using another (additional) views if you need some google map animations, width changes, etc.

Upvotes: 2

BladeCoder
BladeCoder

Reputation: 12929

Relayouting on each frame of your animation is very expensive (even more for a map) and you should not do that. If you really want to animate the bounds of your map, try to apply a scale animation, then at the end of it, relayout your View to its final new dimensions and disable scaling.

To improve animation performance using a map or any other SurfaceView, you can call requestTransparentRegion() on the MapFragment container, passing itself as argument.

Upvotes: 0

Related Questions