好的,所以我刚刚开始Android开发,基本上我的问题是标题描述的内容。到目前为止,我尝试创建一个默认的抽屉导航活动项目,并编写一个谷歌地图片段类,最后将其扩展到主要内容。
我想让它工作的原因是因为抽屉导航活动看起来很好,在它的主屏幕上有谷歌地图会很好。
通过阅读文档:http://developer.android.com/guide/components/fragments.html我知道,为了在另一个活动中成功显示片段,您需要首先创建一个扩展MapFragment或fragment的Google Maps类,然后在活动的布局文件中声明片段。
无论我尝试了什么,它都不会起作用。我已经成功绘制了谷歌地图,但它的类代码没有被调用,因此地图操作不存在。
负责谷歌地图的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));
}
}
}
注意:如果我用类似于"fragment fragment=new MapFragment();"的内容更改MyActivity类中的第73行"GMapsFragment fragment=new GMapsFraction()",那么它工作得很好,但当然GMapsFraction。相反,显示的是一个默认的gmaps,根本没有任何功能。然而,我不明白为什么我自己的gmaps片段的通货膨胀不会起作用。
之后,我明白了我必须在主xml中包含GoogleMaps片段。。下面是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类,但最终总是出错。
所以,在那封墙垃圾邮件之后,让我向你解释一下我的目标。我想使用安卓工作室默认生成的抽屉导航代码,并将其与主要内容上显示的谷歌地图结合使用。
任何启蒙都会很棒。在过去的6天里,我一直在寻找一个没有运气的解决方案。这一定是一个非常愚蠢的错误,我知道,但我被卡住了。
p.S:我看到过使用SupportMapFragment的例子,但我想让上面的代码正常工作,或者理解为什么如果是这样的话,这是不可能的。
将您的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>