Используя Android Studio, я настроил Google Maps в своем приложении, используя демонстрационный репозиторий карт, предоставленный CodePath ( это код для их Activity ), и я хотел использовать нижнюю панель навигации для переключения между фрагментом карты и другими фрагментами.
По умолчанию установлено, что MapDemoActivity
содержит один фрагмент для карты. Этот фрагмент является SupportMapFragment
, классом, который расширяет Fragment
( Документация ).
Нижняя панель навигации включает использование FrameLayout
в качестве контейнера для фрагментов и FragmentManager
заменить его фрагментом, выбранным в соответствии с панелью навигации. Код для этого:
final FragmentManager fragmentManager = getSupportFragmentManager();
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
fragment = null;
switch (menuItem.getItemId()) {
case R.id.action_map:
fragment = new MapFragment();
break;
case R.id.action_notifications:
fragment = new NotificationsFragment();
break;
case R.id.action_profile:
fragment = new ProfileFragment();
break;
default:
break;
}
// flContainer is the FrameLayout container
fragmentManager.beginTransaction().replace(R.id.flContainer, fragment).commit();
return true;
}
});
// Set default selection
bottomNavigationView.setSelectedItemId(R.id.action_map);
Проблема:
Изначально я пытался превратить MapDemoActivity
в фрагмент и создать новое действие, содержащее все фрагменты. Но когда я реализовал нижнюю панель навигации и протестировал ее, карта загружалась правильно, но местоположение и все маркеры никогда не показывались бы на фрагменте карты. Отображение местоположения зависело от получения KEY_LOCATION
от savedInstanceState
, но savedInstanceState
всегда было нулевым, как и местоположение. Я так и не нашел решения, поэтому попробовал другой подход.
Я пытался превратить MapDemoActivity
в контейнер для всех фрагментов, пока он все еще содержал фрагмент карты. Проблема в том, что фрагмент карты представляет собой SupportMapFragment
, а не обычный фрагмент, поэтому FragmentManager
не может заменить FrameLayout
на него. Каждый раз, когда я пытался это сделать, приложение зависало.
Следует отметить, что FrameLayout
и фрагмент карты находятся в одном файле макета XML (для MapDemoActivity
). Это может быть неправильно, так как фрагменты обычно содержатся в отдельных XML файлах макетов и классах. Но когда я попытался отделить фрагмент от FrameLayout
в новый класс и файл макета XML, я столкнулся с той же проблемой, что и раньше: местоположение не будет отображаться.
Прямо сейчас XML файл макета выглядит следующим образом:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout
android:id="@+id/flContainer"
android:layout_height="551dp"
android:layout_width="match_parent"
android:layout_above="@id/bottom_navigation"/>
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/flContainer"
android:layout_alignParentBottom="true"
app:menu="@menu/menu_bottom_navigation" />
<fragment
android:id="@+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="551dp"
map:cameraTargetLat="30.28809"
map:cameraTargetLng="-97.7491283"
map:cameraZoom="16"
map:uiZoomControls="true"/>
</LinearLayout>