4

I get addresses From a database and i mark them on the google Maps activity using first Geocoder and if that returns LatLng null, i use an asynctask to get it From googleapi.

The code Works great, but when selecting 500-600 addresses, loading the map takes a while (15-30 seconds depending on the number).

How can i add a round progressBar while the map is loading? The problema is that while the map is loading, the screen is black. I tried adding a progressBar in the asynctask but it doesnt work.

Even after the map is loaded, the asynctask keeps adding pins to the map and you cant know when it finishes, keep in mind there are a lot of pins.

I created the progressBar in onCreate() and set it to invisible :

 progressBar = new ProgressBar(MapsActivity.this, null,android.R.attr.progressBarStyleSmall);
 progressBar.setVisibility(View.INVISIBLE);  

In the asynctask , on the onPreExecute() i set it on visible:

 @Override
 protected void onPreExecute() {
      progressBar.setVisibility(View.VISIBLE);
    }
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Alex E.
  • 139
  • 3
  • 14
  • "Right now its black screen for 15-30 seconds "? Then you need to add more information to your question. Please add your `AsyncTask` and tell us where you call it. The screen should not be black for any reason. – Barns Apr 19 '18 at 13:53
  • It's a black screen for that time because the app needs to make a query to the database, collect the addresses , 500-600 even more, pass them through the Geocoder, if that returns null, pass them through the googleapis/Maps. So yeah, it takes some time to do that. It's not an error, i think , it just takes time. I just want to add something so that the user knows its working on it, the app has not crashed. – Alex E. Apr 19 '18 at 13:57

2 Answers2

3

Your problem is basically user experience related and not to your code.

There are two solutions you can use that will tell the user the app is doing something and not just frozen or have crashed :

Solution 1
You can use a loading view that is displayed instead of your map while your loading information

<FrameLayout
     <!-- same layout information as your current MapView -->
     ...
     >
     <MapView
         ...
         />
     <View
         <!-- This can be a ProgressBar or a custom loading View with animation -->
         />
</FrameLayout>

You can then make View Visible when data is loading and then display map once finished.. this'll help avoid the black screen

Update
Following this answer, you can find to extend a Fragment and add a MapView

Setting up the layout for showing the map. location_fragment.xml :

<?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" >

    <com.google.android.gms.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <View
        android:id="@+id/loadingView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

Now we code the java class for showing the Map. MapViewFragment :

public class MapViewFragment extends Fragment {

    MapView mMapView;
    View mLoadingView;
    private GoogleMap googleMap;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.location_fragment, container, false);

        mMapView = (MapView) rootView.findViewById(R.id.mapView);
        mLoadingView = rootView.findViewById(R.id.loadingView); // you can handle your view as you wish
        mMapView.onCreate(savedInstanceState);

        mMapView.onResume(); // needed to get the map to display immediately

        try {
            MapsInitializer.initialize(getActivity().getApplicationContext());
        } catch (Exception e) {
            e.printStackTrace();
        }

        mMapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap mMap) {
                googleMap = mMap;

                // For showing a move to my location button
                googleMap.setMyLocationEnabled(true);

                // For dropping a marker at a point on the Map
                LatLng sydney = new LatLng(-34, 151);
                googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker Title").snippet("Marker Description"));

                // For zooming automatically to the location of the marker
                CameraPosition cameraPosition = new CameraPosition.Builder().target(sydney).zoom(12).build();
                googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
            }
        });

        return rootView;
    }

    @Override
    public void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mMapView.onLowMemory();
    }
}

This way you can hide/show loadingView whenever you've done fetching data.

Solution 2
You can display only a map before loading the data then display a ProgressBar on top of it while fetching data. Once data is loaded you can populate your map.

ColdFire
  • 6,764
  • 6
  • 35
  • 51
  • I like the first Solution, but being that the Maps Activity is a fragment, i dont know how or if it is posible to implement a View on the fragment. – Alex E. Apr 19 '18 at 14:27
  • You can show your loading view--> load data then replace the view with the map fragment.. all within you activity.. otherwise you can extend a simple fragment and add a layout with a mapview instead of mapfragment – ColdFire Apr 19 '18 at 14:37
  • I'm sorry, im a begginner with this,it's my first project. I understand what you're saying, but i have no idea how to do it. – Alex E. Apr 19 '18 at 15:22
  • No problem.. I updated my answer on how to create a fragment with mapView and loadingView – ColdFire Apr 19 '18 at 15:35
0

From here

public abstract void onMapLoaded ()

Called when the map has finished rendering. This will only be called once. You must request another callback if you want to be notified again.

This is called on the Android UI thread.

  • If i add the dialog on that method, would that resolve the black screen too? Since it seems that it crashed with the black screen for 30 seconds or more. According to the docs the method is for when the map is loaded : This event will not fire if the map never loads due to connectivity issues, or if the map is continuously changing and never completes loading due to the user constantly interacting with the map. – Alex E. Apr 19 '18 at 13:52
  • Initially before the map is loaded you can make the `progressBar` visible. Once the map is loaded, in this `onMapLoaded()` you can hide it. If the map is loaded once, it doesn't make any difference if it is continuously changing. –  Apr 19 '18 at 14:00