Подтвердить что ты не робот

Как узнать, что карта готова к использованию при использовании SupportMapFragment?

В методе onCreate я использую SupportMapFragment для отображения карты.

    SupportMapFragment fragment = new SupportMapFragment();
    getSupportFragmentManager().beginTransaction()
            .add(android.R.id.content, fragment).commit();

В связи с этим я хотел бы добавить маркер. Проблема в том, когда вызов getMap равен нулю, когда я могу попробовать еще раз? Есть ли какое-то событие, которое я могу зарегистрировать, или мой подход сам по себе не прав?

    mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap();
    if(mMap == null)
        //what do I do here?

Карта фактически отображается на телефоне, однако мне кажется, что нам не удавалось получить ссылку на добавление маркеров.

UPDATE:

Причина, по которой я создавала SupportMapFragment через конструктор, связана с тем, что типичный setContentView был сбой и не работал. Это поставило меня в затруднительное положение, когда я не смог получить свою ссылку в методе onCreate, так как я фактически создавал SupportMapFragment в то время. В дальнейших исследованиях, кажется, что мой вопрос setContentView был побочным продуктом, когда у меня не было как баннера Google-play-services, так и модуль /src, созданный как часть общего проекта. Выполняя ОБА, теперь работает setContentView, и я могу получить ссылку через getMap(), как и следовало ожидать.

lots.xml...

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/map"
          android:name="com.google.android.gms.maps.SupportMapFragment"
          android:layout_width="match_parent"
          android:layout_height="match_parent" />

LotsActivity.java...

public class LotsActivity extends FragmentActivity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.lots);

        GoogleMap mMap;
        mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap();
        if(mMap == null)
            //this should not occur now
    }
4b9b3361

Ответ 1

EDIT: getMap теперь устарел

Проблема в том, когда вызов getMap равен null, когда я могу попробовать еще раз?

Это зависит от характера проблемы.

Если вы настроите SupportMapFragment с помощью элемента <fragment> в макете, вы можете вызвать getMap() успешно в onCreate(). Но, если вы создаете SupportMapFragment через конструктор, это слишком скоро - GoogleMap еще не существует. Вы можете расширить SupportMapFragment и переопределить onActivityCreated(), так как к нему будет готова getMap().

Тем не менее, getMap() также может возвращать null для большей проблемы, например, не устанавливать Google Play Services. Вам нужно будет использовать что-то вроде GooglePlayServicesUtil.isGooglePlayServicesAvailable(), чтобы обнаружить это условие и справиться с ним, как хотите.

Ответ 2

Я закончил расширение класса SupportMapFragment и использовал обратный вызов. Код здесь:

public class MySupportMapFragment extends SupportMapFragment {

public MapViewCreatedListener itsMapViewCreatedListener;

// Callback for results

public abstract static class MapViewCreatedListener {
    public abstract void onMapCreated();
}

@Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = super.onCreateView(inflater, container, savedInstanceState);
    // Notify the view has been created
    if( itsMapViewCreatedListener != null ) {
        itsMapViewCreatedListener.onMapCreated();
    }
    return view;
}
}

Я предпочел бы использовать интерфейс и переопределить метод onAttach (activity), но в моем случае я не хотел, чтобы callback возвращался к моей MainActivity. Я хотел, чтобы он вернулся к экземпляру Fragment. (GoogleMap был по существу фрагментом внутри фрагмента). Я настраиваю обратный вызов и программно загружаю карту с этим. Я хотел бы установить itsMapViewCreatedListener внутри конструктора MySupportMapFragment, но использовать что-либо, кроме конструкторов без параметров, не рекомендуется.

itsMySupportMapFragment = new MySupportMapFragment();
MapViewCreatedListener mapViewCreatedListener = new MapViewCreatedListener() {
    @Override
    public void onMapCreated() {
        initPlacesGoogleMapCtrl();
    }
};
itsMySupportMapFragment.itsMapViewCreatedListener = mapViewCreatedListener;
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.mapFragmentContainer, itsMySupportMapFragment);
transaction.addToBackStack(null);
transaction.commit();

И затем, когда я вернусь, я могу получить карту; не более null!

public void initPlacesGoogleMapCtrl() {
    // Map ready, get it.
    GoogleMap googleMap = itsMySupportMapFragment.getMap();
    // Do what you want...
}

Ответ 3

Я бы прокомментировал ответ CommonsWare, но у меня недостаточно отзывов. В любом случае, у меня также была эта проблема: getMap() вернет null в onActivityCreated. Моя настройка такова: у меня есть MainActivity, которая содержит фрагмент. В методе onCreateView этого фрагмента я создал SupportMapFragment, а затем добавил его к фрагменту через childFragmentManager. Я продолжал ссылаться на SupportMapFragment и ожидал, что он даст мне карту в onActivityCreated, которой она не была. Решение этой проблемы состояло в том, чтобы переопределить onActivityCreated SupportMapFragment, но не родительский фрагмент. Я сделал это в onCreateView:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_location, container, false);
    mMapFragment = new SupportMapFragment() {
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            mMap = mMapFragment.getMap();
            if (mMap != null) {
                setupMap();
            }
        }
    };
    getChildFragmentManager().beginTransaction().add(R.id.framelayout_location_container, mMapFragment).commit();
return v;   
}

Ответ 4

В прошлом месяце (декабрь 2014 года) Google официально разрешил эту проблему. В новейшем (6.5) сервисе Google Play:

Метод getMap() в MapView и MapFragment теперь устарел в пользу нового метода getMapAsync().

С помощью getMapAsync(OnMapReadyCallback callback) вы можете настроить прослушиватель, когда GoogleMap готов. Он передается в обратном вызове и предоставляется непустым.

Google предоставил пример кода для этого:

public class MainActivity extends FragmentActivity
    implements OnMapReadyCallback {
...
}

и при инициализации фрагмента:

MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);

когда карта готова, вы получите обратный вызов

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(0, 0))
        .title("Marker"));
}

Ответ 5

Вы также можете использовать MapsInitializer.initialize(context);, если проблема связана с не инициализированными библиотеками.

Ответ 6

С последними GoogleServices вы можете использовать MapFragment.getMapAsync. Непосредственно из документов

Устанавливает объект обратного вызова, который будет запущен, когда экземпляр GoogleMap готов к использованию.

Ответ 7

если map == null, тогда найдите карту

 if (mGoogleMap == null)
    {
        SupportMapFragment mapFragment1 = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);

        mapFragment1.getMapAsync(this);
    }

а затем вызовите функцию onMapReady();