0

I'm working on googlemap carousel (pager) project and need to show google map inside complex layout, but every time I move the pager, mapfragment is not loading. if I flip back, the map suddenly appear. Here is my code:

MainActivity

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerTabStrip;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.*;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import java.util.ArrayList;

public class MainActivity extends FragmentActivity {
    static final LatLng HAMBURG = new LatLng(53.558, 9.927);
    static final LatLng KIEL = new LatLng(53.551, 9.993);
    private GoogleMap map;
    private ArrayList<MarkerOptions> mMarkers;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
        viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));


    }


}

class MyMapFragment extends SupportMapFragment {
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        GoogleMap map = getMap();

        if (savedInstanceState == null) {
            CameraUpdate center =
                    CameraUpdateFactory.newLatLng(new LatLng(40.76793169992044,
                            -73.98180484771729));
            CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);

            map.moveCamera(center);
            map.animateCamera(zoom);
        }

        addMarker(map, 40.748963847316034, -73.96807193756104);
        addMarker(map, 40.76866299974387, -73.98268461227417);
        addMarker(map, 40.765136435316755, -73.97989511489868);
        addMarker(map, 40.70686417491799, -74.01572942733765);
        setRetainInstance(true);
    }

    private void addMarker(GoogleMap map, double lat, double lon) {
        map.addMarker(new MarkerOptions().position(new LatLng(lat, lon)));

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.ttt, null);
        getActivity().getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.map_layout, newInstance())
                .commit();
        return view;
    }
}

class MyPagerAdapter extends FragmentStatePagerAdapter {

    public MyPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        return new MyMapFragment();  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public int getCount() {
        return 10;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public String getPageTitle(int position) {
        return ("page " + String.valueOf(position + 1));
    }
}

class MapAwarePager extends ViewPager {
    public MapAwarePager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected boolean canScroll(View v, boolean checkV, int dx, int x,
                                int y) {
        if (v instanceof SurfaceView || v instanceof TextureView || v instanceof PagerTabStrip) {
            return (true);
        }

        return (super.canScroll(v, checkV, dx, x, y));
    }
}

and main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
        >
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Hello World, MainActivity"
            />
    <view android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          class="com.spot.maps.MapAwarePager" android:id="@+id/view_pager"/>
</LinearLayout>

and ttt.xml where I have place for fragment:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <EditText
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:text="New EditText"
            android:id="@+id/editText" android:layout_gravity="left|center_vertical" android:layout_weight="1"/>
    <FrameLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" android:layout_gravity="left|center_vertical" android:layout_weight="1"
            android:id="@+id/map_layout">
    </FrameLayout>
    <Button
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:text="New Button"
            android:id="@+id/button" android:layout_weight="1"/>
</LinearLayout>

And my Mainfest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.spot.maps"
          android:versionCode="1"
          android:versionName="1.0">
    <uses-sdk android:minSdkVersion="10"/>
    <permission
    android:name="com.spot.maps.permission.MAPS_RECEIVE"
    android:protectionLevel="signature" />
    <uses-feature
            android:glEsVersion="0x00020000"
            android:required="true" />
    <uses-permission android:name="com.spot.maps.permission.MAPS_RECEIVE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!--<uses-permission android:name="android.permission.INTERNET"/>-->
    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:hardwareAccelerated="true">

        <activity android:name="MainActivity"
                  android:screenOrientation="portrait"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <meta-data
                android:name="com.google.android.maps.v2.API_KEY"
                android:value="AIzaSyChbP6k9pnX4kLoTnOfXHFJK5Y_nM1wSqQ" />
    </application>
</manifest>

I put THIS VIDEO for better understanding.

Hope you can help me.

1 Answers1

0

Viewpager runtime is hard to nail down , leaving lots of room for unexpected results.

Note the adapter for the pager. Lots of examples use an inner-class to implement.

Note 2 general types of adapters used in ViewPagers

Note that either adapter can bind an instance of ArrayList to the view and that a completely different way can be used to load the ViewPager framework. INSTEAD of iterating your calls on the FragmentTransaction, you can simply add fragments to the ArrayList object in the adapter before calling adapter.notifyDataSetChanged(). The ViewPager should automatically manage memory and manage keeping only the most relevant of your mapViews in memory from the much larger ArrayList object.

see example of that last idea

Short answer:

Load your fragment adapter via the ArrayList object and then call "onNotifyDataSetChanged()" as in many samples...

Community
  • 1
  • 1
Robert Rowntree
  • 6,056
  • 2
  • 22
  • 41