2013-01-13 7 views
10

私は画面全体をカバーするマップと上に半透明のアクションバーを配置したマップフラグメント(API v2)をアプリケーションに追加しました。 アクティビティでは、android:windowActionBarOverlayがtrueに設定されたテーマが使用されます。透明なアクションバーの後ろにMyLocationボタンが隠れています。位置を変更する方法は?

マップ上に「MyLocationButton」も有効にしていますが、マップは画面の高さ全体をカバーしているため、ボタンはアクションバーで覆われています。

enter image description here

どのように私は地図の断片は、アクションバーの下またはその代わりに、画面の下部に位置ボタンを描画することができますか?

+0

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

答えて

0

フラグメントのコンテンツを正しくオフセットするには、?android:attr/actionBarSize(または、ActionBarSherlockを使用している場合は?attr/actionBarSize)を必ず使用してください。

達成しようとしている効果に応じて、この値を余白またはパディングとして適用します。私は、半透明のActionBarのために、あなたがまだマップをその背後に表示させ(そしてシースルー効果を維持するために)、パディングを試みたいと思っています。私はパディングが実際に '私の位置を特定する'ボタンを押し下げるかどうかを100%確信していません...もしそうでなければ、恐らくマージンを適用することは唯一の他の選択肢です。

この属性の例と詳細については、hereを参照してください。

+0

これは[マイロケーション]ボタンの位置を正しく変更しますが、ソリッドアクションバーの場合は透明なアクションバーオーバーレイが失われます。 margin属性はフラグメントの親とフラグメント自体に適用されますが、padding属性は親に設定されている場合にのみ機能します。いずれにしても、これはソリッドなアクションバーを生成します。 – qubz

1

これは、すでに私はアクションバーの下に自分の場所の検索ボタンを追加した一時的な回避策として(あなたはまだ持っていない場合は、それを主演してください)http://code.google.com/p/gmaps-api-issues/issues/detail?id=4670

拡張として出願されている(私の地図の断片はですRelativeLayoutので、私はちょうどalignParentRightを行い、適切なマージンを設定します)。

はその後、私のonClickHandler私はこれをしなかったで:

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; 
    } 
} 

私は、マップのAPIによって追加されたボタンのIDを見つけるためにhierarchyviewerを使用しました。それはちょうどマップに追加された2番目のビュー(そして不可視に設定されている)です。

LayoutParamsでこのボタンを非表示にするのではなく、オフにすることはできますが、このボタンは、MyLocationEnabledをtrueに設定した後にのみ表示されます。 (私のユースケースでは、gpsを起動する前にユーザーに決定させることを好みます)

+0

リンクありがとうございます。主演。 – machtnix

+0

それは私のために働いた!ありがとう – Coderji

6

独自のボタンを作成する代わりに、アクションバーのサイズに応じてビルドボタンを移動するだけです。
このコードは、私の作品とボタンが(Googleマップのように)あるべき場所のボタンだけです:

// 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); 
} 


あなたがそれを置く場合だけ(onActivityCreatedにこのコードを置きますonCreateOptionsMenuで、それは3.0の前のバージョンをサポートしていません - 。。そこでの生活サイクルが異なるため
もう一つは、「R.id.MainContainerは」マップフラグメントのコンテナである

私はusinよg ActionBar Sherlockですが、いくつかの変更を加えると、通常のアクションバーでも動作します。

+0

このコードを試してください、それがあなたのために働くなら答えとしてそれをマークするので、他の人がそれを使用するかもしれません。それは私のために働く.. –

+0

例のコードの2行目にfindViewByIdコールにその魔法の番号2を列挙するのは悪い習慣のようです。その番号を見つけた場所や、特にGoogleが文書化したIDでない場合は、その番号を変更できないかどうかについての説明は含まれません。彼らがIDを変更することを決めた場合、あなたは壊れてしまいます。 – Steven

+0

IDは階層ビューアからのものです。Googleが変更する場合は、変更する必要があります。しかし、あなたのリリースを制御し、GoogleがGoogleのプレイサービスを更新する場合は、それをリリースする前に実装する必要があります。最悪の場合、変更するかどうかは、階層ビューアで新しいIDを確認してください。これを修正するまでは、次のことを忘れないでください。http://code.google.com/p/gmaps-api -issues/issues/detail?id = 4670 –

3

以下(特にfixMapControlLocations)では、これをActionBarSherlockで取り上げました。

問題は、狭い画面にあった問題と、回転に応じて間違ったオフセットを持つ分割アクションバーです。 isNarrowチェック・シャーロックは、その狭いかどうかを私に知らせる。

もう1つ重要な変更は、myLocationの親の親ビューのパディングを設定することです。これは、内部のすべてのコントロールをピックアップし、階層ビューアに基づいてどのようにGoogleマップがそれをやっているです。 Googleの帰属ロゴは、サーフェスオブジェクト内のツリーの次の親にあります。見た目が簡単ではないので、おそらくコンプライアンスを維持するためにボトムアクションバーの透過効果を失うことになるでしょう。

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

あなたは最近追加されたGoogleMap.setPadding()方法でこれを達成することができます:APIドキュメントから

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

をこの方法では、あなたは、地図上の可視領域を定義することができ、マップの4つのエッジのそれぞれにパディングを設定することによって、エッジの周りのマップの部分が不明瞭になる可能性があることをマップに知らせることができます。マップ機能はパディングに適合させられる。例えば、ズームコントロール、コンパス、著作権表示やGoogleロゴが定義された領域内に収まるように移動され、カメラの動きは、可視領域の中心に対してであろう、など

またdescription of how padding works in GoogleMap参照。

関連する問題