27

Sto cercando di usare ActionbarSherlock ma ho una query che mi trattiene.Utilizzo di ActionBarSherlock con il nuovo SupportMapFragment

Quindi la mia domanda deve essere completamente retrocompatibile con API livello 7.

ho bisogno di attuare il nuovo Google Maps nella mia applicazione e per farlo ho bisogno di utilizzare la classe SupportMapFragment.

** ** La mia domanda

E 'possibile utilizzare la classe SupportMapFragment fianco ActionBarSherlock?

Grazie in anticipo

EDIT

Ho scaricato e aveva uno sguardo alla biblioteca. Le uniche modifiche al numero esteso Fragments che riesco a vedere sono molto semplici e identiche per tutte.

Pensi che potrei aggiungere il supporto da solo?

ecco come sono supportati.

package com.actionbarsherlock.app; 

import android.app.Activity; 
import android.support.v4.app.DialogFragment; 
import com.actionbarsherlock.internal.view.menu.MenuItemWrapper; 
import com.actionbarsherlock.internal.view.menu.MenuWrapper; 
import com.actionbarsherlock.view.Menu; 
import com.actionbarsherlock.view.MenuInflater; 
import com.actionbarsherlock.view.MenuItem; 

import static com.actionbarsherlock.app.SherlockFragmentActivity.OnCreateOptionsMenuListener; 
import static com.actionbarsherlock.app.SherlockFragmentActivity.OnOptionsItemSelectedListener; 
import static com.actionbarsherlock.app.SherlockFragmentActivity.OnPrepareOptionsMenuListener; 

public class SherlockDialogFragment extends DialogFragment implements OnCreateOptionsMenuListener, OnPrepareOptionsMenuListener, OnOptionsItemSelectedListener { 
    private SherlockFragmentActivity mActivity; 

public SherlockFragmentActivity getSherlockActivity() { 
    return mActivity; 
} 

@Override 
public void onAttach(Activity activity) { 
    if (!(activity instanceof SherlockFragmentActivity)) { 
     throw new IllegalStateException(getClass().getSimpleName() + " must be attached to a SherlockFragmentActivity."); 
    } 
    mActivity = (SherlockFragmentActivity)activity; 

    super.onAttach(activity); 
} 

@Override 
public void onDetach() { 
    mActivity = null; 
    super.onDetach(); 
} 

@Override 
public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) { 
    onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater()); 
} 

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    //Nothing to see here. 
} 

@Override 
public final void onPrepareOptionsMenu(android.view.Menu menu) { 
    onPrepareOptionsMenu(new MenuWrapper(menu)); 
} 

@Override 
public void onPrepareOptionsMenu(Menu menu) { 
    //Nothing to see here. 
} 

@Override 
public final boolean onOptionsItemSelected(android.view.MenuItem item) { 
    return onOptionsItemSelected(new MenuItemWrapper(item)); 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    //Nothing to see here. 
    return false; 
} 

}

risposta

61

tutto funziona come un fascino, soprattutto grazie al grande lavoro di Jake sulla ActionBarSherlock

Questi sono i passi che ho seguito:

  1. creare una classe SherlockMapFragment nel progetto di libreria actiobarsherlock. Ho semplicemente fatto una copia di SherlockFragment perché anche ho bisogno di supporto per setHasOptionsMenu(true)
  2. L'attività si estende SherlockFragmentActivity (come al solito)
  3. Il frammento si estende la nuova creazione SherlockMapFragment
  4. ActionBarSherlock richiede il nuovo google-play-services_lib biblioteca
  5. il progetto richiede la libreria ActionBarSherlock. Non è necessario includere nuovamente i servizi di google play o costruire contro l'API di Google.
  6. Come citato da Graham, si deve cadere il supporto per API 7 dispositivi: <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />

Ed ecco qualche codice per una spiegazione più dettagliata:

SherlockMapFragment

package com.actionbarsherlock.app; 

import com.actionbarsherlock.internal.view.menu.MenuItemWrapper; 
import com.actionbarsherlock.internal.view.menu.MenuWrapper; 
import com.actionbarsherlock.view.Menu; 
import com.actionbarsherlock.view.MenuInflater; 
import com.actionbarsherlock.view.MenuItem; 
import com.google.android.gms.maps.SupportMapFragment; 

import android.app.Activity; 
import android.support.v4.app.Watson.OnCreateOptionsMenuListener; 
import android.support.v4.app.Watson.OnOptionsItemSelectedListener; 
import android.support.v4.app.Watson.OnPrepareOptionsMenuListener; 

public class SherlockMapFragment extends SupportMapFragment 
     implements OnCreateOptionsMenuListener, 
     OnPrepareOptionsMenuListener, 
     OnOptionsItemSelectedListener { 
    private SherlockFragmentActivity mActivity; 

    public SherlockFragmentActivity getSherlockActivity() { 
     return mActivity; 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     if (!(activity instanceof SherlockFragmentActivity)) { 
      throw new IllegalStateException(getClass().getSimpleName() 
        + " must be attached to a SherlockFragmentActivity."); 
     } 
     mActivity = (SherlockFragmentActivity) activity; 

     super.onAttach(activity); 
    } 

    @Override 
    public void onDetach() { 
     mActivity = null; 
     super.onDetach(); 
    } 

    @Override 
    public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) { 
     onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater()); 
    } 

    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     // Nothing to see here. 
    } 

    @Override 
    public final void onPrepareOptionsMenu(android.view.Menu menu) { 
     onPrepareOptionsMenu(new MenuWrapper(menu)); 
    } 

    @Override 
    public void onPrepareOptionsMenu(Menu menu) { 
     // Nothing to see here. 
    } 

    @Override 
    public final boolean onOptionsItemSelected(android.view.MenuItem item) { 
     return onOptionsItemSelected(new MenuItemWrapper(item)); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Nothing to see here. 
     return false; 
    } 
} 

L'attività:

public class MainActivity extends SherlockFragmentActivity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
    } 
} 

Il layout di attività XML:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/root" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal" > 

    <fragment 
     android:id="@+id/fragment_map" 
     android:name=".ui.fragments.MapFragment" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:tag="tag_fragment_map" /> 

    <fragment 
     android:id="@+id/fragment_help" 
     android:name=".ui.fragments.HelpFragment" 
     android:layout_width="0dp" 
     android:layout_height="match_parent" 
     android:tag="tag_fragment_help" /> 
</FrameLayout> 

Il frammento mappa:

public class MapFragment extends SherlockMapFragment { 
    private GoogleMap mMap; 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View root = super.onCreateView(inflater, container, savedInstanceState); 
     mMap = getMap(); 
     return root; 
    } 
} 
+6

ho fatto questo come bene e funziona bene. Puoi anche inserire SherlockMapFragment nel tuo progetto principale se non vuoi fare scherzi con il progetto della libreria ABS. –

+0

Tutto fatto e ti ringrazio. Il prossimo problema è far funzionare correttamente. Si prega di vedere la mia altra domanda relativa al recupero delle mappe. http://stackoverflow.com/questions/13727992/google-maps-api-v2-failed-to-load-map-could-not-contact-google-servers/13728039#13728039 – StuStirling

+0

Sapete se questo codice potrebbe avere Qualche problema con l'utilizzo di un progetto Android Maven? Ho provato lo stesso codice e sto ottenendo l'errore segnalato qui: http://stackoverflow.com/questions/14004668/google-maps-android-v2-not-working-with-actionbarsherlock-fragment-activity –

3

Fondamentalmente quello che sono sicuro è che questa SupportMapFragment è totalmente fresco e forse il manutentore di ActionBarSherlock non aveva ancora avuto il tempo di aggiungerlo sul Progetto ABS.

Inoltre richiede API Lvl 8+, quindi è possibile rimuovere il supporto per i dispositivi API lvl 7 o attendere Jake per aggiungere il supporto per il nuovo SupportMapFragment.

Per altri lvls API è possibile trovare un lavoro qui intorno: http://xrigau.wordpress.com/2012/03/22/howto-actionbarsherlock-mapfragment-listfragment/

+0

Pual, vedere la mia modifica sopra. Grazie per la risposta – StuStirling

4

ho sentito che Jake non ha intenzione di fare anche molto di più di ABS di Google può essere portando il loro proprio ActionBar compatibile con le versioni precedenti. Penso che se ricordo male è stato discusso in uno degli Hangout di Google+ relativi ad Android.

Le nuove mappe richiede livello di API 8 in poi in modo ancora prima di preoccuparsi del ActionBar si incorrere in problemi se è necessario supportare livello di API 7.

mio consiglio sarebbe quello di produrre 2 file di layout uno per il livello 7 e e uno per 8+. Nel livello 7 usa l'ormai vecchio MapView sebbene lo stiano deprecando, il che dimostra per me che il livello API 7 non è necessariamente da considerare come obiettivo. Nel layout 8+ usa il nuovo sistema di mappe.

Per quanto riguarda l'ActionBar, ci sono porting di un'applicazione in questo momento e sono facilmente e con successo ha aggiunto una mappa a un ViewPager, creando il Frammento modo pianificato (piuttosto che in XML). L'abbiamo testato su più dispositivi.

Non abbiamo riscontrato problemi con il nuovo sistema di mappe come descritto nelle demo di Google con ABS. Abbiamo dichiarato il frammento in un layout XML e impostato come contenuto dell'attività. ActionBar viene visualizzato normalmente. L'attività è SherlockFragmentActivity.

+0

Puoi condividere il codice su come aggiungere la mappa tramite programma in un frammento. Sto cercando di aggiungerlo alla scheda Sherlock –

+0

Hai creato una sottoclasse di questo SupportMapFragment? Posso creare programmaticamente ma non se sottoclassi? – StuStirling

+0

E quando si scorre il 'ViewPager', non si hanno quegli artefatti neri tremolanti mentre il' MapFragment' si sposta sullo schermo? –

3

Ho provato ad implementare SupportMapFragment con ActionBarSherlock.

Funziona molto bene.

enter image description here

Di seguito è frammento di codice.

package com.example.newmapview; 

import android.os.Bundle; 
import android.widget.Toast; 
import com.actionbarsherlock.app.SherlockFragmentActivity; 
import com.actionbarsherlock.view.Menu; 
import com.actionbarsherlock.view.MenuItem; 
import com.actionbarsherlock.view.SubMenu; 
import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.SupportMapFragment; 

public class MainActivity extends SherlockFragmentActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     SupportMapFragment fragment = SupportMapFragment.newInstance(); 
     getSupportFragmentManager().beginTransaction() 
       .add(R.id.mapLayout, fragment).commit(); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 

     SubMenu subMenu = menu.addSubMenu("Type"); 

     subMenu.add("Normal"); 
     subMenu.add("SATELLITE"); 

     subMenu.getItem().setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); 

     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 

     if (item.getTitle().toString().equalsIgnoreCase("Normal")) { 
      Toast.makeText(this, "Clicked Normal", Toast.LENGTH_LONG).show(); 
      GoogleMap googleMap = ((SupportMapFragment) getSupportFragmentManager() 
        .findFragmentById(R.id.mapLayout)).getMap(); 

      if (googleMap != null) 
       googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 
      else 
       Toast.makeText(this, "GoogleMap is null", Toast.LENGTH_LONG) 
         .show(); 
     } else if (item.getTitle().toString().equalsIgnoreCase("SATELLITE")) { 
      Toast.makeText(this, "Clicked SATELLITE", Toast.LENGTH_LONG).show(); 
      GoogleMap googleMap = ((SupportMapFragment) getSupportFragmentManager() 
        .findFragmentById(R.id.mapLayout)).getMap(); 

      if (googleMap != null) 
       googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); 
      else 
       Toast.makeText(this, "GoogleMap is null", Toast.LENGTH_LONG) 
         .show(); 
     } 

     return true; 

    } 
} 

Spero che questo vi aiuterà.

+1

puoi condividere anche l'xml.Sto cercando di implementarlo all'interno di un frammento –

+0

Grazie per la risposta e sono contento che tu abbia funzionato in quanto mi mostra che è assolutamente possibile. Il problema ora è che ho bisogno di essere in grado di creare una sottoclasse di questo SupportMapFragment, tuttavia sto correndo in tutti i tipi di eccezioni cast di classe. Qualche idea? – StuStirling

+0

nel layout XML, modificare MapFragment a SupportMapFragment, dovrebbe assomigliare a questa: Gruzilkin

0
@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // toggle mapType 
    if (mapFragment != null) { 
     googleMap = mapFragment.getMap(); 
    } 
    switch (item.getItemId()) { 
    case R.id.action_normal: 
     googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 
     Toast.makeText(getActivity(), "normal", Toast.LENGTH_LONG).show(); 
     return true; 
    case R.id.action_satellite: 
     googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); 
     Toast.makeText(getActivity(), "satellite", Toast.LENGTH_LONG) 
       .show(); 
     return true; 
    case R.id.action_terrian: 
     googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN); 
     Toast.makeText(getActivity(), "terian", Toast.LENGTH_LONG).show(); 
     return true; 
    case R.id.action_hybrid: 
     googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); 
     Toast.makeText(getActivity(), "hybrid", Toast.LENGTH_LONG).show(); 
     return true; 
    default: 

     return super.onOptionsItemSelected(item); 
    } 
} 
+0

In che modo questo pezzo di codice è una risposta alla domanda? Si prega di espandere o eliminare. – laalto

+0

Controlla semplicemente mapfragment è nullo o non solo una volta e non è necessario controllare la mappa è nullo ogni volta mentre si cambia il tipo di mappa come mostrato nel codice precedente – Rahul

Problemi correlati