隐藏在透明操作栏后面的MyLocation按钮,如何重新定位?

时间:2013-01-13 00:29:54

标签: android google-maps google-maps-android-api-2

我已将地图片段(API v2)添加到我的应用中,地图覆盖整个屏幕,顶部是半透明的操作栏。 活动使用 android:windowActionBarOverlay 设置为true的主题。

我还在地图上启用了“MyLocationButton”,但由于地图覆盖了屏幕的整个高度,因此按钮被操作栏覆盖。

enter image description here

如何让地图片段在操作栏下方或屏幕底部绘制位置按钮?

5 个答案:

答案 0 :(得分:6)

不要创建自己的按钮,只需根据操作栏大小移动内置按钮。
这段代码适合我,按钮就是按钮的位置(就像谷歌地图一样):

// 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”是地图片段的容器。

我正在使用ActionBar Sherlock,但它也适用于常规操作栏,只需进行一些修改。

答案 1 :(得分:3)

下面(特别是fixMapControlLocations)我用ActionBarSherlock解决了这个问题。

我遇到的问题是在狭窄的屏幕上,并且分割操作栏具有错误的偏移,具体取决于旋转。 isNarrow通过sherlock检查让我知道它是否狭窄。

另一个关键变化是我正在设置myLocation父级父视图的填充。这会获取内部的所有控件,并且基于hierarchyviewer是google maps正在执行的操作。 Google归因徽标位于Surface对象中树的下一个父级。看起来不容易移动,所以我可能最终会失去底部操作栏的透明效果以保持合规。

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 :(得分:3)

您可以使用最近添加的GoogleMap.setPadding()方法完成此操作:

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

来自API文档:

  

此方法允许您在地图上定义可见区域,通过在地图的四个边缘中的每一个上设置填充来向地图发信号通知边缘周围的地图部分可能被遮挡。地图功能将适应填充。例如,缩放控件,指南针,版权声明和Google徽标将移动到适合定义区域内,相机移动将相对于可见区域的中心等。

另见description of how padding works in GoogleMap

答案 3 :(得分: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;
   }
}

我使用了hierarchyviewer来查找maps api添加的按钮的id。它恰好是添加到地图中的第二个视图(并设置为不可见)。

当然,您可以使用LayoutParams来调整偏移此按钮而不是隐藏它,但只有在将setMyLocationEnabled设置为true后才会出现此按钮! (在我的用例中,我更愿意让用户在启动gps之前做出决定)

答案 4 :(得分:0)

确保使用?android:attr/actionBarSize(或?attr/actionBarSize,如果您正在使用ActionBarSherlock)来正确地抵消片段的内容。

根据您尝试完成的效果,将此值应用为边距或填充。我猜测因为半透明的ActionBar,你会想要尝试填充,以便仍然让地图出现在它后面(并保持透视效果)。我不是100%确定填充是否会实际移动'找到我'按钮...如果没有,那么可能应用保证金是你唯一的其他选择。

有关此属性的示例和详细信息,请参阅here