FindFragmentById для SupportMapFragment возвращает null в Android Studio
Недавно я перенес проект из Eclipse в Android Studio. Все настроено и работает отлично, за исключением одного фрагмента, который использует SupportMapFragment. Ниже findFragmentById (который работал при создании в Eclipse) теперь возвращает null:(
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
SupportMapFragment m = ((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.safety_map));
фрагмент xml...
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:id="@+id/safety_map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="40dp"
map:cameraTargetLat="@string/livesafe_latitude"
map:cameraTargetLng="@string/livesafe_longitude"
map:uiZoomControls="false"
class="com.google.android.gms.maps.SupportMapFragment"/>
Вот мои зависимости в моей build.gradle:
dependencies {
//google analytics
compile 'com.google.apis:google-api-services-analytics:v3-rev103-1.19.0'
//support library for api 10
compile 'com.android.support:support-v4:21.0.0'
//google play services
compile 'com.google.android.gms:play-services:6.1.11'
compile project(':facebook')
compile files('libs/android-support-multidex.jar')
compile files('libs/aws-android-sdk-1.6.0-debug.jar')
compile files('libs/FlurryAnalytics_3.3.2.jar')
}
Я не изменил код в файле xml или классе Fragment, который ранее работал в Eclipse.
Ответы
Ответ 1
Судя по тому, что вы переопределяете Fragment.onActivityCreated()
, я полагаю, что ваш макет, содержащий фрагмент карты, является макетом для вашего Fragment
. В этом случае SupportMapFragment
является дочерним фрагментом вашего хостинга Fragment
. Когда вы пытаетесь восстановить его, вы используете Activity
FragmentManager
. Вместо этого вы должны использовать Fragment
FragmentManager
:
Например, это:
SupportMapFragment m = ((SupportMapFragment) getActivity()
.getSupportFragmentManager().findFragmentById(R.id.safety_map));
становится:
SupportMapFragment m = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.safety_map));
Ответ 2
Да. Это не работает для targetSdkVersion 21, если фрагмент вашей карты является внутренней частью фрагмента (из-за некоторых проблем, упомянутых this и this).
Как временное решение может дать такой трюк:
public class MyFragment extends Fragment {
private SupportMapFragment fragment;
private GoogleMap map;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.layout_with_map, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
if (fragment == null) {
fragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map_container, fragment).commit();
}
}
}
Ответ 3
Следующий код работал у меня. Я использовал карту Google в Fragment
:
SupportMapFragment m = ((SupportMapFragment) getChildFragmentManager() .findFragmentById(R.id.safety_map));
Ответ 4
Все ответы верны соответствующим образом. Может случиться так, что вы следуете за кодом java, который работает для них, но не работает для вас, потому что у вас была другая реализация в вашем xml-коде, чем у них.
Итак, позвольте мне высказать свое мнение о том, как мне удалось загрузить карту как в Activity
, так и в Fragment
Активность:
<fragment
android:name="com.google.android.gms.maps.MapFragment"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Класс Java:
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
В фрагменте:
<fragment
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Класс Java:
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
Ответ 5
Для Kotlin в onCreateView просто добавьте следующий код:
private lateinit var mapFragment : SupportMapFragment
mapFragment = childFragmentManager.findFragmentById(R.id.mapview) as SupportMapFragment
mapFragment.getMapAsync { googleMap ->
this.googleMap = googleMap
setGoogleMapSettings()
}
Ответ 6
если вы разработали свой код с помощью Kotlin и хотите добавить MapFragment в другой фрагмент, вам нужно использовать SupportMapFragment
, но если вы сделаете это, вы получите исключение NULL, поэтому вам следует использовать childFragmentManager
, а не supportFragmentManager
и код должен быть в onCreateView
, а не в onCreate
, просто добавьте следующий код:
private lateinit var mapFragment : SupportMapFragment
mapFragment = childFragmentManager.findFragmentById(R.id.mapview) as SupportMapFragment
mapFragment.getMapAsync { googleMap ->
this.googleMap = googleMap
setGoogleMapSettings()
}