无法使用导航抽屉绘制Google Maps v2

时间:2014-10-10 16:56:40

标签: android google-maps android-studio navigation-drawer android-maps-v2

好的,所以我刚开始使用Android开发,基本上我的问题是标题所描述的。我到目前为止尝试的是创建一个默认的抽屉导航活动项目并编写一个谷歌地图片段类,最后将其膨胀到主要内容。

我希望这个工作的原因是因为抽屉导航活动看起来不错,在主屏幕上安装谷歌地图会很不错。

通过阅读文档:http://developer.android.com/guide/components/fragments.html我了解为了在另一个活动中成功显示片段,您需要首先创建一个扩展MapFragment或Fragment的Google Maps类,然后在活动的布局文件中声明该片段

无论我尝试什么,它都无法运作。我已成功绘制Google地图,但未调用其类代码,因此不存在地图操作。

谷歌地图负责GMapsFragment类(我认为下面标记的行(35)导致错误与地图xml文件一起):

package com.example.s0me0n3.ytgooglemapstut;

import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;


public class GMapsFragment extends Fragment {

    public MapView mapView;
    private static GoogleMap googleMap;


    public GMapsFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        Log.w("GMAPS", "Map place 1");
        // **********************************************************************************
        // The line below throws an inflation error when trying to parse the fragment_map xml
        // **********************************************************************************
        View rootView = inflater.inflate(R.layout.fragment_map, container, false);
        // Log.w("GMAPS", "Map place 1");

        if (googleMap != null)
            setUpMap();
        if (googleMap == null) {
            googleMap = ((MapFragment) MyActivity.fragmentManager.findFragmentById(R.id.ContactMapView)).getMap();
            if (googleMap != null) {
                setUpMap();
            }
        }

        return rootView;
    }

    private static void setUpMap() {
        googleMap.setMyLocationEnabled(true);
        googleMap.addMarker(new MarkerOptions().position(new LatLng(41.009471, 28.916134)).title("baslik"));
        googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(41.009471, 28.916134), 12.0f));
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (googleMap != null) {
            MyActivity.fragmentManager.beginTransaction()
                    .remove(MyActivity.fragmentManager.findFragmentById(R.id.ContactMapView))
                    .commit();
            googleMap = null;
        }
    }
}

和主要活动类MyActivity:

package com.example.s0me0n3.ytgooglemapstut;

import android.app.Activity;

import android.app.ActionBar;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.widget.DrawerLayout;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.maps.MapFragment;


public class MyActivity extends Activity
        implements NavigationDrawerFragment.NavigationDrawerCallbacks {


    public static FragmentManager fragmentManager;
    /**
     * Fragment managing the behaviors, interactions and presentation of the navigation drawer.
     */
    private NavigationDrawerFragment mNavigationDrawerFragment;


    /**
     * Used to store the last screen title. For use in {@link #restoreActionBar()}.
     */
    private CharSequence mTitle;

    // private GMapsFragment _gmaps;

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

        mNavigationDrawerFragment = (NavigationDrawerFragment)
                getFragmentManager().findFragmentById(R.id.navigation_drawer);
        mTitle = getTitle();

        // _gmaps = (GMapsFragment)
        //        getFragmentManager().findFragmentById(R.id.ContactMapView);

        // FragmentTransaction fragmentTransaction = _gmaps.beginTransaction();


        // Set up the drawer.
        mNavigationDrawerFragment.setUp(
                R.id.navigation_drawer,
                (DrawerLayout) findViewById(R.id.drawer_layout));

        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        // *** The Note below is pointing here! ***
        GMapsFragment fragment = new GMapsFragment();
        fragmentTransaction.add(R.id.container, fragment);
        fragmentTransaction.commit();

    }

    @Override
    public void onNavigationDrawerItemSelected(int position) {
        // update the main content by replacing fragments
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
                .commit();
    }

    public void onSectionAttached(int number) {
        switch (number) {
            case 1:
                mTitle = getString(R.string.title_section1);
                break;
            case 2:
                mTitle = getString(R.string.title_section2);
                break;
            case 3:
                mTitle = getString(R.string.title_section3);
                break;
        }
    }

    public void restoreActionBar() {
        ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setTitle(mTitle);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (!mNavigationDrawerFragment.isDrawerOpen()) {
            // Only show items in the action bar relevant to this screen
            // if the drawer is not showing. Otherwise, let the drawer
            // decide what to show in the action bar.
            getMenuInflater().inflate(R.menu.my, menu);
            restoreActionBar();
            return true;
        }
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            // showMsg("Settings reeee");
            // Log.w("MyActivity", "Will now log u out...");
            Intent intent = new Intent();
            intent.setClass(MyActivity.this, SetPreferenceActivity.class);
            startActivityForResult(intent, 0);
            // return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void showMsg(String msg) {
        Toast toast = Toast.makeText(this, msg, Toast.LENGTH_LONG);
        toast.setGravity(Gravity.CENTER, toast.getXOffset() / 2, toast.getYOffset() / 2);
        toast.show();
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        private static final String ARG_SECTION_NUMBER = "section_number";

        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */
        public static PlaceholderFragment newInstance(int sectionNumber) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        }

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_my, container, false);
            return rootView;
        }

        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            ((MyActivity) activity).onSectionAttached(
                    getArguments().getInt(ARG_SECTION_NUMBER));
        }
    }

}

注意:如果我更改第73行“GMapsFragment fragment = new GMapsFragment();”在MyActivity类中使用类似“Fragment fragment = new MapFragment();”的内容然后它工作正常,但当然GMapsFragment没有运行。相反,显示的默认gmaps根本没有功能。但是,我不明白为什么我自己的gmaps片段的膨胀不起作用。

之后,我知道我必须在主xml中包含Google Maps片段..所以这里是activity_my.xml:

<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MyActivity">

    <!-- As the main content view, the view below consumes the entire
         space available using match_parent in both dimensions. -->
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- android:layout_gravity="start" tells DrawerLayout to treat
         this as a sliding drawer on the left side for left-to-right
         languages and on the right side for right-to-left languages.
         If you're not building against API 17 or higher, use
         android:layout_gravity="left" instead. -->
    <!-- The drawer is given a fixed width in dp and extends the full height of
         the container. -->

    <fragment android:id="@+id/navigation_drawer"
        android:layout_width="@dimen/navigation_drawer_width"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:name="com.example.s0me0n3.ytgooglemapstut.NavigationDrawerFragment"
        tools:layout="@layout/fragment_navigation_drawer" />

</android.support.v4.widget.DrawerLayout>

和fragment_map.xml:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    android:id="@+id/ContactMapView"
    android:name="com.google.android.gms.maps.MapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
 />

这是我的AndroidManifest.xml:

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

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <permission android:name="com.example.s0me0n3.ytgooglemapstut.permission.MAPS_RECEIVE" android:protectionLevel="signature" />
    <uses-permission android:name="com.example.s0me0n3.ytgooglemapstut.permission.MAPS_RECEIVE" />
    <uses-permission android:name="com.example.s0me0n3.ytgooglemapstut.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>
    <uses-permission android:name="com.example.s0me0n3.ytgooglemapstut.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="com.example.s0me0n3.ytgooglemapstut.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
        <activity
            android:name=".MyActivity"
            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=".SetPreferenceActivity"
            android:label="User Settings" >
        </activity>

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="AIzaSyCoyacHtM9Nl0rjDYFJqV9wUQfiN6OlDOU"/>
    </application>

</manifest>

运行应用后我收到的Logcat错误是:

10-10 12:44:55.420    8017-8017/com.example.s0me0n3.ytgooglemapstut E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.s0me0n3.ytgooglemapstut, PID: 8017
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.s0me0n3.ytgooglemapstut/com.example.s0me0n3.ytgooglemapstut.MyActivity}: android.view.InflateException: Binary XML file line #1: Error inflating class fragment
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
            at android.app.ActivityThread.access$800(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class fragment
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:714)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:469)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
            at com.example.s0me0n3.ytgooglemapstut.GMapsFragment.onCreateView(GMapsFragment.java:35)
            at android.app.Fragment.performCreateView(Fragment.java:1700)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1040)
            at android.app.Activity.onCreateView(Activity.java:4805)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:690)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:469)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
            at com.example.s0me0n3.ytgooglemapstut.GMapsFragment.onCreateView(GMapsFragment.java:35)
            at android.app.Fragment.performCreateView(Fragment.java:1700)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
            at android.app.BackStackRecord.run(BackStackRecord.java:684)
            at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
            at android.app.Activity.performStart(Activity.java:5240)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2168)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
            at android.app.ActivityThread.access$800(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.IllegalArgumentException: Binary XML file line #1: Duplicate id 0x7f050017, tag null, or parent id 0x7f050015 with another fragment for com.google.android.gms.maps.MapFragment
            at android.app.Activity.onCreateView(Activity.java:4791)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:690)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:469)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
            at com.example.s0me0n3.ytgooglemapstut.GMapsFragment.onCreateView(GMapsFragment.java:35)
            at android.app.Fragment.performCreateView(Fragment.java:1700)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1040)
            at android.app.Activity.onCreateView(Activity.java:4805)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:690)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:469)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
            at com.example.s0me0n3.ytgooglemapstut.GMapsFragment.onCreateView(GMapsFragment.java:35)
            at android.app.Fragment.performCreateView(Fragment.java:1700)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
            at android.app.BackStackRecord.run(BackStackRecord.java:684)
            at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
            at android.app.Activity.performStart(Activity.java:5240)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2168)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
            at android.app.ActivityThread.access$800(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
            at dalvik.system.NativeStart.main(Native Method)

最后的话......我尝试从其他xml文件或my_activity.xml运行GMapsFragment类,但我总是遇到错误。

所以,在那个墙垃圾邮件之后,让我向你解释我的目标。我想使用Android Studio中默认生成的Drawer Nav代码以及主要内容上显示的Google地图。

任何启示都会很棒。我一直在寻找过去6天没有运气的解决方案。它必须是一个非常愚蠢的错误,我知道,但我被卡住了。

P.S:我看过使用SupportMapFragment的例子,但我想让上面的代码工作或者理解为什么这样做是不可能的。

1 个答案:

答案 0 :(得分:0)

将fragment_map.xml更改为:

<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">

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

</RelativeLayout>