2015-07-10 70 views
1

我使用ActionBar選項卡,有三個選項卡,第三個選項卡具有Google地圖。 當我在第一和第三之間切換時,它在第一和第二之間崩潰,它也崩潰,但在第二和第三切換之間從不崩潰。我不知道爲什麼會發生這種情況。Android應用程序崩潰Tabs和谷歌地圖

代碼的MainActivity

package com.example.prototype; 


import android.app.ActionBar; 
import android.app.ActionBar.Tab; 
import android.app.ActionBar.TabListener; 
import android.app.Activity; 
import android.support.v4.app.FragmentManager; 
import android.app.FragmentTransaction; 
import android.os.Bundle; 
import android.support.v4.app.ActionBarDrawerToggle; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.view.ViewPager; 
import android.support.v4.view.ViewPager.OnPageChangeListener; 
import android.support.v4.widget.DrawerLayout; 
import android.support.v4.widget.DrawerLayout.DrawerListener; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.widget.Toast; 

public class MainActivity extends FragmentActivity implements ActionBar.TabListener { 
    TabsPagerAdapter tabpager; 
    ViewPager pager; 
    DrawerLayout drawerLayout;  
    ActionBar action_bar; 
    ListView navigation_list; 
    @SuppressWarnings("deprecation") 
    ActionBarDrawerToggle drawerToggle; 
    String items[]; 
    String tabs_list[]={"Best Offers","Categories","Near By Places"}; 

    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.drawer_layout); 
     initComponents(); 
     action_bar=getActionBar(); 
     setNavigationList(); 
     setTabs(); 
    } 

    @SuppressWarnings("deprecation") 
    private void setTabs() { 

     action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
     for (String tab_name : tabs_list) { 
      action_bar.addTab(action_bar.newTab().setText(tab_name) 
        .setTabListener(this)); 
     } 
     pager.setAdapter(tabpager); 
     pager.setOnPageChangeListener(new OnPageChangeListener() { 

      @Override 
      public void onPageSelected(int arg0) { 
       // TODO Auto-generated method stub 
       action_bar.setSelectedNavigationItem(arg0);; 
      } 

      @Override 
      public void onPageScrolled(int arg0, float arg1, int arg2) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void onPageScrollStateChanged(int arg0) { 
       // TODO Auto-generated method stub 

      } 
     }); 
    } 

    @SuppressWarnings("deprecation") 
    private void setNavigationList() { 

     int open=R.string.navigation_open; 
     int close=R.string.navigation_close; 
     navigation_list.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items)); 

     drawerToggle=new ActionBarDrawerToggle(this,drawerLayout, R.drawable.ic_menu_white_18dp,open,close){ 


      public void onDrawerClosed(View view) { 
       super.onDrawerClosed(view); 
       action_bar.show(); 
      } 

      public void onDrawerOpened(View drawerView) { 
       super.onDrawerOpened(drawerView); 
       action_bar.hide(); 

      } 
     }; 

     drawerLayout.setDrawerListener(drawerToggle); 

     action_bar.setDisplayHomeAsUpEnabled(true); 
     action_bar.setHomeButtonEnabled(true); 

    } 

    @Override 
    protected void onPostCreate(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onPostCreate(savedInstanceState); 
     drawerToggle.syncState(); 
    } 


    private void initComponents() { 
     // TODO Auto-generated method stub 

     drawerLayout=(DrawerLayout) findViewById(R.id.drawer_layout); 
     action_bar=getActionBar(); 
     navigation_list=(ListView) findViewById(R.id.left_drawer); 
     items=getResources().getStringArray(R.array.navigation_drawer); 
     pager=(ViewPager) findViewById(R.id.pager);  
     FragmentManager m=getSupportFragmentManager(); 
     tabpager=new TabsPagerAdapter(m); 

    } 

    @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 
    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) { 
      return true; 
     } 

     if (id == R.id.search_menu) { 
      Toast.makeText(getApplicationContext(), "Searched Clicked ", Toast.LENGTH_LONG).show(); 
      return true; 
     } 

     if (id == R.id.share_menu) { 
      Toast.makeText(getApplicationContext(), "Share Clicked ", Toast.LENGTH_LONG).show(); 
      return true; 
     } 

     if (id == R.id.navigation_menu) { 
      Toast.makeText(getApplicationContext(), "Navigation Clicked ", Toast.LENGTH_LONG).show(); 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onTabSelected(Tab tab, FragmentTransaction ft) { 
     // TODO Auto-generated method stub 
     pager.setCurrentItem(tab.getPosition()); 
    } 

    @Override 
    public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onTabReselected(Tab tab, FragmentTransaction ft) { 
     // TODO Auto-generated method stub 

    } 

} 

標籤1個Java代碼:

public class BestOfferFragment extends Fragment{ 

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

     rootView = inflater.inflate(R.layout.bestoffer, container, false); 

    } 
} 

標籤2 Java代碼:

public class CategoriesrFragment extends Fragment{ 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 

     View rootView = inflater.inflate(R.layout.categories, container, false); 

     return rootView; 
    } 
} 

標籤3 Java代碼:

package com.example.prototype.tabs; 

import java.util.Timer; 

import com.example.prototype.MainActivity; 
import com.example.prototype.R; 
import com.google.android.gms.maps.CameraUpdate; 
import com.google.android.gms.maps.CameraUpdateFactory; 
import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.GoogleMapOptions; 
import com.google.android.gms.maps.MapFragment; 
import com.google.android.gms.maps.OnMapReadyCallback; 
import com.google.android.gms.maps.SupportMapFragment; 
import com.google.android.gms.maps.model.Circle; 
import com.google.android.gms.maps.model.CircleOptions; 
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 android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentManager; 
import android.app.Activity; 
import android.content.Context; 
import android.graphics.Color; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Toast; 

public class NearByPlacesFragment extends Fragment implements OnMapReadyCallback, LocationListener { 
    static int i=0; 
    GoogleMap gmap; 
    Marker mp; 
    LatLng ll; 
    Location l; 
    Context ctx; 
    double lat,lon; 
    boolean isGpsEnabled,isNetworkAvailable,isLocationSet; 
    LocationManager lmgr; 
    long minTime = 1000; 
    long minDistance = 1; 
    Location loc; 
    SupportMapFragment mapFragment; 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     ctx=getActivity(); 
     super.onCreateView(inflater, container, savedInstanceState); 
     if(mapFragment!=null){ Toast.makeText(getActivity(), "fragment exist`", 1000).show();} 
     View rootView = inflater.inflate(R.layout.nearbyplaces, container, false); 
     loc=getLocation(); 
     if(gmap==null) 
      setMap(); 
     Toast.makeText(getActivity(), "created`", 1000).show(); 
     return rootView; 

    } 


    private void setMap() { 
     // TODO Auto-generated method stub 
    mapFragment = (SupportMapFragment) getChildFragmentManager() 
       .findFragmentById(R.id.map); 
     mapFragment.getMapAsync(this); 

    } 


    private void setMarker() { 
     // TODO Auto-generated method stub 
     if(gmap!=null){ 
     lat=loc.getLatitude(); 
     lon=loc.getLongitude(); 
     ll=new LatLng(lat, lon); 
     Toast.makeText(getActivity(), "lat"+lat, Toast.LENGTH_LONG).show(); 
     mp=gmap.addMarker(new MarkerOptions().position(ll).title("Your Location")); 
     CameraUpdate center=CameraUpdateFactory.newLatLng(new LatLng(lat,lon)); 
     CameraUpdate zoom=CameraUpdateFactory.zoomTo(15); 
     gmap.moveCamera(center); 
     gmap.animateCamera(zoom); 
     } 
    } 




    @Override 
    public void onMapReady(GoogleMap map) { 
     // TODO Auto-generated method stub 

      map.getUiSettings().setAllGesturesEnabled(true); 
      map.setMapType(GoogleMap.MAP_TYPE_HYBRID); 
      map.setMyLocationEnabled(true); 
      gmap=map; 
     setMarker(); 
    } 



    public Location getLocation(){ 

     lmgr=(LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE); 

     isGpsEnabled=lmgr.isProviderEnabled(LocationManager.GPS_PROVIDER); 
     isNetworkAvailable=lmgr.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
     if(isGpsEnabled==true){ 
      setLocationManager("gps"); 
     } 
     else if(isNetworkAvailable==true){ 
      setLocationManager("network"); 
     } 

     return loc; 

    } 


    private boolean setLocationManager(String s){ 

     if(s.equals("gps")){ 
      Toast.makeText(getActivity(), "gps", Toast.LENGTH_LONG).show(); 
      lmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTime, minDistance, this); 
      loc=lmgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);   
     } 

     else{ 
      lmgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, minTime, minDistance, this); 
      loc=lmgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
     } 

     return isLocationSet; 
    } 



    @Override 
    public void onLocationChanged(Location location) { 

    } 



    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
     // TODO Auto-generated method stub 

    } 



    @Override 
    public void onProviderEnabled(String provider) { 
     // TODO Auto-generated method stub 

    } 



    @Override 
    public void onProviderDisabled(String provider) { 
     // TODO Auto-generated method stub 

    } 

} 

標籤3 XML:

<?xml version="1.0" encoding="utf-8"?> 

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

    <fragment android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/map" 

    android:name="com.google.android.gms.maps.SupportMapFragment" /> 

</RelativeLayout> 

選項卡適配器:

package com.example.prototype; 


import com.example.prototype.tabs.BestOfferFragment; 
import com.example.prototype.tabs.CategoriesrFragment; 
import com.example.prototype.tabs.NearByPlacesFragment; 

import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 

public class TabsPagerAdapter extends FragmentPagerAdapter { 
    BestOfferFragment frag1=new BestOfferFragment(); 
    CategoriesrFragment frag2=new CategoriesrFragment(); 
    NearByPlacesFragment frag3=new NearByPlacesFragment(); 

    public TabsPagerAdapter(FragmentManager fm) { 
     super(fm); 
     // TODO Auto-generated constructor stub 
    } 

    Fragment f = null; 
    @Override 
    public Fragment getItem(int index) { 

     switch (index) { 
     case 0: 

      f= frag1; break; 

     case 1: 
      f= frag2; break; 
     case 2: 
      // Movies fragment activity 
      f= frag3; break; 
     } 

     return f; 
    } 


    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     return 3; 
    } 

} 

下面是日誌:

07-11 01:49:28.877: E/NativeCrypto(7463): ssl=0x616b4438 cert_verify_callback x509_store_ctx=0x6210aab0 arg=0x0 
07-11 01:49:28.882: E/NativeCrypto(7463): ssl=0x616b4438 cert_verify_callback calling verifyCertificateChain authMethod=ECDHE_ECDSA 
07-11 01:49:35.046: E/AndroidRuntime(7463): FATAL EXCEPTION: main 
07-11 01:49:35.046: E/AndroidRuntime(7463): android.view.InflateException: Binary XML file line #8: Error inflating class fragment 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:746) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.view.LayoutInflater.inflate(LayoutInflater.java:489) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.view.LayoutInflater.inflate(LayoutInflater.java:396) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at com.example.prototype.tabs.NearByPlacesFragment.onCreateView(NearByPlacesFragment.java:58) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:955) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1314) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:730) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:490) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.support.v4.view.ViewPager.populate(ViewPager.java:1105) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.support.v4.view.ViewPager.populate(ViewPager.java:951) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.support.v4.view.ViewPager$3.run(ViewPager.java:250) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.view.Choreographer.doCallbacks(Choreographer.java:579) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.view.Choreographer.doFrame(Choreographer.java:547) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.os.Handler.handleCallback(Handler.java:725) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.os.Handler.dispatchMessage(Handler.java:92) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.os.Looper.loop(Looper.java:153) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.app.ActivityThread.main(ActivityThread.java:5297) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at java.lang.reflect.Method.invokeNative(Native Method) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at java.lang.reflect.Method.invoke(Method.java:511) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at dalvik.system.NativeStart.main(Native Method) 
07-11 01:49:35.046: E/AndroidRuntime(7463): Caused by: java.lang.IllegalArgumentException: Binary XML file line #8: Duplicate id 0x7f08006c, tag null, or parent id 0x7f08006b with another fragment for com.google.android.gms.maps.SupportMapFragment 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2175) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:168) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:675) 
07-11 01:49:35.046: E/AndroidRuntime(7463):  ... 27 more 
+0

我已添加日誌貓請參考它,並幫助我爲什麼是應用程序崩潰,同時切換標籤第二次 – AnonymousDev

+0

好吧,讓我試試.. – AnonymousDev

+0

感謝dainel它工作,但我不明白原因可以解釋我th原因? – AnonymousDev

回答

1

,以確保你不會遇到這個錯誤的最好辦法是使片段延長SupportMapFragment代替嵌套一個內次e片段。

我剛剛得到這個工作,使用ViewPagerFragmentPagerAdapter與地圖作爲其中一個選項卡。

這裏是一般結構,注意有沒有需要重寫onCreateView()方法,而且也沒有必要誇大任何佈局的xml:

public class MyMapFragment extends SupportMapFragment implements OnMapReadyCallback { 

    private GoogleMap mMap; 
    private Marker marker; 


    public MyMapFragment() { 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 

     Log.d("MyMap", "onResume"); 
     setUpMapIfNeeded(); 
    } 

    private void setUpMapIfNeeded() { 

     if (mMap == null) { 

      Log.d("MyMap", "setUpMapIfNeeded"); 

      getMapAsync(this); 
     } 
    } 

    @Override 
    public void onMapReady(GoogleMap googleMap) { 
     Log.d("MyMap", "onMapReady"); 
     mMap = googleMap; 
     setUpMap(); 
    } 

    private void setUpMap() { 

     mMap.setMyLocationEnabled(true); 
     mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); 
     mMap.getUiSettings().setMapToolbarEnabled(false); 


     mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() { 

      @Override 
      public void onMapClick(LatLng point) { 

       Log.d("MyMap", "MapClick"); 

       //remove previously placed Marker 
       if (marker != null) { 
        marker.remove(); 
       } 

       //place marker where user just clicked 
       marker = mMap.addMarker(new MarkerOptions().position(point).title("Marker") 
         .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA))); 

       Log.d("MyMap", "MapClick After Add Marker"); 

      } 
     }); 

    } 


} 

結果:

enter image description here

0

原因運行時異常:當應用程序是不是啓動它初始化所有並再次滑動到選項卡3即地圖選項卡,代碼正試圖創建另一個尚未銷燬的地圖片段,這導致了非法狀態異常,此兩種解決方案:

解決方案1:

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
       Bundle savedInstanceState) { 
       ctx=getActivity(); 

       if (view != null) { 
        ViewGroup parent = (ViewGroup) view.getParent(); 
        if (parent != null) 
         parent.removeView(view); 
       } 
       try { 
        view = inflater.inflate(R.layout.nearbyplaces, container, false); 
       } catch (InflateException e) { 

       } 

//rest of code is same  
} 

在此我們要更換由從父隨後再次加入移除第一現有片段..

解決方案2:這個人是最好的解決辦法:

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
      ctx=getActivity(); 

      if (view == null) { 
    view = inflater.inflate(R.layout.nearbyplaces, container, false); 
      } 
//rest of code is same 
      return view; 


    }