[英]Android Java Google Map error when load second time
package com.example.cheng.freequeue;
import android.app.Fragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
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.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
public class MapPage extends Fragment implements GoogleMap.OnMarkerClickListener,OnMapReadyCallback {
private GoogleMap mGoogleMap;
private String address="myphpadress";
private InputStream is=null;
private String lat;
private String lng;
private String name;
private Marker data;
View myView;
ArrayList<returnLatLng> list = null;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
myView = inflater.inflate(R.layout.activity_map_page, container, false);
init();
getJSON(address);
list = new ArrayList<returnLatLng>();
return myView;
}
public void init()
{
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.mapFragment);
mapFragment.getMapAsync(this);
}
/** Called when the map is ready. */
@Override
public void onMapReady(GoogleMap map) {
mGoogleMap = map;
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(3.4496739,102.6010782),8.0f));
// Set a listener for marker click.
mGoogleMap.setOnMarkerClickListener(this);
}
/** Called when the user clicks a marker. */
@Override
public boolean onMarkerClick(final Marker marker) {
// Retrieve the data from the marker.
Integer clickCount = (Integer) marker.getTag();
// Check if a click count was set, then display the click count.
if (clickCount != null) {
clickCount = clickCount + 1;
marker.setTag(clickCount);
//Toast.makeText(getActivity(), "Click!", Toast.LENGTH_SHORT).show();
}
// Return false to indicate that we have not consumed the event and that we wish
// for the default behavior to occur (which is for the camera to move such that the
// marker is centered and for the marker's info window to open, if it has one).
return false;
}
//this method is actually fetching the json string
private void getJSON(final String urlWebService) {
/*
* As fetching the json string is a network operation
* And we cannot perform a network operation in main thread
* so we need an AsyncTask
* The constrains defined here are
* Void -> We are not passing anything
* Void -> Nothing at progress update as well
* String -> After completion it should return a string and it will be the json string
* */
class GetJSON extends AsyncTask<Void, Void, String> {
//this method will be called before execution
//you can display a progress bar or something
//so that user can understand that he should wait
//as network operation may take some time
@Override
protected void onPreExecute() {
super.onPreExecute();
}
//this method will be called after execution
//so here we are displaying a toast with the json string
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
getLatLng(s);
} catch (JSONException e) {
e.printStackTrace();
}
}
//in this method we are fetching the json string
@Override
protected String doInBackground(Void... voids) {
if(android.os.Debug.isDebuggerConnected())
android.os.Debug.waitForDebugger();
try {
//creating a URL
URL url = new URL(urlWebService);
//Opening the URL using HttpURLConnection
HttpURLConnection con = (HttpURLConnection) url.openConnection();
//StringBuilder object to read the string from the service
StringBuilder sb = new StringBuilder();
//We will use a buffered reader to read the string from service
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
//A simple string to read values from each line
String json;
//reading until we don't find null
while ((json = bufferedReader.readLine()) != null) {
//appending it to string builder
sb.append(json + "\n");
}
//finally returning the read string
return sb.toString().trim();
} catch (Exception e) {
return null;
}
}
}
//creating asynctask object and executing it
GetJSON getJSON = new GetJSON();
getJSON.execute();
}
private void getLatLng(String json) throws JSONException {
//creating a json array from the json string
JSONArray jsonArray = new JSONArray(json);
//creating a string array for listview
list.clear();
//looping through all the elements in json array
for (int i = 0; i < jsonArray.length(); i++) {
//getting json object from the json array
JSONObject obj = jsonArray.getJSONObject(i);
//getting the name from the json object and putting it inside string array
lat = obj.getString("Latitude");
lng=obj.getString("Longitude");
name=obj.getString("company_name");
Log.i("lat:", lat);
Log.i("lng:", lng);
Log.i("lng:", name);
list.add(new returnLatLng(lat,lng,name));
createMarker(Double.parseDouble(lat),Double.parseDouble(lng),name);
}
}
protected Marker createMarker(double latitude, double longitude, String title) {
return mGoogleMap.addMarker(new MarkerOptions()
.position(new LatLng(latitude, longitude))
.anchor(0.5f, 0.5f)
.title(title)
);
}
@Override
public void onDestroyView() {
super.onDestroyView();
MapFragment f = (MapFragment) getFragmentManager()
.findFragmentById(R.id.mapFragment);
if (f != null)
getFragmentManager().beginTransaction().remove(f).commit();
}
}
04-07 15:57:43.504 22910-22910/com.example.cheng.freequeue E/AndroidRuntime: FATAL EXCEPTION: main
android.view.InflateException: Binary XML file line #0: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at com.example.cheng.freequeue.MapPage.onCreateView(MapPage.java:44)
at android.app.Fragment.performCreateView(Fragment.java:1699)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)
at android.app.BackStackRecord.run(BackStackRecord.java:682)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:441)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5166)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:561)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Binary XML file line #0: Duplicate id 0x7f080070, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.MapFragment
at android.app.Activity.onCreateView(Activity.java:4811)
at android.support.v4.app.BaseFragmentActivityApi14.onCreateView(BaseFragmentActivityApi14.java:41)
at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:67)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at com.example.cheng.freequeue.MapPage.onCreateView(MapPage.java:44)
at android.app.Fragment.performCreateView(Fragment.java:1699)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)
at android.app.BackStackRecord.run(BackStackRecord.java:682)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:441)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5166)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:561)
at dalvik.system.NativeStart.main(Native Method)
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.cheng.freequeue.MapPage">
<fragment
android:id="@+id/mapFragment"
class="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="0dp"
android:layout_marginTop="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.294" />
</android.support.constraint.ConstraintLayout>
Can anyone help me ? 谁能帮我 ? I already try onDestroyView();
我已经尝试过onDestroyView(); replace android:name to class and try and catch method all from stackoverflow solution but still have the same problem.
将android:name替换为class并尝试从stackoverflow解决方案中捕获方法,但仍然存在相同的问题。 I've run debug I noticed that this
我已经运行调试,我注意到
myView = inflater.inflate(R.layout.activity_map_page, container, false);
On the first click it run without problem , myView will get the value from inflate. 第一次单击时,myView毫无问题地运行,它将从inflate获取值。 When I click second time to run the googleMap , although there is there contain same value inside inflate but myView will return null and direct to this error:
当我第二次单击运行googleMap时,尽管inflate中包含相同的值,但myView将返回null并直接导致此错误:
Binary XML file line #0: Error inflating class fragment
The Error is because, you are inflating fragments inside other fragments. 错误的原因是,您正在将其他片段内的片段膨胀。 Here is the Nested Fragment Documentation.
这是嵌套片段文档。
Change your layout into an empty container. 将您的布局更改为一个空容器。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapFragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
Then in the Fragment onViewCreated method: 然后在Fragment onViewCreated方法中:
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
FragmentManager fm = getChildFragmentManager();
SupportMapFragment mapFragment = (SupportMapFragment) fm.findFragmentByTag("mapFragment");
if (mapFragment == null) {
mapFragment = new SupportMapFragment();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.mapFragmentContainer, mapFragment, "mapFragment");
ft.commit();
fm.executePendingTransactions();
}
mapFragment.getMapAsync(callback);
}
Let me know if it helps. 让我知道是否有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.