【问题标题】:java.lang.IllegalArgumentException: No suitable parent found from the given view. Please provide a valid view. In arcgis Runtime developejava.lang.IllegalArgumentException:从给定视图中找不到合适的父级。请提供有效的观点。在 arcgis 运行时开发中
【发布时间】:2021-08-24 03:59:56
【问题描述】:

gradle的时候没有报错。当它安装在虚拟机上时,程序无法运行并显示以下错误。这是代码。这是 Android 开发。

MainActivity.java

package com.example.app; 
import java.util.List;
import android.annotation.SuppressLint;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.content.Intent;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import com.esri.arcgisruntime.data.ArcGISFeature;
import com.esri.arcgisruntime.data.FeatureEditResult;
import com.esri.arcgisruntime.loadable.LoadStatus;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.layers.ArcGISTiledLayer;
import com.esri.arcgisruntime.data.ServiceFeatureTable;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.GeoElement;
import com.esri.arcgisruntime.mapping.Viewpoint;
import com.esri.arcgisruntime.mapping.view.Callout;
import com.esri.arcgisruntime.mapping.view.DefaultMapViewOnTouchListener;
import com.esri.arcgisruntime.mapping.view.IdentifyLayerResult;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.google.android.material.snackbar.Snackbar;
import android.app.ProgressDialog;
import android.widget.Toast; 
public class MainActivity extends AppCompatActivity {
    private MapView mMapView;
    private Callout mCallout;
    private ArcGISFeature mSelectedArcGISFeature;
    private static final String TAG = MainActivity.class.getSimpleName();
    private android.graphics.Point mClickPoint;
    private Snackbar mSnackbarSuccess;
    private Snackbar mSnackbarFailure;
    private String mSelectedArcGISFeatureAttributeValue;
    private boolean mFeatureUpdated;
    private View mCoordinatorLayout;
    private ProgressDialog mProgressDialog;
    private ServiceFeatureTable mServiceFeatureTable;
    private FeatureLayer mFeatureLayer;

    @SuppressLint("ClickableViewAccessibility")
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mMapView = findViewById(R.id.mapView);
        String url = "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer";
        ArcGISTiledLayer arcGISTiledLayer = new ArcGISTiledLayer(url);
        Basemap basemap = new Basemap(arcGISTiledLayer);
        ArcGISMap arcGISMap = new ArcGISMap(basemap);
        mCallout = mMapView.getCallout();
        ServiceFeatureTable mServiceFeatureTable = new ServiceFeatureTable("http://192.168.1.103:6080/arcgis/rest/services/huda1/MapServer/0");
        FeatureLayer featureLayer = new FeatureLayer(mServiceFeatureTable);
        arcGISMap.getOperationalLayers().add(featureLayer);
        mFeatureLayer.setOpacity(0.8f);*/
        mMapView.setMap(arcGISMap);
        mMapView.setViewpoint(new Viewpoint(30.577421, 114.331955, 10000));
        //set an on touch listener to listen for click events
        // set an on touch listener to listen for click events
        mMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, mMapView) {
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {

                // get the point that was clicked and convert it to a point in map coordinates
                mClickPoint = new android.graphics.Point((int) e.getX(), (int) e.getY());

                // clear any previous selection
                mFeatureLayer.clearSelection();
                mSelectedArcGISFeature = null;
                mCallout.dismiss();

                // identify the GeoElements in the given layer
                final ListenableFuture<IdentifyLayerResult> identifyFuture = mMapView
                        .identifyLayerAsync(mFeatureLayer, mClickPoint, 5, false, 1);

                // add done loading listener to fire when the selection returns
                identifyFuture.addDoneListener(() -> {
                    try {
                        // call get on the future to get the result
                        IdentifyLayerResult layerResult = identifyFuture.get();
                        List<GeoElement> resultGeoElements = layerResult.getElements();
                        if (!resultGeoElements.isEmpty()) {
                            if (resultGeoElements.get(0) instanceof ArcGISFeature) {
                                mSelectedArcGISFeature = (ArcGISFeature) resultGeoElements.get(0);
                                // highlight the selected feature
                                mFeatureLayer.selectFeature(mSelectedArcGISFeature);
                                // show callout with the value for the attribute "typdamage" of the selected feature
                                mSelectedArcGISFeatureAttributeValue = (String) mSelectedArcGISFeature.getAttributes()
                                        .get("typdamage");
                                showCallout(mSelectedArcGISFeatureAttributeValue);
                                Toast.makeText(MainActivity.this, "Tap on the info button to change attribute value",
                                        Toast.LENGTH_SHORT).show();
                            }
                        } else {
                            // none of the features on the map were selected
                            mCallout.dismiss();
                        }
                    } catch (Exception e1) {
                        Log.e(TAG, "Select feature failed: " + e1.getMessage());
                    }
                });
                return super.onSingleTapConfirmed(e);
            }
        });

        mSnackbarSuccess = Snackbar
                .make(mCoordinatorLayout, "Feature successfully updated", Snackbar.LENGTH_LONG)
                .setAction("UNDO", view -> {
                    String snackBarText = updateAttributes(mSelectedArcGISFeatureAttributeValue) ?
                            "Feature is restored!" :
                            "Feature restore failed!";
                    Snackbar snackbar1 = Snackbar.make(mCoordinatorLayout, snackBarText, Snackbar.LENGTH_SHORT);
                    snackbar1.show();
                });
        mSnackbarFailure = Snackbar.make(mCoordinatorLayout, "Feature update failed", Snackbar.LENGTH_LONG);
    }

    /**
     * Function to read the result from newly created activity
     */
    @Override
    protected void onActivityResult(int requestCode,
                                    int resultCode, final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == 100) {
            // display progress dialog while updating attribute callout
            mProgressDialog.show();
            updateAttributes(data.getStringExtra("typdamage"));
        }
    }

    /**
     * Applies changes to the feature, Service Feature Table, and server.
     */
    private boolean updateAttributes(final String typeDamage) {

        // load the selected feature
        mSelectedArcGISFeature.loadAsync();

        // update the selected feature
        mSelectedArcGISFeature.addDoneLoadingListener(() -> {
            if (mSelectedArcGISFeature.getLoadStatus() == LoadStatus.FAILED_TO_LOAD) {
                Log.e(TAG, "Error while loading feature");
            }

            // update the Attributes map with the new selected value for "typdamage"
            mSelectedArcGISFeature.getAttributes().put("typdamage", typeDamage);

            try {
                // update feature in the feature table
                ListenableFuture<Void> mapViewResult = mServiceFeatureTable.updateFeatureAsync(mSelectedArcGISFeature);
                /*mServiceFeatureTable.updateFeatureAsync(mSelectedArcGISFeature).addDoneListener(new Runnable() {*/
                mapViewResult.addDoneListener(() -> {
                    // apply change to the server
                    final ListenableFuture<List<FeatureEditResult>> serverResult = mServiceFeatureTable.applyEditsAsync();

                    serverResult.addDoneListener(() -> {
                        try {

                            // check if server result successful
                            List<FeatureEditResult> edits = serverResult.get();
                            if (!edits.isEmpty()) {
                                if (!edits.get(0).hasCompletedWithErrors()) {
                                    Log.e(TAG, "Feature successfully updated");
                                    mSnackbarSuccess.show();
                                    mFeatureUpdated = true;
                                }
                            } else {
                                Log.e(TAG, "The attribute type was not changed");
                                mSnackbarFailure.show();
                                mFeatureUpdated = false;
                            }
                            if (mProgressDialog.isShowing()) {
                                mProgressDialog.dismiss();
                                // display the callout with the updated value
                                showCallout((String) mSelectedArcGISFeature.getAttributes().get("typdamage"));
                            }
                        } catch (Exception e) {
                            Log.e(TAG, "applying changes to the server failed: " + e.getMessage());
                        }
                    });
                });
            } catch (Exception e) {
                Log.e(TAG, "updating feature in the feature table failed: " + e.getMessage());
            }
        });
        return mFeatureUpdated;
    }

    /**
     * Displays Callout
     *
     * @param title the text to show in the Callout
     */
    private void showCallout(String title) {

        // create a text view for the callout
        RelativeLayout calloutLayout = new RelativeLayout(getApplicationContext());
        TextView calloutContent = new TextView(getApplicationContext());
        calloutContent.setId(R.id.textview);
        calloutContent.setTextColor(Color.BLACK);
        calloutContent.setTextSize(18);
        calloutContent.setPadding(0, 10, 10, 0);
        calloutContent.setText(title);
        RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        relativeParams.addRule(RelativeLayout.RIGHT_OF, calloutContent.getId());

        // create image view for the callout
        ImageView imageView = new ImageView(getApplicationContext());
        imageView
                .setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_info_outline_black_18dp));
        imageView.setLayoutParams(relativeParams);
        imageView.setOnClickListener(new ImageViewOnclickListener());

        calloutLayout.addView(calloutContent);
        calloutLayout.addView(imageView);

        mCallout.setGeoElement(mSelectedArcGISFeature, null);
        mCallout.setContent(calloutLayout);
        mCallout.show();
    }

    @Override
    protected void onPause() {
        mMapView.pause();
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mMapView.resume();
    }

    @Override
    protected void onDestroy() {
        mMapView.dispose();
        super.onDestroy();
    }

    /**
     * Defines the listener for the ImageView clicks
     */
    private class ImageViewOnclickListener implements View.OnClickListener {

        @Override public void onClick(View v) {
            Intent myIntent = new Intent(MainActivity.this, DamageTypesListActivity.class);
            startActivityForResult(myIntent, 100);
        }
    }
}

DamageTypesListActivity.java

package com.example.app;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

/**
 * Displays the Damage type options in a ListView.
 */
public class DamageTypesListActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.damage_types_listview);
        final String[] damageTypes = getResources().getStringArray(R.array.damage_types);

        ListView listView = (ListView) findViewById(R.id.listview);

        listView.setAdapter(new ArrayAdapter<>(this, R.layout.damage_types, damageTypes));

        listView.setTextFilterEnabled(true);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                Intent myIntent = new Intent();
                myIntent.putExtra("typdamage", damageTypes[position]); //Optional parameters
                setResult(100, myIntent);
                finish();
            }
        });

    }

    @Override
    public void onBackPressed() {
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-feature android:glEsVersion="0x00020000" android:required="true" />

    <application
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.DisplayAMapJava">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".DamageTypesListActivity"
            android:label="@string/select_damage_Type">
        </activity>
    </application>
</manifest>

字符串.xml

<resources>
    <string name="app_name">Display a map java</string>
    <string name="select_damage_Type">"Select new damage type"</string>
    <!-- Progress dialog messages -->
    <string name="progress_title">Updating attribute type</string>
    <string name="progress_message">Please wait&#8230;</string>
    <!-- Sample Strings -->
    <string name="sample_service_url">https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0</string>

    <string-array name="damage_types">
        <item>Destroyed</item>
        <item>Major</item>
        <item>Minor</item>
        <item>Affected</item>
        <item>Inaccessible</item>
    </string-array>

</resources>

下面是logcat消息

AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.app, PID: 21571
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.app/com.example.app.MainActivity}: java.lang.IllegalArgumentException: No suitable parent found from the given view. Please provide a valid view.
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: java.lang.IllegalArgumentException: No suitable parent found from the given view. Please provide a valid view.
        at com.google.android.material.snackbar.Snackbar.make(Snackbar.java:158)
        at com.example.app.MainActivity.onCreate(MainActivity.java:137)
        at android.app.Activity.performCreate(Activity.java:7802)
        at android.app.Activity.performCreate(Activity.java:7791)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7356) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 

【问题讨论】:

标签: java android android-snackbar


【解决方案1】:

在 Snackbar.make() 中使用之前初始化 CoordinatorLayout (mCoordinatorLayout)

使用 findViewById 初始化 mCoordinatorLayout mCoordinatorLayout = findViewById(layout_id)

【讨论】:

  • 如何操作?请说的具体点。谢谢。
  • 在哪里添加这个?谢谢。如果初始化mCoordinatorLayout,是否需要双mCoordinatorLayout mCoordinatorLayout?
猜你喜欢
  • 2018-05-19
  • 1970-01-01
  • 2018-12-14
  • 2019-05-21
  • 2020-01-15
  • 1970-01-01
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多