Pages

2013/07/25

Prevent flickering MapFragment on ViewPager in Android

If you add MapFragment(or SupportMapFragment) to ViewPager, there is some flickering(or blinking, the screen become black for a while) when the SupportMapFragment is initialized. See what happen to MapFragment in ViewPager :




In my case, I used SupportMapFragment for compatibility in Support ViewPager. The ViewPager consists of three fragments:

|Fragment #1| Fragment #2|Fragment Map|.

The map fragment is on the right. When I swipe to the right from the first fragment, whole screen is blinking for a while like the video. There is no blinking after loading the mapfragment first time.

This is an limitation of Android with using GLSurfaceView.
My solution is below:


// This FragmentActivity contains a ViewPager and the ViewPager has 3 fragments. 
// SupportMapFragment is one of them. 
public class GymDetailActivity extends SherlockFragmentActivity{
@Override
    public void onCreate(Bundle savedInstanceState) {
        /* ... */
        ViewPager pager = (ViewPager)findViewById(R.id.detail_main_pager);
        pager.setAdapter(adapter);
        
        pager.requestTransparentRegion(pager);  //This is the solution! 

    }
}

The problem may come again on some devices, but I think this is the best solution what ever I met before.

2013/06/26

Write & read parcelable array in parcelable object - how to in Android

When you pass object references to activities or fragments, you should put those in an Intent or Bundle. Intent or Bundle could be put every thing without boolean. You can put Integer, String, Float, Double, Long, various primitive type array and ArrayList of objects implements parcelable.

Parcelable is very useful and easy to use. It is similar to Serialize in Java, but very fast. Recently, I developed an Android application that shows gyms near the users. Of course, the gym data should be received from the server. How can the app hold huge data? The app and server communicates each other in JSON interface. JSON formatted data of a gym entity is below :

 
[
{
 "id": 5,
 "events": [
 {
  "type": "FITNESS",
  "price": 9000,
 },
 {
  "type": "GOLF",
  "price": 10000,
 },
 "name": "World Gym",
 "description": "World best fitness!"
},
......
]

There are many gyms information and each gym has several events information. Because those gyms information should be passed between activities or fragments, must be ArrayList which objects are parcelable implemented class.
import java.util.ArrayList;

import android.os.Parcel;
import android.os.Parcelable;

public class GymEntity implements Parcelable {
 private String name;
 private String description;
 
 public GymEntity(Parcel in) {
     readFromParcel(in);
 }

 @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
  dest.writeString(description);
 }
 
 public void readFromParcel(Parcel in){
  name = in.readString();
  description = in.readString();
 
 }
 
 public static final Parcelable.Creator<GymEntity> CREATOR = new Parcelable.Creator<GymEntity>() {
        public GymEntity createFromParcel(Parcel in) {
             return new GymEntity(in);
       }

       public GymEntity[] newArray(int size) {
            return new GymEntity[size];
       }
   };
   
   
 @Override
    public int describeContents() {
        return 0;
    }
 
}

And then, create a class for holding event data.
public class GymEventEntity implements Parcelable{

...

public static final Parcelable.Creator<GymEventEntity> CREATOR = new Parcelable.Creator<GymEventEntity>() {
        public GymEventEntity createFromParcel(Parcel in) {
             return new GymEventEntity(in);
       }

       public GymEventEntity[] newArray(int size) {
            return new GymEventEntity[size];
       }
   };
   
}

Add ArrayList to member of GymEntity class for holding events information.
private ArrayList<GymEventEntity> eventArray = new ArrayList<GymEventEntity>();

Add below to writeToParcel method to write ArrayList<GymEventEntity>.
dest.writeTypedList(eventArray);

Add Below to readToParcel method to write ArrayList<GymEventEntity>
in.readTypedList(eventArray, GymEventEntity.CREATOR);


Finished! Now you can read & write those array though Bundle or Intent. (access with getParcelableArrayList(key) or getParcelable(key) method)