web-dev-qa-db-ja.com

IllegalStateException:パディング後のビューサイズが小さすぎます

Androidアプリを開発しています。このアプリでは、MapViewをフラグメントで表示しています。デバイスを回転させて、次のいずれかの方法でカメラを動かそうとした場合:

mapa.animateCamera(cameraUpdate);

または

mapa.moveCamera(cameraUpdate);

次に、アプリがクラッシュし、次のエラーが表示されます。

_Java.lang.IllegalStateException: View size is too small after padding
 at com.google.a.a.ab.b(Unknown Source)
 at com.google.maps.api.Android.lib6.gmm6.c.a.a(Unknown Source)
 at com.google.maps.api.Android.lib6.gmm6.c.a.a(Unknown Source)
 at com.google.maps.api.Android.lib6.d.dw.a(Unknown Source)
 at com.google.maps.api.Android.lib6.gmm6.c.a.a(Unknown Source)
 at com.google.maps.api.Android.lib6.d.et.a(Unknown Source)
 at com.google.Android.gms.maps.internal.j.onTransact(SourceFile:83)
 at Android.os.Binder.transact(Binder.Java:380)
 at com.google.Android.gms.maps.internal.IGoogleMapDelegate$zza$zza.moveCamera(Unknown Source)
 at com.google.Android.gms.maps.GoogleMap.moveCamera(Unknown Source)
 at com.accionplus.dbdplus.utils.MapUtils.centrarCamara(MapUtils.Java:88)
 at com.accionplus.dbdplus.utils.MapUtils.centrarCamara(MapUtils.Java:52)
 at com.accionplus.dbdplus.controladores.pdv.RutaProgramadaFragment$4.onMyLocationButtonClick(RutaProgramadaFragment.Java:274)
 at com.google.Android.gms.maps.GoogleMap$3.onMyLocationButtonClick(Unknown Source)
 at com.google.Android.gms.maps.internal.zzo$zza.onTransact(Unknown Source)
 at Android.os.Binder.transact(Binder.Java:380)
 at com.google.Android.gms.maps.internal.be.a(SourceFile:81)
 at com.google.maps.api.Android.lib6.d.ak.onClick(Unknown Source)
 at Android.view.View.performClick(View.Java:5156)
 at Android.view.View$PerformClick.run(View.Java:20755)
 at Android.os.Handler.handleCallback(Handler.Java:739)
 at Android.os.Handler.dispatchMessage(Handler.Java:95)
 at Android.os.Looper.loop(Looper.Java:145)
 at Android.app.ActivityThread.main(ActivityThread.Java:5832)
 at Java.lang.reflect.Method.invoke(Native Method)
 at Java.lang.reflect.Method.invoke(Method.Java:372)
 at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1399)
 at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:1194)
_

私はそれをグーグルで検索しましたが、成功しませんでした。グーグルで報告された問題であることがわかりましたが、この問題を「解決」するための回避策があるかどうかはわかりません。誰かが私を助けることができますか?

編集:コードを追加しています

_<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="com.accionplus.dbdplus.controladores.pdv.RutaProgramadaActivity">

    <LinearLayout
        Android:id="@+id/card_container"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:background="#15000000"
        Android:orientation="vertical"/>

    <LinearLayout
        Android:id="@+id/filtro_ll"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_below="@+id/card_container"
        Android:layout_margin="10dp"
        Android:gravity="left|top"
        Android:orientation="horizontal"
        Android:weightSum="1">

        <LinearLayout
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="0.7"
            Android:gravity="left|top"
            Android:orientation="vertical">

            <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:gravity="left"
                Android:orientation="horizontal"
                Android:weightSum="1">

                <ImageButton
                    Android:id="@+id/seleccionar_fecha_btn"
                    Android:layout_width="wrap_content"
                    Android:layout_height="35dp"
                    Android:background="@drawable/button"
                    Android:src="@drawable/ic_date"
                    Android:text="@string/buscar"
                    Android:textColor="@color/color_text_primary"/>

                <TextView
                    Android:id="@+id/fecha_consulta_tv"
                    Android:layout_width="match_parent"
                    Android:layout_height="35dp"
                    Android:layout_alignParentTop="true"
                    Android:layout_marginLeft="5dp"
                    Android:background="@drawable/rectangle"
                    Android:gravity="center"/>
            </LinearLayout>

            <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:layout_marginTop="10dp"
                Android:background="@drawable/rectangle">

                <Spinner
                    Android:id="@+id/tipo_ruta_sp"
                    Android:layout_width="fill_parent"
                    Android:layout_height="35dp"
                    Android:layout_gravity="center"
                    />
            </LinearLayout>

        </LinearLayout>
    </LinearLayout>

    <com.google.Android.gms.maps.MapView
        Android:id="@+id/map"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_below="@+id/filtro_ll"/>

    <ProgressBar
        Android:id="@+id/progress_bar"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_centerHorizontal="true"
        Android:foregroundGravity="center|top"
        Android:visibility="gone"/>

</RelativeLayout>
_

MyLocationButtonがクリックされたときは次のとおりです。

_mMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
            @Override
            public boolean onMyLocationButtonClick() {
                MapUtils.centrarCamara(getActivity(), mMap, mPuntosFinales);
                return true;
            }
        });
_

MapUtils.centrarCamara()メソッドは次のとおりです。

_public static void centrarCamara(Context contexto, GoogleMap mapa, LatLng... posiciones) {
        centrarCamara(contexto, mapa, Boolean.TRUE, posiciones);
    }

    public static void centrarCamara(Context contexto, GoogleMap mapa, boolean animado,
                                     LatLng... posiciones) {
        if (mapa == null) {
            return;
        }

        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        for (LatLng posicion : posiciones) {
            builder.include(posicion);
        }

        LatLngBounds bounds = builder.build();

        CameraUpdate cu = CameraUpdateFactory
                .newLatLngBounds(bounds, ViewUtils.dpAPixeles(MARKERS_DP_OFFSET, contexto));

        if (animado) {
            mapa.animateCamera(cu);
        } else {
            mapa.moveCamera(cu);
        }
    }
_

ViewUtils.dpAPixeles:

_public static int dpAPixeles(int dp, Context contexto) {
    Resources r = contexto.getResources();
    int px = (int) TypedValue
            .applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());

    return px;
}
_

例外は、mapa.moveCamera()またはmapa.animateCamera()が呼び出されたときに発生します。

11
Antonio

から ドキュメント

マップがレイアウトされるまで、このカメラの更新でカメラを変更しないでください(この方法で適切な境界ボックスとズームレベルを正しく決定するには、マップにサイズが必要です)。そうしないと、IllegalStateExceptionがスローされます。マップが使用可能であるだけでは不十分です(つまり、getMap()はnull以外のオブジェクトを返します)。マップを含むビューも、その寸法が決定されるようにレイアウトされている必要があります。これが発生したことを確認できない場合は、代わりにnewLatLngBounds(LatLngBounds、int、int、int)を使用して、マップのサイズを手動で指定してください。

したがって、問題は、mapa.animateCamera(cameraUpdate)またはmapa.moveCamera(cameraUpdate)を呼び出しているときにマップにサイズがないことである可能性があります。

とにかく、デバイスを回転させると例外がスローされると言うように、本当の問題は、newLatLngBoundsViewUtils.dpAPixeles(MARKERS_DP_OFFSET, contexto))を呼び出すときに使用しているパディングが問題を引き起こします(おそらく、パディングがビューの高さ/ 2よりも大きいですか?)。問題の解決に役立つ可能性のあるGoogleマップに関連する登録済みの問題( 477 )があります。そこに記載されているように、考えられる回避策の1つは、向きに応じてcameraUpdateを設定することです。

if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
    cu = CameraUpdateFactory.newLatLngBounds(bounds, ViewUtils.dpAPixeles(MARKERS_DP_OFFSET, contexto));
} else {
    // Use another method to get your camera update, for example CameraUpdateFactory.newLatLng(latLng);
}
7
antonio

Androidの場合、さまざまな解決策も試しましたが、最終的にクラッシュの主な理由を見つけました。

クラッシュの背後にある主な理由は、Android 7-7.1.2(API:24 – 25)での分割画面サポート/マルチウィンドウサポートです。

LatLngBoundsは、デバイス幅のパーセンテージに基づいてパディングが設定されているため、小さなデバイスでも機能します。これは、4インチディスプレイを搭載した小型デバイスでも機能しますが、Android 7.0のマルチウィンドウモードおよびそれ以前のマルチウィンドウモードをサポートするデバイス(Galaxy S7など)では失敗します。

マルチウィンドウモードでは高さが幅よりも小さくなる可能性があるため、解決策は幅と高さの間で最小のメトリックを選択することです。

final int width = getResources().getDisplayMetrics().widthPixels;
final int height = getResources().getDisplayMetrics().heightPixels;
final int minMetric = Math.min(width, height);
final int padding = (int) (minMetric * paddingPercentage);

要件に基づいてパディングの割合を選択できます。

移動カメラの場合、

googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), width, height, padding));

Animate Cameraの場合、

googleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), width, height, padding));
2
mini developer

react-native-maps でエラーが発生しました

解決策は、親ビューよりも前にレイアウトされていたため、マップビューコンポーネントに最小の幅と高さを与えることでした。

0
Ryan Knell

パディングを300から150に設定します。これでうまくいきます。

  map.animateCamera(
                CameraUpdateFactory.newLatLngBounds(boundsLatLongs, 150),
                1000, null);
0
Lalit kumar

以下の私の解決策は、解像度が小さい(1280x720)画面の約60%のマップで機能します(コードはKotlinです)

 val builder = LatLngBounds.Builder()
            //storing the MarkerOptions in a hashmap
            builder.include(markers[MarkerType.START]?.position)
            builder.include(markers[MarkerType.END]?.position)
            val bounds = builder.build()
            val width = resources.displayMetrics.widthPixels
            val  height = resources.displayMetrics.heightPixels
            val  minMetric = min(width, height)
            //divide the smallest screen value by 10 , to get a value around 100
            val  padding = minMetric.div(10) 
            val cu = CameraUpdateFactory.newLatLngBounds(bounds, padding)
            googleMap?.animateCamera(cu)
0
BMU