Вкладка "Карты" в панели действий

Я пытаюсь создать приложение, которое будет реализовывать вкладки панели действий. Одна из вкладок должна содержать MapFragment.

Как реализовать панель действий с вкладками, под одной из которых находится фрагмент карты?

Можете ли вы помочь мне с этим?

Вот что у меня так далеко:

основной класс

package com.nfc.demo;

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;

public class NFCDemoActivity extends Activity {

  Tab selectedTab = null;

  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ActionBar bar = getActionBar();
    bar.setDisplayShowHomeEnabled(false);
    bar.setDisplayShowTitleEnabled(false);

    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    bar.setCustomView(R.layout.main);

    ActionBar.Tab mapTab = bar.newTab().setText("Map");
    ActionBar.Tab settingsTab = bar.newTab().setText("Settings");
    ActionBar.Tab aboutTab = bar.newTab().setText("About");

    MapFragment mapFragment = new MapFragment();
    SettingsFragment settingsFragment = new SettingsFragment();
    AboutFragment aboutFragment = new AboutFragment();

    mapTab.setTabListener(new TabListener(mapFragment));
    settingsTab.setTabListener(new TabListener(settingsFragment));
    aboutTab.setTabListener(new TabListener(aboutFragment));

    Tab selectedTab = (Tab) getLastNonConfigurationInstance();

    if (selectedTab == null) {
      bar.addTab(mapTab, false);
      bar.addTab(settingsTab, false);
      bar.addTab(aboutTab, true);
    }

    setContentView(R.layout.main);

  }

  public Object onRetainNonConfigurationInstance() {
    return selectedTab;
  }

  protected boolean isRouteDisplayed() {
      return false;
  }

  protected class TabListener implements ActionBar.TabListener {
    private Fragment fragment;

    public TabListener(Fragment fragment) {
        this.fragment = fragment;
    }

    public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {
        fragmentTransaction.replace(R.id.mainFragment, this.fragment, null);
        selectedTab = tab;
    }

    public void onTabUnselected(Tab tab, FragmentTransaction fragmentTransaction) {
        fragmentTransaction.remove(this.fragment);
    }

    public void onTabReselected(Tab tab, FragmentTransaction fragmentTransaction) {
        //do nothing
    }
  }
}

Все классы Fragment просто возвращают инфлятор с макетом .xml.

XML-макеты:

main.xml (карта должна быть в этом XML файле)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mainFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

</LinearLayout>

settings.xml И about.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/textView123"
        android:text="asdfg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

Но добавление MapFragment приводит к ошибке:

Error inflating class fragment 
error caused by java.lang.IllegalArgumentException: 
Binary XML file line #2: Duplicate id 0x7f040005, tag null, or parent id 0x1020002 with another fragment for com.google.android.gms.maps.MapFragment 12-28 21:14:07.991: E/AndroidRuntime(26189): at android.app.Activity.onCreateView(Activity.java:4722)

Я пытался понять, как действовать в течение нескольких дней, но я действительно смущен. Любая помощь/советы будут с благодарностью.

Кроме того, как насчет getLastNonConfigurationInstance()? Это устарело.

Ответ 1

В следующем решении можно добавить GoogleMap на вкладку "Панель действий" /выпадающий список. Ключом к этому является правильная настройка фрагмента для уничтожения MapFragment при переключении на другой фрагмент в панели действий.

Создать действие, реализующее функциональность панели действий:

  • Создайте проект в Eclipse, который использует вкладки для основного действия. Если вы этого не сделаете, перейдите к шагам 2-5.
  • Создайте класс, который расширяет Activity и реализует ActionBar.OnNavigationListener.
  • Создайте XML файл макета, который является контейнером для ваших фрагментов вкладки, когда вы переключаетесь между ними.
  • Внедрить/переопределить следующий метод в вашем классе Activity: public boolean onNavigationItemSelected(int position, long id).
  • В этом методе перейдите между объектом position, чтобы определить выбранную вкладку, и установите фрагмент в новый экземпляр, используя FragmentManager, как это: getFragmentManager().beginTransaction().replace(R.id.container, fragment).commit().

Создайте фрагмент, содержащий карту:

  • Создайте класс, который расширяет Fragment для использования в качестве фрагмента вкладки. Прочтите [1], чтобы лучше понять MapFragment.
  • Создайте XML файл макета, содержащий элемент фрагмента (как показано в [1]). Используйте XML на этой странице, чтобы создать размещать XML файл и использовать его в своем классе фрагментов.
  • Надуйте этот XML файл макета в свой класс фрагментов, переопределив onCreateView.
  • Теперь ваше приложение должно отображать карту на вкладке, которая использует ваш класс фрагмента, однако переход на другую вкладку и обратно на вкладку карты приведет к дублированному идентификатору вида. Чтобы преодолеть это, переходите к следующему шагу.
  • В вашем классе фрагмента переопределите следующий метод, чтобы специально уничтожить основной объект GoogleMap, чтобы его можно было воссоздать, когда вкладка карты снова загрузит ваш класс фрагмента:

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        MapFragment f = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
        if (f != null) 
            getFragmentManager().beginTransaction().remove(f).commit();
    }

Ответ 2

Не уверен, что вы уже решили это или нет. Вы должны добавить сервисы google play как проект библиотеки, чтобы он работал. Сначала я попытался добавить файл jar, но это не сработало.