I have a Fragment that contains a map, this map is loaded up on the callback and OnMapReady which pulls in a map at my location successfully.
However I am trying to add in a feature whereby the user selects a location from a Spinner and the selection then draws the relevant Polygon on my map, however I keep getting an error 'Attempting to invoke virtual method Polygon'
I am by no means a talented Android developer, trying to learn and play about somewhat.
public class FindCarpark extends Fragment {
private SupportMapFragment mapFragment;
private UserLocation.OnFragmentInteractionListener mListener;
Spinner spinCar;
String selectedItem;
GoogleMap mMap;
private static final ArrayList<LatLng> cpB = new ArrayList<>();
public FindCarpark() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_find_carpark, container, false);
Context context = getActivity().getApplicationContext();
spinCar = rootView.findViewById(R.id.car_spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this.getActivity(),R.array.car_parks, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
spinCar.setAdapter(adapter);
spinCar.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
if (i > 0) {
selectedItem = spinCar.getSelectedItem().toString().trim();
addCoords(selectedItem.toString());
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
if (mapFragment == null) {
mapFragment = SupportMapFragment.newInstance();
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap mMap) {
new googleMap().makeMap(mMap);
}
});
}
getChildFragmentManager().beginTransaction().replace(R.id.map, mapFragment).commit();
return rootView;
}
public void addCoords(String coords){
Log.i("coords", coords);
switch (coords){
case "B":
cpB.add(new LatLng(53.797731, -1.546351));
cpB.add(new LatLng(53.797551, -1.545983));
cpB.add(new LatLng(53.797447, -1.545267));
cpB.add(new LatLng(53.797731, -1.546351));
makePolygon(cpB);
Log.i("coords", cpB.toString());
break;
default:
break;
}
}
public void makePolygon(ArrayList<LatLng> coords){
mMap.addPolygon(new PolygonOptions()
.addAll(coords)
.strokeColor(Color.RED)
.fillColor(Color.BLUE));
}
XML:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FindCarpark">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Spinner
android:id="#+id/car_spinner"
android:prompt="#string/app_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
</Spinner>
<com.google.android.gms.maps.MapView
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</FrameLayout>
Error:
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.maps.model.Polygon com.google.android.gms.maps.GoogleMap.addPolygon(com.google.android.gms.maps.model.PolygonOptions)' on a null object reference
Your mMap variable is never filled. This then later causes a null pointer exception. The problem is:
if (mapFragment == null) {
mapFragment = SupportMapFragment.newInstance();
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap mMap) {
new googleMap().makeMap(mMap);
}
});
}
here mMap is a local variable, while the mMap you later try to access is a property of the object, thus:
if (mapFragment == null) {
mapFragment = SupportMapFragment.newInstance();
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap mMap) {
FindCarpark.this.mMap = mMap
new googleMap().makeMap(mMap);
}
});
}
Related
I did a tabbed-activity with for tabs. In the fourth tab I did a map, and I added a marker but the marker is not visible and I do not undertand why. I tried many solutions for my problem, but for now I have come to this situation.
This is my Java code:
public class tab_mappa extends SupportMapFragment implements OnMapReadyCallback {
private GoogleMap googleMap;
SupportMapFragment mSupportMapFragment;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.tabmappa, null, false);
mSupportMapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
if (mSupportMapFragment == null) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
mSupportMapFragment = SupportMapFragment.newInstance();
fragmentTransaction.replace(R.id.map, mSupportMapFragment).commit();
}
return root;
}
#Override
public void onMapReady(final GoogleMap googleMap) {
this.googleMap = googleMap;
this.googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
this.googleMap.getUiSettings().setZoomControlsEnabled(true);
this.googleMap.getUiSettings().setCompassEnabled(true);
this.googleMap.getUiSettings().setMyLocationButtonEnabled(true);
this.googleMap.getUiSettings().setZoomGesturesEnabled(true);
this.googleMap.getUiSettings().setRotateGesturesEnabled(true);
LatLng pos1 = new LatLng(44.783878,10.879663);
final LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(pos1);
this.googleMap.addMarker(new MarkerOptions().position(pos1));
this.googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
#Override
public void onMapLoaded() {
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 100));
}
});
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (googleMap == null) {
getMapAsync(this);
}
}
}
This is my xml code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:gravity="center"
android:orientation="vertical"
tools:context="esame.progetto.xhondar.github.com.info.tab_mappa">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.03"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="#+id/map" />
</LinearLayout>
And this is my final result:
Do you have any ideas?
I solved the problem, this is the solution for those who need it:
Java code:
import android.support.v4.app.Fragment;
public class tab_mappa extends Fragment implements OnMapReadyCallback {
GoogleMap map;
SupportMapFragment mapFragment;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.tabmappa, container, false);
SupportMapFragment mapFragment = (SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
return v;
}
#Override
public void onMapReady(GoogleMap googleMap){
map = googleMap;
this.map = googleMap;
this.map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
this.map.getUiSettings().setZoomControlsEnabled(true);
this.map.getUiSettings().setCompassEnabled(true);
this.map.getUiSettings().setMyLocationButtonEnabled(true);
this.map.getUiSettings().setZoomGesturesEnabled(true);
this.map.getUiSettings().setRotateGesturesEnabled(true);
LatLng pp = new LatLng(44.783878,10.879663);
map.addMarker(new MarkerOptions().position(pp).title("Carpi"));
map.animateCamera(CameraUpdateFactory.newLatLngZoom(pp, 8));
}
}
Xml code:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="esame.progetto.xhondar.github.com.info.tab"/>
The error was located in xml code: is Fragment and not FrameLayout, this thing brought conflict within the code.
How about use marker without the builder? you wrote the code in onMapReady()
LatLng pos1 = new LatLng(44.783878,10.879663);
final LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(pos1);
this.googleMap.addMarker(new MarkerOptions().position(pos1));
this.googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
#Override
public void onMapLoaded() {
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 100));
}
});
it change to
LatLng pos1 = new LatLng(44.783878,10.879663);
googleMap.addMarker(new MarkerOptions().position(pos1));
this.googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
#Override
public void onMapLoaded() {
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 100));
}
});
this one. I removed builder and this before googleMap.
i Have a Fragment that should show a Specific place on Google Map
public class ContactFragment extends Fragment implements OnMapReadyCallback {
public ContactFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
FragmentManager fragment = getActivity().getSupportFragmentManager();
final SupportMapFragment myMAPF = (SupportMapFragment) fragment.findFragmentById(R.id.map);
return inflater.inflate(R.layout.fragment_contact, container, false);
}
#Override
public void onMapReady(GoogleMap googleMap) {
LatLng marker = new LatLng(34.877737,-1.326545);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(marker,13));
googleMap.addMarker(new MarkerOptions().position(marker));
}
}
and in the XML file of the Fragment i have this :
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/map"
android:layout_below="#+id/contact_domiciliation"
class="com.google.android.gms.maps.MapFragment"
></fragment>
Yet when i launch click on the button that opens this fragment i get a map of the entire globe .
Add this line of code to the fragment:
myMAPF.getMapAsync(this);
My app's MainActivity has two Fragments within a ViewPager, a MapFragment and a ListFragment. I'm trying to follow Arshu's guide on adding the MapFragment into a ViewPager but without much luck. If you want to see what I mean, here's a screenshot from my app:
Here's a condensed form of the MainActivity:
#Bind(R.id.activity_main_tabs)
PagerSlidingTabStrip mainTabs;
#Bind(R.id.activity_main_pager)
ViewPager mainPager;
#Bind(R.id.activity_main_toolbar)
Toolbar activityToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setSupportActionBar(activityToolbar);
ButterKnife.bind(this);
fragManager = getSupportFragmentManager();
MainTabPagerAdapter adapter = new MainTabPagerAdapter(fragManager, aircraftArrayList);
mainPager.setAdapter(adapter);
mainTabs.setViewPager(mainPager);
}
My ViewPager's TabPagerAdapter:
public class MainTabPagerAdapter extends FragmentStatePagerAdapter {
private final String[] TAB_TITLES = {"Map", "List of planes"};
public final String AIR_KEY = "aircraftKey";
public static FragmentManager fragMgr;
public Bundle bundle;
ArrayList<Aircraft> aircraftArrayList;
public MainTabPagerAdapter(FragmentManager fm, ArrayList<Aircraft> aircraftArrayList) {
super(fm);
fragMgr = fm;
this.aircraftArrayList = aircraftArrayList;
}
#Override
public CharSequence getPageTitle(int position){
return TAB_TITLES[position];
}
#Override
public int getCount() {
return TAB_TITLES.length;
}
#Override
public Fragment getItem(int position){
switch(position){
case 0:
return MainMapFragment.newInstance(aircraftArrayList);
case 1:
return AircraftListFragment.newInstance(1, aircraftArrayList);
}
return null;
}
}
My MainActivity's layout file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/activity_main"
android:fitsSystemWindows="true"
tools:context="com.example.se415017.maynoothskyradar.activities.MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/activity_main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
<android.support.v4.view.ViewPager
android:id="#+id/activity_main_pager"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#eeeeee">
<com.astuetz.PagerSlidingTabStrip
android:id="#+id/activity_main_tabs"
android:layout_width="match_parent"
android:layout_height="36dp"
android:layout_gravity="top"
android:background="#eeeeee"
android:paddingBottom="4dp"
android:paddingTop="4dp"
app:pstsIndicatorColor="#33ccee"
app:pstsIndicatorHeight="4dp"
app:pstsUnderlineColor="#33ccee"
app:pstsUnderlineHeight="2dp"
app:pstsShouldExpand="true"/>
</android.support.v4.view.ViewPager>
</android.support.design.widget.CoordinatorLayout>
And, if it helps, my MapFragment:
public class MainMapFragment extends Fragment implements OnMapReadyCallback {
static View view;
SupportMapFragment mainMapFrag;
private GoogleMap googleMap;
private CameraPosition camPos;
public static MainMapFragment newInstance(ArrayList<Aircraft> aircraftArrayList) {
MainMapFragment fragment = new MainMapFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(AIR_KEY, aircraftArrayList);
fragment.setArguments(bundle);
return fragment;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
if(container == null)
return null;
view = inflater.inflate(R.layout.fragment_main_map, container, false);
ButterKnife.bind(this, view);
mainMapFrag = (SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.main_map);
mainMapFrag.getMapAsync(this);
setUpMapIfNeeded();
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState){
if(googleMap != null)
setUpMap(googleMap);
else { //It's null anyway
((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.main_map)).getMapAsync(this);
mainMapFrag.getMapAsync(this);
if (googleMap != null)
setUpMap(googleMap);
}
}
#Override
public void onPause() {
super.onPause();
if(googleMap != null)
camPos = googleMap.getCameraPosition();
googleMap = null;
}
#Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
//Wait until googleMap is re-initialised
if(camPos != null & googleMap != null) {
googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(camPos));
camPos = null;
}
}
//Sets up the map if it hasn't been set up already
//Somehow it works just fine if I get rid of "static"
protected void setUpMapIfNeeded() {
if (googleMap == null){
Log.d(TAG, "Map was null");
((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.main_map)) //TODO: FIX THIS
.getMapAsync(this);
//Check if the map was obtained successfully
if (googleMap != null)
setUpMap(googleMap);
}
}
/** This is where markers, lines and listeners are added, and where the camera is moved.
* #param googleMap The GoogleMap object to be set up.
*/
private void setUpMap(GoogleMap googleMap) {
googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
//googleMap.setMyLocationEnabled(true); //TODO: Maybe wait until I have the pointing function worked out
googleMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)))
.setTitle("My server is here");
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(53.5, -6.35), 8.0f));
}
#Override
public void onMapReady(final GoogleMap gMap) {
googleMap = gMap;
setUpMap(googleMap);
}
Its layout file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.se415017.maynoothskyradar.fragments.MainMapFragment">
<fragment
android:id="#+id/main_map"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:name="com.google.android.gms.maps.SupportMapFragment"/>
</RelativeLayout>
Can someone please tell me what I'm doing wrong?
It turns out I messed up the layout file for the MainActivity by putting the PagerSlidingTabStrip within the ViewPager element. Here's my fixed file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/activity_main"
android:fitsSystemWindows="true"
tools:context="com.example.se415017.maynoothskyradar.activities.MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/activity_main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimaryDark"
app:popupTheme="#style/AppTheme.PopupOverlay"
android:visibility="visible" />
<android.support.v4.view.ViewPager
android:id="#+id/activity_main_pager"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#eeeeee"
android:clickable="false"/>
<com.astuetz.PagerSlidingTabStrip
android:id="#+id/activity_main_tabs"
android:layout_below="#id/activity_main_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#eeeeee"
android:paddingBottom="4dp"
android:paddingTop="4dp"
app:pstsIndicatorColor="#33ccee"
app:pstsIndicatorHeight="4dp"
app:pstsUnderlineColor="#33ccee"
app:pstsUnderlineHeight="2dp"
app:pstsShouldExpand="true"
android:visibility="visible"
android:measureAllChildren="false"
android:longClickable="true"
android:clickable="true" />
</android.support.design.widget.CoordinatorLayout>
I am fairly new at Android dev, so bear with me. I am having some problems with instance state saving for my google maps api implementation i believe. I am using Android Studio. I am implementing AppCompactActivity to setup a tab view. I am changing fragments in my pager view using a FragmentStatePagerAdapter. My problem is that My google maps api will not save state in very certain circumstances. If i am clicking a tab that is >1 index away from my MapFragment index, the state of the map fragment will not be retained and i cannot add markers or a Go Home button to the map, but the map is present.
My initial marker and home location button works, it just won't show back up/allow me to add more markers after i switch to my last tab and switch back to the map tab.
As i said, i am new at android dev, so any advice is appreciative.
This is my main activity
public class MainActivity extends AppCompatActivity{
public static FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getSupportFragmentManager();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
tabLayout.addTab(tabLayout.newTab().setText("Map"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
}
with main activity xml as this
<RelativeLayout
android:id="#+id/main_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/tab_layout"/>
</RelativeLayout>
This is my PagerAdapter class
public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
public PagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new TabFragment1();
case 1:
return new MapViewFragment();
case 2:
return new TabFragment2();
case 3:
return new TabFragment3();
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
this is my MapFragment class
public class MapViewFragment extends Fragment {
private static View view;
/**
* Note that this may be null if the Google Play services APK is not
* available.
*/
private static GoogleMap mMap;
private static Double latitude, longitude;
private static String quickFilterText="";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
return null;
}
view = inflater.inflate(R.layout.activity_maps, container, false);
// Passing harcoded values for latitude & longitude. Please change as per your need. This is just used to drop a Marker on the Map
latitude = 26.78;
longitude = 72.56;
ImageButton arrowButton = (ImageButton) view.findViewById(R.id.arrowButton);
arrowButton.setOnClickListener(new ImageButton.OnClickListener() {
public void onClick(View newView) {
RelativeLayout relLayout = (RelativeLayout) view.findViewById(R.id.filterDropDown);
EditText text = (EditText) view.findViewById(R.id.quickFilter);
try
{
quickFilterText = text.getText().toString();
}
catch(Exception err)
{
}
if(relLayout.getHeight()>0)
{
relLayout.setLayoutParams(new RelativeLayout.LayoutParams(relLayout.getWidth(),0));
}
else
{
relLayout.setLayoutParams(new RelativeLayout.LayoutParams(relLayout.getWidth(),180));
}
}
});
return view;
}
/***** Sets up the map if it is possible to do so *****/
public void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null)
setUpMap();
}
}
/**
* This is where we can add markers or lines, add listeners or move the
* camera.
* <p>
* This should only be called once and when we are sure that {#link #mMap}
* is not null.
*/
private static void setUpMap() {
// For showing a move to my loction button
mMap.setMyLocationEnabled(true);
// For dropping a marker at a point on the Map
mMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)).title("My Home").snippet("Home Address"));
// For zooming automatically to the Dropped PIN Location
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,
longitude), 12.0f));
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// TODO Auto-generated method stub
setUpMapIfNeeded();
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById(map)).getMap(); // getMap is deprecated
// Check if we were successful in obtaining the map.
if (mMap != null)
setUpMap();
}
setRetainInstance(true);
}
/**** The mapfragment's id must be removed from the FragmentManager
**** or else if the same it is passed on the next time then
**** app will crash ****/
#Override
public void onDestroy(){
super.onDestroy();
}
#Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
}
}
and this is my activity_maps.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapActivity">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment" />
<RelativeLayout
android:id="#+id/filterDropDown"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal"
android:background="#80000000"
android:gravity="top|center"
android:padding="4dp"
android:weightSum="1">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="8dp"
android:text="Filter"
android:id="#+id/filterTextBox"
android:gravity="center_vertical" />
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/quickFilter"
android:paddingRight="8dp"
android:paddingLeft="8dp"
android:layout_toRightOf="#+id/filterTextBox" />
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="#+id/arrow"
android:layout_width="70dp"
android:layout_height="23dp"
android:orientation="horizontal"
android:background="#drawable/shape"
android:gravity="center"
android:padding="4dp"
android:layout_gravity="center_horizontal|top"
android:weightSum="1"
android:layout_centerHorizontal="true"
android:layout_below="#+id/filterDropDown">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Filter"
android:id="#+id/arrowButton"
android:background="#drawable/down_arrow"
android:clickable="true" />
</RelativeLayout>
</RelativeLayout>
my other 3 tabs are just simple fragments with a text view inside of them
public class TabFragment1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.tab_fragment_1, container, false);
}
}
with layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Tab 1"
android:textAppearance="?android:attr/textAppearanceLarge"/>
</RelativeLayout>
By default the view pager keeps the current fragment, and one fragment to the left and right of it alive. In your pager adapter you are telling it the create a brand new fragment, instead of using the existing one.
List<Fragment> myPages; // populate this in the constructor
#Override
public Fragment getItem(int position) {
return myPages.get(position);
}
#Override
public int getCount() {
return myPages.size();
}
You should also increase the off screen page limit if you know you will only ever have those four fragments.
viewPager.setOffscreenPageLimit(3);
If you run into more problems with the map after doing these two things you may want to set the map fragment to retain its instance state. Override the fragments onCreate() method.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
When Google Map displayed, there is default infowindow above a maker.
and if I clicked the marker again, custom infowindow is displayed.
but, when I clicked map then all infowindow disappear. I want default infowindow to stay on map always.
the point is I want to keep showing infowindow which was displayed at first even if new infowindow is displayed.
what should I do?
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mMap = ((SupportMapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
moveToLocation();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.map_page, null);
}
protected void moveToLocation() {
CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(new LatLng(mLatitude, mLongitude), 15);
mMap.moveCamera(cu);
MarkerOptions options = new MarkerOptions().position(new LatLng(mLatitude, mLongitude)).title(mCompany);
mMarker = mMap.addMarker(options);
mMarker.showInfoWindow();
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
mMap.setInfoWindowAdapter(new CustomInfoAdapter());
}
});
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
mMap.setInfoWindowAdapter(new CustomInfoAdapter());
return false;
}
});
}
private class CustomInfoAdapter implements GoogleMap.InfoWindowAdapter {
private View mWindow;
public CustomInfoAdapter() {
mWindow = getActivity().getLayoutInflater().inflate(R.layout.marker_window, null);
}
#Override
public View getInfoWindow(Marker marker) {
render(marker, mWindow);
return mWindow;
}
#Override
public View getInfoContents(Marker marker) {
return null;
}
private void render(Marker marker, View view) {
ImageView badge = (ImageView) view.findViewById(R.id.badge);
badge.setImageResource(R.drawable.ic_launcher);
TextView title = (TextView) view.findViewById(R.id.title);
TextView snippet = (TextView) view.findViewById(R.id.snippet);
title.setText(mCompany);
snippet.setText(mAddress);
}
}
xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>