Android ConstraintLayout 中的 MapFragment 失败

Android MapFragment in a ConstraintLayout fails

当 Mapfragment 位于 ConstraintLayout 内时,Android Studio 2.2 中的模板 Google 地图项目失败。只需将 ConstraintLayout 更改为 'RelativeLayout' 即可解决问题。

以下在 activity_main.xml 中工作正常 - 即。 google 地图出现在 phone。

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/constraintLayout"
    tools:context="tech.trilobite.geology.MainActivity">

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/map"
    android:name="com.google.android.gms.maps.MapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="tech.trilobite.geology.MainActivity"
    />
</RelativeLayout>

如果 'RelativeLayout' 更改为 'android.support.constraint.ConstraintLayout' 那么我会在日志中得到相同的信息,但我只是得到一个白屏 - 没有地图。

public class MainActivity extends Activity implements OnMapReadyCallback {
    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        //SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
        //        .findFragmentById(R.id.map);
        MapFragment mapFragment = (MapFragment) getFragmentManager()
            .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
     }


/**
 * Manipulates the map once available.
 * This callback is triggered when the map is ready to be used.
 * This is where we can add markers or lines, add listeners or move the camera. In this case,
 * we just add a marker near Sydney, Australia.
 * If Google Play services is not installed on the device, the user will be prompted to install
 * it inside the SupportMapFragment. This method will only be triggered once the user has
 * installed Google Play services and returned to the app.
 */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Add a marker in Sydney and move the camera
        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    }
}

Build.gradle ..

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"
    defaultConfig {
        applicationId "tech.trilobite.geology"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.0.1'
    compile 'com.google.android.gms:play-services:10.0.0'
    testCompile 'junit:junit:4.12'
    compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4'
}

.. 和不显示 Google 地图的 ConstraintLayout(只是一个白屏)..

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/constraintLayout"
    tools:context="tech.trilobite.geology.MainActivity">

    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:map="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"

        android:id="@+id/map"
        android:name="com.google.android.gms.maps.MapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="tech.trilobite.geology.MainActivity"
        />

</android.support.constraint.ConstraintLayout>

.. 和 'Android Monitor' 日志(这与 RelativeLayout 和 ConstraintLayout 相同,但前者有效而后者无效)..

11-26 09:14:24.569 30654-30654/? I/art: Late-enabling -Xcheck:jni
11-26 09:14:24.599 30654-30661/? E/art: Failed sending reply to debugger: Broken pipe
11-26 09:14:24.608 30654-30661/? I/art: Debugger is no longer active
11-26 09:14:24.608 30654-30661/? I/art: Starting a blocking GC Instrumentation
11-26 09:14:24.626 30654-30654/? W/System: ClassLoader referenced unknown path: /data/app/tech.trilobite.geology-1/lib/arm64
11-26 09:14:24.639 30654-30654/? I/InstantRun: Instant Run Runtime started. Android package is tech.trilobite.geology, real application class is null.
11-26 09:14:26.222 30654-30654/tech.trilobite.geology W/System: ClassLoader referenced unknown path: /data/app/tech.trilobite.geology-1/lib/arm64
11-26 09:14:26.267 30654-30654/tech.trilobite.geology I/FirebaseInitProvider: FirebaseApp initialization unsuccessful
11-26 09:14:26.432 30654-30654/tech.trilobite.geology I/zzai: Making Creator dynamically
11-26 09:14:26.558 30654-30654/tech.trilobite.geology W/System: ClassLoader referenced unknown path: 
11-26 09:14:26.651 30654-30654/tech.trilobite.geology W/System: ClassLoader referenced unknown path: /data/user/0/com.google.android.gms/app_chimera/m/00000018/n/arm64-v8a
11-26 09:14:26.706 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:26.721 30654-30654/tech.trilobite.geology I/Google Maps Android API: Google Play services client version: 10084000
11-26 09:14:26.735 30654-30654/tech.trilobite.geology I/Google Maps Android API: Google Play services package version: 10084440
11-26 09:14:26.758 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:26.784 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:26.799 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:26.811 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:26.825 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:26.844 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:26.855 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:26.887 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:26.887 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskWriteViolation
11-26 09:14:26.889 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:26.935 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:26.937 30654-30654/tech.trilobite.geology I/c: Token loaded from file. Expires in: 344773986 ms.
11-26 09:14:26.937 30654-30654/tech.trilobite.geology I/c: Scheduling next attempt in 344473 seconds.
11-26 09:14:27.014 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskWriteViolation
11-26 09:14:27.014 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskWriteViolation
11-26 09:14:27.037 30654-30706/tech.trilobite.geology D/NetworkSecurityConfig: No Network Security Config specified, using platform default
11-26 09:14:27.130 30654-30732/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:27.130 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:27.131 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskWriteViolation
11-26 09:14:27.302 30654-30735/tech.trilobite.geology I/Adreno: QUALCOMM build                   : 74df444, I409c65498b
                                                                Build Date                       : 06/22/16
                                                                OpenGL ES Shader Compiler Version: XE031.08.00.02
                                                                Local Branch                     : N16
                                                                Remote Branch                    : 
                                                                Remote Branch                    : 
                                                                Reconstruct Branch               : 
11-26 09:14:27.315 30654-30735/tech.trilobite.geology I/OpenGLRenderer: Initialized EGL, version 1.4
11-26 09:14:27.315 30654-30735/tech.trilobite.geology D/OpenGLRenderer: Swap behavior 1
11-26 09:14:27.599 30654-30750/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:27.895 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskReadViolation
11-26 09:14:27.897 30654-30654/tech.trilobite.geology W/f: Suppressed StrictMode policy violation: StrictModeDiskWriteViolation
11-26 09:14:29.151 30654-30733/tech.trilobite.geology W/DynamiteModule: Local module descriptor class for com.google.android.gms.googlecertificates not found.
11-26 09:14:29.160 30654-30733/tech.trilobite.geology I/DynamiteModule: Considering local module com.google.android.gms.googlecertificates:0 and remote module com.google.android.gms.googlecertificates:2
11-26 09:14:29.160 30654-30733/tech.trilobite.geology I/DynamiteModule: Selected remote version of com.google.android.gms.googlecertificates, version >= 2

这似乎是 gradle 的优化问题,您应该尝试禁用即时 运行 并禁用它:

buildTypes {
    release {
        minifyEnabled false
        shrinkResources false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
        minifyEnabled false
        shrinkResources false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

这看起来像是一个 ConstraintLayout 问题。您没有使用任何约束!

ConstraintLayout 使用约束让视图相对于彼此定位,也可以使用它们来定义视图的尺寸。

对于 ConstraintLayout 中的视图,match_parent 的正确等价物是将高度 and/or 宽度设置为 0dp(有时称为 "match constraints"),然后确保视图对其设置了适当的约束。你的情况:

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/constraintLayout"
    tools:context="tech.trilobite.geology.MainActivity">

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.MapFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        tools:context="tech.trilobite.geology.MainActivity"
        />

</android.support.constraint.ConstraintLayout>

此处片段的高度和宽度设置为 0dp,这意味着它会根据其约束来确定其大小。约束将 Fragment 的所有四个边连接到其父级的边缘,因此它将扩展以填充 space.

之前可能发生的情况是 Fragment 正在工作,但您看不到它,因为它的大小为零。