【问题标题】:Navigation drawer combined with google maps crashes导航抽屉结合谷歌地图崩溃
【发布时间】:2014-06-05 09:26:05
【问题描述】:

我尝试使用谷歌地图启动导航抽屉,但由于某种原因它让我崩溃了。 (它甚至不加载第一张地图)。 我认为问题出在适配器或 xml 文件上。 LogCat 说问题出在第 102 行:

        mDrawerList.setAdapter(new ArrayAdapter<String>(this,

但我找不到这条线有什么问题。 我附加了 xml 文件、Java 和 LogCat。 正如官方 Android 开发者网站中提到的那样,我非常关注……但我仍然不明白我的代码有什么问题。 我怀疑这是关于 XML 之一。也许 Fragment FrameLayout 需要随着drawerlayout.xml中地图的FrameLayout而改变? 我有点困惑。使应用程序运行而不会崩溃的解决方案是什么?(它崩溃了,并且不加载地图) 谢谢。

drawer_layout.xml

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->

<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<!-- The navigation drawer -->
<ListView android:id="@+id/left_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp"
    android:background="#111"/>

activitymain.xml

    <?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/map"
  android:name="com.google.android.gms.maps.MapFragment"
  android:layout_width="match_parent"
  android:layout_height="match_parent" />

MainActivity.Java

  import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.google.android.gms.location.LocationListener;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMyLocationButtonClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;

public class MainActivity extends Activity implements LocationListener {

    // maps&location global variables
    GoogleMap map;
    public double longitude;
    public double latitude;
    Location location;

    // navigation drawer global variables
    private String[] mNavigationTitles;
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;
    private CharSequence mDrawerTitle;
    private CharSequence mTitle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
                .getMap();
        map.setMyLocationEnabled(true);

        // get location code
        final Criteria criteria = new Criteria();
        final LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        lm.getBestProvider(criteria, true);
        final Location location = lm
                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
        // animates the camera in zoom 7 to the location of the user
        if (location != null) {
            latitude = location.getLatitude();
            longitude = location.getLongitude();
            LatLng UserLoc = new LatLng(latitude, longitude);
            map.animateCamera(CameraUpdateFactory.newLatLngZoom(UserLoc, 7));
        }
        // else {
        // Toast.makeText(getApplicationContext(), "cant get loc",
        // Toast.LENGTH_LONG).show();
        // }

        // LocationButtonListener
        map.setOnMyLocationButtonClickListener(new OnMyLocationButtonClickListener() {
            @Override
            public boolean onMyLocationButtonClick() {
                // if the Gps is off it openes a dialog to turn it off
                if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                    buildAlertMessageNoGps();
                } else /* if (location == null) */{
                    // if it on, animates to the current position
                    final Location location = lm
                            .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                    map.animateCamera(CameraUpdateFactory.newLatLngZoom(
                            new LatLng(location.getLatitude(), location
                                    .getLongitude()), 15));
                    return false;
                }
                return false;
            }
        });

        // navigation drawer declarations&adapter
        mNavigationTitles = getResources().getStringArray(
                R.array.Navigation_Drawer);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        // Set the adapter for the list view
        mDrawerList.setAdapter(new ArrayAdapter<String>(this,
                R.layout.drawer_layout, mNavigationTitles));
        // Set the list's click listener
        mDrawerList.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                // TODO Auto-generated method stub
                selectItem(position);
            }
        });
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.firstlogo, R.string.Yes, R.string.no) {

            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); // creates call to
                                            // onPrepareOptionsMenu()
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); // creates call to
                                            // onPrepareOptionsMenu()
            }
        };

        mDrawerLayout.setDrawerListener(mDrawerToggle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);
        // end of OnCreate function
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle your other action bar items...

        return super.onOptionsItemSelected(item);
    }

    private void selectItem(int position) {
        // Create a new fragment and specify the planet to show based on
        // position

        switch (position) {
        case 1:
            Toast.makeText(getApplicationContext(), "cant get loc",
                    Toast.LENGTH_LONG).show();

            break;

        default:
            break;
        }
        // Highlight the selected item, update the title, and close the drawer
        mDrawerList.setItemChecked(position, true);
        setTitle(mNavigationTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }

    @Override
    public void setTitle(CharSequence title) {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        setUpMapIfNeeded();
        super.onResume();
    }

    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the
        // map.
        if (map == null) {
            map = ((MapFragment) getFragmentManager()
                    .findFragmentById(R.id.map)).getMap();
            if (map != null) {
            }
        }
    }

    // function that opened an activity to turn on the GPS
    private void buildAlertMessageNoGps() {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("GPS is off ")
                .setCancelable(true)
                .setPositiveButton("Yes",
                        new DialogInterface.OnClickListener() {
                            public void onClick(final DialogInterface dialog,
                                    final int id) {
                                startActivity(new Intent(
                                        android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                            }
                        })
                .setNegativeButton("No", new DialogInterface.OnClickListener() {
                    public void onClick(final DialogInterface dialog,
                            final int id) {
                        dialog.cancel();
                    }
                });
        final AlertDialog alert = builder.create();
        alert.show();
    }

    @Override
    public void onLocationChanged(Location location) {
        longitude = location.getLongitude();
        latitude = location.getLatitude();
    }

}

LogCat:

 06-05 12:15:53.816: E/AndroidRuntime(22316): FATAL EXCEPTION: main
06-05 12:15:53.816: E/AndroidRuntime(22316): java.lang.RuntimeException: Unable to start activity ComponentInfo{nir.rauch.flantir/nir.rauch.flantir.MainActivity}: java.lang.NullPointerException
06-05 12:15:53.816: E/AndroidRuntime(22316):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2295)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at android.app.ActivityThread.access$700(ActivityThread.java:159)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at android.os.Handler.dispatchMessage(Handler.java:99)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at android.os.Looper.loop(Looper.java:137)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at android.app.ActivityThread.main(ActivityThread.java:5419)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at java.lang.reflect.Method.invokeNative(Native Method)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at java.lang.reflect.Method.invoke(Method.java:525)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at dalvik.system.NativeStart.main(Native Method)
06-05 12:15:53.816: E/AndroidRuntime(22316): Caused by: java.lang.NullPointerException
06-05 12:15:53.816: E/AndroidRuntime(22316):    at nir.rauch.flantir.MainActivity.onCreate(MainActivity.java:102)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at android.app.Activity.performCreate(Activity.java:5372)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
06-05 12:15:53.816: E/AndroidRuntime(22316):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2257)
06-05 12:15:53.816: E/AndroidRuntime(22316):    ... 11 more

【问题讨论】:

  • 102 行是什么?
  • @SimplePlan 这是第 102 行:" mDrawerList.setAdapter(new ArrayAdapter(this," 设置适配器。

标签: java android xml google-maps android-fragments


【解决方案1】:

您的实际问题在下面一行 替换

 setContentView(R.layout.activity_main); 

setContentView(R.layout.drawer_layout);

您绑定了错误的 xml,并且您没有在相同的活动中加载片段和抽屉 还要在创建时注释所有地图代码并将其放在新的片段类中......并将地图加载到片段类而不是活动类中。

【讨论】:

  • 我将其更改为“扩展片段”,但 Eclipse 显示了很多错误。你能更详细地描述一下吗?我也可以用 Activity 来做这件事(在 Android 开发者网站的演示上)
  • 不,我认为您不明白我能说什么。扩展活动没问题,只需创建新类“MyMapFragment 扩展片段”并删除主要活动中的所有加载映射代码。并将所有代码放在 MymapFragment 类中。并且在抽屉中的第一个孩子是你的 MyMapFragment 类。调用你的第一个抽屉孩子意味着 MyMapFragment。就是这样
  • 再次感谢。当我想从我的地图的 FragmentActivty 调用函数时,问题就开始了。它显示了很多错误。我不想只加载片段,我想加载所有“活动”。
  • 你为什么不明白你没有在同一本书上用抽屉加载地图,你同时做两件不同的事情
  • 我的建议是首先创建带有 3 个片段的抽屉,然后使用抽屉列表移动这些片段。
猜你喜欢
  • 2016-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多