【问题标题】:Android Google Maps API - align custom button with existing buttonsAndroid Google Maps API - 将自定义按钮与现有按钮对齐
【发布时间】:2014-09-25 21:26:00
【问题描述】:

我正在尝试在 googlemap 上显示自定义按钮。

<Button
        android:id="@+id/button_backHome"
        android:layout_alignParentRight="true"
        android:layout_marginTop="50dp"
        android:layout_marginRight="11.5dp"
        android:layout_height="39dp"
        android:layout_width="39dp"
        android:background="@drawable/custom_button"
         />

这会在屏幕右上角的 googlemap 的“将相机设置为当前位置”按钮正下方显示按钮,但显然仅在我的测试设备上。在其他设备上,这些设置无法正确对齐按钮。

XXHDPI(银河 S4)

XHDPI (Nexus 10)

除了自己制作所有按钮之外,还有什么好的解决方案?我可以在不知道样式名称的情况下从 google 按钮继承边距吗?

我在这里几乎不知所措,任何帮助都会非常感激。

提前致谢!

【问题讨论】:

  • 发布一张图片它的样子和预期结果

标签: android google-maps button


【解决方案1】:

Google Maps 地图的父布局为RelativeLayout,因此自定义按钮与默认 Google Maps 控制按钮(适用于所有屏幕)对齐的最佳方法是将该自定义按钮置于与默认 Google Maps 控制按钮相同的布局中。假设我们使用 Google Maps 地图的活动具有如下布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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"
    tools:context="<YOUR_PACKAGE>.MainActivity">

    <fragment
        android:id="@+id/map_fragment"
        android:name="com.google.android.gms.maps.MapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <ImageView
        android:id="@+id/custom_button"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        android:visibility="gone"
        android:src="@drawable/ic_home_target"/>

</RelativeLayout>

自定义按钮视图最好使用ImageView,因为默认按钮布局中有 9 个补丁填充(details here),或者需要为默认的 Google 地图控制按钮设置额外的填充。现在它属于活动布局。所以在onMapReady(GoogleMap googleMap)我们应该:

1) 获取默认谷歌地图控制按钮的父视图;

2) 从根活动布局中移除自定义按钮视图;

3) 将自定义按钮视图添加到默认谷歌地图控制按钮的父视图(在 p.1 中定义);

4) 设置自定义按钮视图相对于默认 Google 地图控件按钮的对齐方式。

使用这样的源代码:

...
private GoogleMap mGoogleMap;
private MapFragment mMapFragment;
private ImageView mCustomButton;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mCustomButton = (ImageView) findViewById(R.id.custom_button);

    mMapFragment = (MapFragment) getFragmentManager()
            .findFragmentById(R.id.map_fragment);

    mMapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mGoogleMap = googleMap;

    // don't forget to allow LOCATION permission
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
        if (locationPermission == PackageManager.PERMISSION_GRANTED) {
            setConrolsPositions();
        } 
    } else {
        setConrolsPositions();
    }
}

void setConrolsPositions() {
    try {
        mGoogleMap.setMyLocationEnabled(true);
        mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);

        // get parent view for default Google Maps control button
        final ViewGroup parent = (ViewGroup) mMapFragment.getView().findViewWithTag("GoogleMapMyLocationButton").getParent();
        parent.post(new Runnable() {
            @Override
            public void run() {
                try {
                    // get view for default Google Maps control button
                    View defaultButton = mMapFragment.getView().findViewWithTag("GoogleMapMyLocationButton");

                    // remove custom button view from activity root layout
                    ViewGroup customButtonParent = (ViewGroup) mCustomButton.getParent();
                    customButtonParent.removeView(mCustomButton);

                    // add custom button view to Google Maps control button parent
                    ViewGroup defaultButtonParent = (ViewGroup) defaultButton.getParent();
                    defaultButtonParent.addView(mCustomButton);

                    // create layout with same size as default Google Maps control button
                    RelativeLayout.LayoutParams customButtonLayoutParams = new RelativeLayout.LayoutParams(defaultButton.getHeight(), defaultButton.getHeight());

                    // align custom button view layout relative to defaultButton
                    customButtonLayoutParams.addRule(RelativeLayout.ALIGN_LEFT, defaultButton.getId());
                    customButtonLayoutParams.addRule(RelativeLayout.BELOW, defaultButton.getId());

                    // add other settings (optional)
                    mCustomButton.setAlpha(defaultButton.getAlpha());
                    mCustomButton.setPadding(defaultButton.getPaddingLeft(), defaultButton.defaultButton(),
                            defaultButton.getPaddingRight(), defaultButton.getPaddingBottom());

                    // apply layout settings to custom button view
                    mCustomButton.setLayoutParams(customButtonLayoutParams);
                    mCustomButton.setVisibility(View.VISIBLE);


                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

并在Developer Options 中启用Show layout boundaries 选项,您应该会得到类似的结果:

如您所见,自定义按钮的大小与默认按钮布局完全相同,并位于其下方。

为了获得更好的效果,有必要调整自定义按钮字形(填充、透明度、颜色等)

或者可能是最简单的方法:根本不要使用默认的 Google 地图 "GoogleMapMyLocationButton" 按钮 - 将其 Enabled 属性设置为 false (mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);),但使用具有相同图标和功能的按钮的自定义布局由 @ 模拟987654323@ 与“目标主页”自定义按钮的布局相同。

【讨论】:

    【解决方案2】:

    您发布的图像中存在 dpi 问题,此外,在您发布的 xml 中,您仅对所有设备使用 1 个属性值android:layout_marginRight="11.5dp",这将在具有更高 dpi 的其他设备中失败,除了您第一次尝试的设备。

    解决方案:

    使用带 dpi 的 values 文件夹click here 了解它。

    您需要在每个 dpi 文件夹 ldpi、hdpi 等上为边距创建一个尺寸属性

    样本:

    <resources>
        <dimen name="margin_right">11.5dp</dimen> //this is located in hdpi values dimension
    </resources>
    

    另一个在 xhdpi 中

    <resources>
       <dimen name="margin_right">greater than hdpi</dimen> //this is located in xhdpi values dimension
    </resources>
    

    使用它只需拨打@dimension

    android:layout_marginRight="@dimension/margin_right"
    

    现在使用此解决方案将使您的设备能够在不同设备上选择正确的边距值。

    【讨论】:

    • 那么,每个 dpi 文件夹基本上都有不同的值吗?我可以试一试,假设谷歌按钮本身也处理 dp 中的边距。一个问题;大于 hdpi 表示 dp 值大于 hdmi 资源中使用的 11.5dp,对吗?
    • @ThomQ 是的,每个 dpi 文件夹都有不同的值,并且是大于 hdpi/11.5dp 或满足您的大小。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    • 2021-12-03
    • 2020-09-03
    • 1970-01-01
    相关资源
    最近更新 更多