GetMapAsync() в фрагменте

У меня возникли проблемы с реализацией карты Google в фрагменте.

Это моя часть класса моего фрагмента:

public class FragmentStoreFinderMap extends Fragment implements OnMapReadyCallback {

// Google Map
private GoogleMap googleMap;
private int i;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

        googleMap = ((SupportMapFragment)getActivity().getSupportFragmentManager().findFragmentById(
              R.id.map)).getMapAsync(this);

Я получаю сообщение об ошибке в getMapAsync (this). Я говорю несовместимый тип.

он говорит:

требуется: com.google.android.gms.map.GoogleMap

найдено: void

Кстати вот мой xml:

<?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"
android:orientation="vertical" >
<fragment class="com.google.android.gms.maps.SupportMapFragment"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

</LinearLayout>

Ответ 1

В вашем 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">

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

</FrameLayout>

внутри вашего фрагмента реализовать это

private MapView mapView;
private GoogleMap googleMap;

переопределить onCreateView, если onCreateView не существует, как в приведенном ниже коде

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.your_layout, container, false);
}

переопределить onViewCreated() внутри этого onViewCreated() вставьте это

mapView = (MapView) view.findViewById(R.id.map);
mapView.onCreate(savedInstanceState);
mapView.onResume();
mapView.getMapAsync(this);//when you already implement OnMapReadyCallback in your fragment

когда вы уже внедрили OnMapReadyCallback в своем фрагменте, добавьте этот код/​​наподобие этого

@Override
public void onMapReady(GoogleMap map) {
    googleMap = map;
}

надеюсь, это поможет вам.

Ответ 2

После нескольких перегревов в голове, благодаря этому посту и fooobar.com/questions/834215/..., я бы сказал, что в настоящее время существует два способа добавления MapFragment в ваше приложение:

<fragment xmlns:android="http://schemas.android.com/apk/res/android" 
class="com.google.android.gms.maps.SupportMapFragment"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

Таким образом, вы должны использовать стандартный фрагмент и реализовать это внутри. На самом деле вы вставляете фрагмент в другой:

    @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    SupportMapFragment supportMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
    supportMapFragment.getMapAsync(this);
}

Другой способ - использовать настоящий SupportMapFragment и реализовать его следующим образом:

    @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    getMapAsync(this);
}

И они работают без необходимости устанавливать макет в onCreateView, также не вызывая mapView.onCreate(savedInstanceState); и mapView.onResume(); вручную внутри onViewCreated(), что в любом случае не рекомендуется.

Надеюсь, это поможет!

Ответ 3

 SupportMapFragment mMapFragment = SupportMapFragment.newInstance();
 FragmentTransaction fragmentTransaction =
 getChildFragmentManager().beginTransaction();
 fragmentTransaction.add(R.id.flMap, mMapFragment);
 fragmentTransaction.commit();
 mMapFragment.getMapAsync(this);

Ответ 4

Ваш код возвращает эту ошибку, потому что getMapAsync() ничего не возвращает. Если вы посмотрите на документацию для этой функции:

public void getMapAsync (обратный вызов OnMapReadyCallback)

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

Обратите внимание, что:

Этот метод должен вызываться из основного потока. Обратный вызов будет выполненных в основном потоке. В случае, когда услуги Google Play не установлен на пользовательском устройстве, обратный вызов не будет запущен пока пользователь не установит его. В редком случае, когда GoogleMap уничтожается сразу после создания, обратный вызов не запускается. Объект GoogleMap, предоставляемый обратным вызовом, не имеет значения.

OnMapReadyCallback - это интерфейс, который необходимо реализовать и передать через эту функцию. В настоящее время ничто не привязано к вашей переменной googleMap, вместо этого вы должны установить ее значение в этом блоке кода, который implements OnMapReadyCallback

@Override
    public void onMapReady(GoogleMap googleMap) {
        this.googleMap = googleMap;


    }

Этот код должен находиться в вашем фрагменте где-то. Поскольку ваш фрагмент уже реализует этот интерфейс, вы передаете его как this.