0

Tout fonctionne plus ou moins. Mais si le LocationFragment est recréé, l'application tombe.Erreur InflateException Android dans la mise en page de fragment avec SupportMapFragment (fragment recréé)

Manifest

<?xml version="1.0" encoding="utf-8"?> 
<manifest package="XX.XX.XXXXXXXX" 
xmlns:android="http://schemas.android.com/apk/res/android"> 
<uses-permission android:name="android.permission.GET_ACCOUNTS"/> 
<uses-permission android:name="android.permission.INTERNET"/> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
<uses-permission android:name="android.permission.CAMERA"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 

<uses-feature 
    android:glEsVersion="0x00020000" 
    android:required="true"/> 

<uses-feature android:name="android.hardware.camera" 
    android:required="true" /> 

<application 
    android:name=".App" 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme"> 

    <meta-data 
     android:name="com.google.android.geo.API_KEY" 
     android:value="@string/google_maps_key"/> 

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

    <activity 
     android:name=".ui.activities.LaunchActivity" 
     android:label="@string/app_name" 
     android:screenOrientation="portrait" 
     android:theme="@style/AppTheme.FullScreen" 
     android:windowSoftInputMode="stateAlwaysHidden|adjustResize"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN"/> 

      <category android:name="android.intent.category.LAUNCHER"/> 
     </intent-filter> 
    </activity> 
    <activity android:name=".ui.activities.MainActivity" 
     android:screenOrientation="portrait" 
     android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"/> 
    <activity android:name=".ui.activities.SettingsActivity" 
     android:screenOrientation="portrait" 
     android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"/> 
    <activity android:name="com.facebook.FacebookActivity" 
     android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation" 
     android:theme="@android:style/Theme.Translucent.NoTitleBar" 
     android:label="@string/app_name" /> 

    <meta-data 
     android:name="com.crashlytics.ApiKey" 
     android:value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"/> 

    <meta-data 
     android:name="com.facebook.sdk.ApplicationId" 
     android:value="@string/facebook_app_id"/> 
</application> 

public enum GeolocationState

import android.content.Context; 
import android.location.Address; 
import android.location.Geocoder; 
import android.location.Location; 
import android.location.LocationManager; 
import android.widget.Toast; 

import com.google.android.gms.maps.CameraUpdateFactory; 
import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.model.CameraPosition; 
import com.google.android.gms.maps.model.LatLng; 

import java.io.IOException; 
import java.util.List; 
import java.util.Locale; 

public enum GeolocationState { 
    INST; 

private static final String TAG = "Geolocation"; 

public static final long WAITING_TIME_MILLIS = 3000L; 
public static final float ACCURANCY_IN_METERS = 3f; 

private Context context; 
private LocationManager locationManager; 
private Geocoder geocoder; 

public void init(Context context) { 
    this.context = context; 
    locationManager = (LocationManager)  context.getSystemService(Context.LOCATION_SERVICE); 
    geocoder = new Geocoder(context, Locale.getDefault()); 
} 

public Address getAddress(Location location) { 
    try { 
     List<Address> addressList = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1); 

     if (addressList != null && !addressList.isEmpty()) { 
      return addressList.get(0); 
     } 

    } catch (IOException e) { 
     e.printStackTrace(); 
     Toast.makeText(context, "Помилка геопозиціонування", Toast.LENGTH_SHORT).show(); 
    } 
    return null; 
} 

public void mapPositioning(GoogleMap mMap, double latitude, double longitude){ 
    LatLng coordinates = new LatLng(latitude, longitude); 
    if(mMap!=null) { 
     mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(coordinates, 13)); 
     CameraPosition cameraPosition = new CameraPosition.Builder() 
       .target(coordinates) 
       .zoom(17) 
       .bearing(90) 
       .tilt(0) 
       .build(); 

      mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); 
     } 
    } 

    public LocationManager getLocationManager() { 
     return locationManager; 
    } 
} 

public class LocationFragment

import android.location.Address; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.support.v4.app.Fragment; 
import android.view.Gravity; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Button; 
import android.widget.LinearLayout; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.OnMapReadyCallback; 
import com.google.android.gms.maps.SupportMapFragment; 

import java.text.DecimalFormat; 

import butterknife.BindView; 
import butterknife.ButterKnife; 
import butterknife.Unbinder; 
import xx.xx.xxxxxxxx.R; 
import xx.xx.xxxxxxxx.services.ClaimState; 
import xx.xx.xxxxxxxx.services.GeolocationState; 
import xx.xx.xxxxxxxx.ui.activities.MainActivity; 

public class LocationFragment extends BaseFragment implements OnMapReadyCallback, GoogleMap.OnMyLocationButtonClickListener{ 

private static final String TAG = LocationFragment.class.getName(); 

private GoogleMap mMap; 
@BindView(R.id.positioning_text_view) 
TextView positioningText; 
@BindView(R.id.next_button) 
Button nextButton; 
private Unbinder unbinder; 

public static Fragment newInstance() { 
    return new LocationFragment(); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 

    View rootView = inflater.inflate(R.layout.fragment_location, container, false); 
//**INFLATE ERROR IN rootView WHEN YOU MOVE QUICKLY BETWEEN FRAGMENTS** 
    unbinder = ButterKnife.bind(this, rootView); 

    SupportMapFragment fragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map); 
    fragment.getMapAsync(this); 

    return rootView; 
} 

@Override 
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 

    nextButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      ((MainActivity) getActivity()).moveToNext(); 
     } 
    }); 
    nextButton.setVisibility(View.GONE); 
} 

@Override 
public void onResume() { 
    super.onResume(); 
    GeolocationState.INST.getLocationManager().requestLocationUpdates(
      LocationManager.GPS_PROVIDER, 
      GeolocationState.WAITING_TIME_MILLIS, 
      GeolocationState.ACCURANCY_IN_METERS, 
      locationListener); 
} 

@Override 
public void onPause() { 
    super.onPause(); 
    GeolocationState.INST.getLocationManager().removeUpdates(locationListener); 
} 

private LocationListener locationListener = new LocationListener() { 
    @Override 
    public void onLocationChanged(Location location) { 
     if(location != null && mMap != null) { 
      Address address = GeolocationState.INST.getAddress(location); 

      if (address != null) { 
       ClaimState.INST.getClaim().setCity(address.getLocality()); 
       ClaimState.INST.getClaim().setAddress(address.getAddressLine(0)); 
       positioningText.setText(ClaimState.INST.getFullAddress()); 
       nextButton.setVisibility(View.VISIBLE); 
      } 

      DecimalFormat df = new DecimalFormat("#.######"); 
      ClaimState.INST.getClaim().setLatitude(df.format(location.getLatitude()).replace(",", ".")); 
      ClaimState.INST.getClaim().setLongitude(df.format(location.getLongitude()).replace(",", ".")); 
      GeolocationState.INST.mapPositioning(mMap, location.getLatitude(), location.getLongitude()); 
     } 
    } 

    @Override 
    public void onProviderDisabled(String provider) { 
    } 

    @Override 
    public void onProviderEnabled(String provider) { 
    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
    } 
}; 

@Override 
public void onMapReady(GoogleMap googleMap) { 
    mMap = googleMap; 
    if(mMap != null) { 
     mMap.setMyLocationEnabled(true); 
     mMap.setOnMyLocationButtonClickListener(this); 
     mMap.getUiSettings().setCompassEnabled(false); 
    } 
} 

@Override 
public boolean onMyLocationButtonClick() { 
    return false; 
} 

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) { 
    super.setUserVisibleHint(isVisibleToUser); 
    if (isVisibleToUser && isResumed()){ 
     Toast toast = Toast.makeText(getContext(), "Bla-bla-bla", Toast.LENGTH_LONG); 
     LinearLayout layout = (LinearLayout) toast.getView(); 
     if (layout.getChildCount() > 0) { 
      TextView tv = (TextView) layout.getChildAt(0); 
      tv.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL); 
     } 
     toast.setGravity(Gravity.CENTER, 0, 0); 
     toast.show(); 
    } 
} 

@Override public void onDestroyView() { 
    super.onDestroyView(); 
    unbinder.unbind(); 
} 
} 

fragment_location.xml (Disposition)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 


<RelativeLayout 
    android:id="@+id/bottomPanel" 
    android:layout_width="match_parent" 
    android:layout_height="130dp" 
    android:layout_alignParentBottom="true" 
    android:background="@color/primaryColor"> 

    <TextView 
     android:id="@+id/positioning_text_view" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerHorizontal="true" 
     android:layout_marginTop="10dp" 
     android:text="@string/positioning_in_progress" 
     android:textColor="@android:color/white" 
     android:textSize="17sp"/> 

    <Button 
     android:id="@+id/next_button" 
     android:layout_width="wrap_content" 
     android:layout_height="50dp" 
     android:layout_alignParentBottom="true" 
     android:layout_alignParentRight="true" 
     android:layout_marginBottom="20dp" 
     android:layout_marginRight="20dp" 
     android:background="@drawable/button_background" 
     android:paddingLeft="45dp" 
     android:paddingRight="45dp" 
     android:text="@string/next" 
     android:textAllCaps="false" 
     android:textSize="17sp" 
     /> 
</RelativeLayout> 

<fragment 
    android:id="@+id/map" 
    class="com.google.android.gms.maps.SupportMapFragment" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_above="@+id/bottomPanel" 
    android:layout_alignParentTop="true" /> 

</RelativeLayout> 

printStackTrace

07-28 13:17:57.257 28765-28765/xx.xx.xxxxxxxx E/AndroidRuntime: FATAL EXCEPTION: main 
                   Process: xx.xx.xxxxxxxx, PID: 28765 
                   android.view.InflateException: Binary XML file line #40: Binary XML file line #40: Error inflating class fragment 
                    at android.view.LayoutInflater.inflate(LayoutInflater.java:539) 
                    at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
                    at xx.xx.xxxxxxxx.ui.fragments.LocationFragment.onCreateView(LocationFragment.java:55) 
                    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974) 
                    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) 
                    at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1430) 
                    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:732) 
                    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) 
                    at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570) 
                    at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141) 
                    at android.support.v4.view.ViewPager.populate(ViewPager.java:1177) 
                    at android.support.v4.view.ViewPager.populate(ViewPager.java:1025) 
                    at android.support.v4.view.ViewPager$3.run(ViewPager.java:254) 
                    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858) 
                    at android.view.Choreographer.doCallbacks(Choreographer.java:670) 
                    at android.view.Choreographer.doFrame(Choreographer.java:603) 
                    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) 
                    at android.os.Handler.handleCallback(Handler.java:739) 
                    at android.os.Handler.dispatchMessage(Handler.java:95) 
                    at android.os.Looper.loop(Looper.java:148) 
                    at android.app.ActivityThread.main(ActivityThread.java:5417) 
                    at java.lang.reflect.Method.invoke(Native Method) 
                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
                   Caused by: android.view.InflateException: Binary XML file line #40: Error inflating class fragment 
                    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:782) 
                    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 
                    at android.view.LayoutInflater.rInflate(LayoutInflater.java:835) 
                    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
                    at android.view.LayoutInflater.inflate(LayoutInflater.java:515) 
                    at android.view.LayoutInflater.inflate(LayoutInflater.java:423)  
                    at xx.xx.xxxxxxxx.ui.fragments.LocationFragment.onCreateView(LocationFragment.java:55)  
                    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)  
                    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)  
                    at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1430)  
                    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:732)  
                    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)  
                    at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)  
                    at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)  
                    at android.support.v4.view.ViewPager.populate(ViewPager.java:1177)  
                    at android.support.v4.view.ViewPager.populate(ViewPager.java:1025)  
                    at android.support.v4.view.ViewPager$3.run(ViewPager.java:254)  
                    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)  
                    at android.view.Choreographer.doCallbacks(Choreographer.java:670)  
                    at android.view.Choreographer.doFrame(Choreographer.java:603)  
                    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)  
                    at android.os.Handler.handleCallback(Handler.java:739)  
                    at android.os.Handler.dispatchMessage(Handler.java:95)  
                    at android.os.Looper.loop(Looper.java:148)  
                    at android.app.ActivityThread.main(ActivityThread.java:5417)  
                    at java.lang.reflect.Method.invoke(Native Method)  
                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)  
                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)  
                   Caused by: java.lang.IllegalArgumentException: Binary XML file line #40: Duplicate id 0x7f0e0104, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.SupportMapFragment 
                    at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2293) 
                    at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44) 
                    at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:186) 
                    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:746) 
                    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)  
                    at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)  
                    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)  
                    at android.view.LayoutInflater.inflate(LayoutInflater.java:515)  
                    at android.view.LayoutInflater.inflate(LayoutInflater.java:423)  
                    at xx.xx.xxxxxxxx.ui.fragments.LocationFragment.onCreateView(LocationFragment.java:55)  
                    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)  
                    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)  
                    at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1430)  
..... 

UPD: I have 4 fragments

CaptureFragment (1) - TypeFragment (2) - LocationFragment (3) - OverviewFragment (4)

Lorsque je déplace rapidement entre:

TypeFragment - LocationFragment

ou

LocationFragment - OverviewFragment

tout est ok.

Mais si je déménage CaptureFragment (1) -> TypeFragment (2) -> LocationFragment (3)

puis

LocationFragment (3) -> TypeFragment (2) -> CaptureFragment (1)

puis

CaptureFragment (1) -> TypeFragment (2)

il casse. Je sais que lorsque TypeFragment est créé, il est créé et l'activité suivante est CaptureFragment. À ce stade, l'application tombe.

Est-ce que quelqu'un sait comment le réparer?

Répondre

1

Voici comment je charge ma présentation de la carte dans un fragment:

private View view; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    if (view != null) { 
     ViewGroup parent = (ViewGroup) view.getParent(); 
     if (parent != null) 
      parent.removeView(view); 
    } 

    try { 
     view = inflater.inflate(R.layout.map_fragment_location, container, false); 
    } catch (InflateException e) { 
     /* map is already there, just return view as it is */ 
    } 

    ButterKnife.bind(this, view); 

    SupportMapFragment mapFragment = (SupportMapFragment)getChildFragmentManager().findFragmentById(R.id.map); 

    mapFragment.getMapAsync(this); 

    return view; 
} 

Cela permet de vérifier votre mise en page et si elle existe déjà, vous ne devez pas créer de nouveau!

S'il vous plaît essayer et laissez-moi savoir comment ça se passe!

+0

LocationFragment fonctionne bien, mais SupportFragmentMap ne fonctionne pas correctement (n'affiche pas la position actuelle), affiche uniquement la carte sans point d'emplacement. – Volodymyr

0

Il m'a aidé

private static View rootView; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 

     if (rootView == null) { 
      rootView = inflater.inflate(R.layout.fragment_location, container, false); 
     } 

     unbinder = ButterKnife.bind(this, rootView); 
     return rootView; 
    } 

LocationFragment et SupportMapFragment fonctionnent correctement.

Peut-être que ce n'est pas la meilleure solution. Si vous connaissez une meilleure solution, merci de la partager.