2013-01-13 2 views
10

Ich habe meiner App ein Kartenfragment (API v2) hinzugefügt, wobei die Karte den gesamten Bildschirm und eine halbtransparente Aktionsleiste darüber abdeckt. Die Aktivität verwendet ein Thema mit android: windowActionBarOverlay auf True festgelegt.MyLocation-Schaltfläche, die hinter einer transparenten Aktionsleiste verborgen ist, wie wird sie neu positioniert?

Ich habe auch die "MyLocationButton" auf der Karte aktiviert, aber da die Karte die gesamte Höhe des Bildschirms abdeckt, ist die Schaltfläche durch die Aktionsleiste abgedeckt.

enter image description here

Wie kann ich das Fragment der Karte den Standort Button in der Aktionsleiste oder am unteren Rand des Bildschirms anstelle ziehen lassen?

+0

http://stackoverflow.com/a/20750956/1066839 – John

Antwort

0

Stellen Sie sicher, dass Sie ?android:attr/actionBarSize (oder ?attr/actionBarSize, wenn Sie ActionBarSherlock verwenden) verwenden, um den Inhalt des Fragments korrekt zu versetzen.

Abhängig von dem Effekt, den Sie erzielen möchten, wenden Sie diesen Wert entweder als Rand oder Abstand an. Ich nehme an, dass Sie wegen der halbtransparenten ActionBar versuchen, Padding zu versuchen, um die Karte immer noch dahinter erscheinen zu lassen (und den Durchsicht-Effekt behalten). Ich bin mir nur nicht 100% sicher, ob das Auffüllen tatsächlich dazu führt, dass der Button "Finde mich" nach unten bewegt wird ... Wenn nicht, dann ist es wahrscheinlich die einzige Möglichkeit, eine Marge anzuwenden.

Ein Beispiel und weitere Details zu diesem Attribut finden Sie unter here.

+0

Dadurch wird die Schaltfläche "Meine Position" korrekt positioniert, aber die transparente Aktionsleisten-Überlagerung wird für eine feste Aktionsleiste verloren. Das margin-Attribut gilt für das Fragment-Parent und -Fragment selbst, aber das padding-Attribut funktioniert nur, wenn es im Parent-Element festgelegt ist. So oder so, das erzeugt einen soliden Aktionsbalken. – qubz

1

Dies wurde bereits als Erweiterung (bitte Sterne es, wenn Sie nicht bereits haben) eingereicht worden http://code.google.com/p/gmaps-api-issues/issues/detail?id=4670

als eine vorübergehende Lösung ich meine eigene Fundort Taste unterhalb des ActionBar (meine Karte Fragment ist in einem hinzugefügt haben RelativeLayout, also habe ich gerade ParentRight ausgerichtet und den entsprechenden Rand oben gesetzt).

Da ist in meinem onClickHandler Ich tat dies:

public void onClickHandler(View target) { 
    switch (target.getId()) { 
     case R.id.my_fml_btn:   
     mMap.setMyLocationEnabled(true); 
     View fmlBtn = mMapWrapper.findViewById(2); //mMapWrapper is my RelativeLayout 
     if (fmlBtn != null) fmlBtn.setVisibility(View.INVISIBLE); 
     break; 
    } 
} 

I hierarchyviewer verwendet, um die ID der Schaltfläche zu finden, die von den Karten api aufgenommen. Es ist zufällig die zweite Ansicht, die der Karte hinzugefügt wurde (und auf unsichtbar gesetzt wurde).

Sie können natürlich mit LayoutParams herumfummeln, um diese Schaltfläche zu verschieben, anstatt sie auszublenden, aber diese Schaltfläche wird nur angezeigt, nachdem Sie setMyLocationEnabled auf true gesetzt haben! (in meinem Anwendungsfall lasse ich den Benutzer lieber entscheiden, bevor er den GPS auslöst)

+0

Danke für den Link. markiert. – machtnix

+0

Es hat für mich funktioniert! Danke – Coderji

6

Anstatt einen eigenen Button zu erstellen, verschiebe einfach den Button "Build in" entsprechend der Größe der Aktionsleiste.
Dieser Code funktioniert für mich und die Taste ist genau dort, wo Sie die Taste (wie in Google Maps) sein sollte:

// Gets the my location button 
View myLocationButton = getSherlockActivity().findViewById(R.id.MainContainer).findViewById(2); 

// Checks if we found the my location button   
if (myLocationButton != null){ 
     int actionBarHeight = 0; 
     TypedValue tv = new TypedValue(); 

      // Checks if the os version has actionbar in it or not 
      if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){ 
       if (getSherlockActivity().getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) 
       actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics()); 
      } 
      // Before the action bar was added to the api 
      else if(getSherlockActivity().getTheme().resolveAttribute(com.actionbarsherlock.R.attr.actionBarSize, tv, true)){ 
       actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics()); 
      } 

     // Sets the margin of the button 
     ViewGroup.MarginLayoutParams marginParams = new ViewGroup.MarginLayoutParams(myLocationButton.getLayoutParams()); 
     marginParams.setMargins(0, actionBarHeight + 20, 20, 0); 
     RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams); 
     layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE); 
     myLocationButton.setLayoutParams(layoutParams); 
} 


diesen Code Einfach in der onActivityCreated (wenn Sie es setzen wird im onCreateOptionsMenu, unterstützen sie nicht Version vor 3.0 - weil der Lebenszyklus dort anders ist
Eine andere Sache, die „R.id.MainContainer“ ist der Behälter der Karte Fragment

ich bin usin.. g ActionBar Sherlock, aber es wird auch mit ein paar Modifikationen für reguläre Aktionsleiste funktionieren.

+0

Bitte versuchen Sie diesen Code und wenn es für Sie funktioniert, markieren Sie es als die Antwort, so können andere Leute es verwenden. Es funktioniert für mich .. –

+0

Es scheint mir eine schlechte Übung zu sein, diese magische Zahl 2 in Ihrem findViewById-Aufruf in der zweiten Zeile Ihres Beispielcodes aufgeführt zu haben. Sie geben keine Erklärung dazu an, wo Sie diese Nummer gefunden haben und ob wir uns darauf verlassen können, dass sich diese Zahl nicht ändert, insbesondere wenn es sich nicht um eine von Google dokumentierte ID handelt. Wenn sie sich dazu entschließen, die ID zu ändern, sind Sie kaputt. – Steven

+0

Die ID stammt vom Hierarchieviewer .. Und ich stimme zu, wenn Google es ändert, müssen Sie es auch ändern. Aber du kontrollierst deine Veröffentlichung und wenn Google ihre Google-Play-Dienste aktualisiert, musst du sie implementieren, bevor du sie veröffentlichst. Im schlimmsten Fall, wenn sie es ändern, überprüfen Sie die neue ID in der Hierarchieviewer. Und vergessen Sie nicht, dass dies nur, bis sie das beheben werden: http://code.google.com/p/gmaps-api -issues/issues/details? id = 4670 –

3

Unten (speziell in fixMapControlLocations) habe ich dies mit ActionBarSherlock angesprochen.

Probleme, die ich hatte, waren auf schmalen Bildschirmen und die Split-Action-Leiste hatte den falschen Offset abhängig von der Rotation. Die isNarrow Kontrolle durch Sherlock lässt mich wissen, ob es eng ist.

Eine weitere wichtige Änderung ist die Festlegung der Auffüllung der übergeordneten Ansicht von myLocation. Dies greift alle Steuerelemente auf und basierend auf dem Hierarchieviewer funktioniert Google Maps. Das Google-Attributionslogo befindet sich auf dem nächsten übergeordneten Baum in einem Surface-Objekt. Wenn man nicht so aussieht, ist es leicht zu bewegen, also werde ich wahrscheinlich am Ende den Transparenzeffekt der unteren Aktionsleiste verlieren, um in Übereinstimmung zu bleiben.

protected void onCreate(Bundle savedInstanceState) { 
    getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY); 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.map); 
    setUpMapIfNeeded(); 

    getSupportActionBar().setBackgroundDrawable(d); 
    getSupportActionBar().setSplitBackgroundDrawable(d); 
} 

private void setUpMapIfNeeded() { 
    // Do a null check to confirm that we have not already instantiated the 
    // map. 
    if (map == null) { 
     // Try to obtain the map from the SupportMapFragment. 
     map = ((SupportMapFragment) getSupportFragmentManager() 
       .findFragmentById(R.id.map)).getExtendedMap(); 

     // Check if we were successful in obtaining the map. 
     if (map != null) { 
      setUpMap(); 
     } 
    } 
} 

private void setUpMap() { 
    fixMapControlLocations(); 
    ..... 
} 

private void fixMapControlLocations() { 
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() 
      .findFragmentById(R.id.map); 
    int actionBarHeight = 0; 
    TypedValue tv = new TypedValue(); 
    if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) 
    { 
     actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics()); 
    } 

    View myLocationParent = ((View)mapFragment.getView().findViewById(1).getParent()); 
    View myLocationParentParent = ((View)myLocationParent.getParent()); 
    myLocationParentParent.setPadding(0, actionBarHeight, 0, isNarrow()?actionBarHeight:0); 
} 

public boolean isNarrow() { 
    return ResourcesCompat.getResources_getBoolean(getApplicationContext(), 
      R.bool.abs__split_action_bar_is_narrow); 
} 
2

Sie erreichen dies mit der kürzlich hinzugefügt GoogleMap.setPadding() Methode:

map.setPadding(leftPadding, topPadding, rightPadding, bottomPadding); 

Aus der API-Dokumentation:

Diese Methode ermöglicht es Ihnen, einen sichtbaren Bereich auf der Karte zu definieren, um der Karte zu signalisieren, dass Teile der Karte um die Kanten herum verdeckt werden können, indem auf jeder der vier Kanten der Karte eine Füllung gesetzt wird. Kartenfunktionen werden an das Padding angepasst. Zum Beispiel werden die Zoomsteuerung, Kompass, Copyright-Vermerke und Google-Logo bewegt werden innerhalb des definierten Bereichs zu passen, werden Kamerabewegungen in der Mitte des sichtbaren Bereichs relativ seine usw.

Auch die description of how padding works in GoogleMap sehen.