2016-04-19 44 views
1

我有一個使用SectionsPageAdapter的選項卡活動。有兩個選項卡,每個使用不同的片段,其中一個是谷歌地圖。當我試圖從MapFragment獲取SupportMapFragment時,它返回null。如何將地圖添加到選項卡式活動(Android)

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

我也曾嘗試:

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

如果我創建一個新的GoogleMapsActivity它工作得很好,這證實它已經無關,與我的鑰匙。存在編號爲map的片段。

MainActivity.java

package com.example.frias19o.trackthem2; 

import android.support.design.widget.TabLayout; 
import android.support.design.widget.FloatingActionButton; 
import android.support.design.widget.Snackbar; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.Toolbar; 

import android.support.v4.view.ViewPager; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 

public class MainActivity extends AppCompatActivity { 

    private SectionsPagerAdapter mSectionsPagerAdapter; 

    private ViewPager mViewPager; 

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

     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     // Create the adapter that will return a fragment for each of the three 
     // primary sections of the activity. 
     mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); 

     // Set up the ViewPager with the sections adapter. 
     mViewPager = (ViewPager) findViewById(R.id.container); 
     mViewPager.setAdapter(mSectionsPagerAdapter); 

     TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); 
     tabLayout.setupWithViewPager(mViewPager); 

     FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) 
         .setAction("Action", null).show(); 
      } 
     }); 
    } 


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_map, 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(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

} 

MapFragment.java

package com.example.frias19o.trackthem2; 

import android.content.Intent; 
import android.os.Bundle; 
import android.provider.Settings; 
import android.support.annotation.NonNull; 
import android.support.annotation.Nullable; 
import android.support.v4.app.Fragment; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Toast; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.location.LocationServices; 
import com.google.android.gms.maps.CameraUpdateFactory; 
import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.OnMapReadyCallback; 
import com.google.android.gms.maps.SupportMapFragment; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.MarkerOptions; 

import org.json.JSONException; 
import org.json.JSONObject; 

/******************************************************************** 
* Fragment for Map 
*********************************************************************/ 
public class MapFragment extends Fragment implements OnMapReadyCallback { 
    private static final String LOGTAG = "MapFragment"; 
    private static final String ARG_SECTION_NUMBER = "section_number"; 
    public static GoogleApiClient mGoogleApiClient; 
    private GoogleMap mMap; 

    public MapFragment() { 
    } 

    public static MapFragment newInstance(int sectionNumber) { 
     MapFragment fragment = new MapFragment(); 
     Bundle args = new Bundle(); 
     args.putInt(ARG_SECTION_NUMBER, sectionNumber); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView; 
     Toast.makeText(getContext(), "fragment_map", Toast.LENGTH_SHORT).show(); 
     rootView = inflater.inflate(R.layout.activity_maps, container, false); 

     return rootView; 
    } 

    @Override 
    public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager() 
       .findFragmentById(R.id.map); 
     mapFragment.getMapAsync(this); // it brakes here because mapFragment is null 
    } 


    @Override 
    public void onMapReady(GoogleMap googleMap) { 
     mMap = googleMap; 
     Log.v(LOGTAG, "map is ready"); 

     LatLng sydney = new LatLng(-34, 151); 
     mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney")); 
     mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); 
     Log.v(LOGTAG, "Added Sydney"); 
    } 
} 

SectionsPagerAdapter.java

package com.example.frias19o.trackthem2; 

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

/*********************************************************************** 
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to 
* one of the sections/tabs/pages. 
**********************************************************************/ 
public class SectionsPagerAdapter extends FragmentPagerAdapter { 

    public SectionsPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     // getItem is called to instantiate the fragment for the given page. 
     // Return a ClusterFragment (defined as a static inner class below). 

     Fragment fragment = null; 

     switch (position) { 
      case 0: 
       fragment = MapFragment.newInstance(position + 1); 
       break; 
      case 1: 
       fragment = ClusterFragment.newInstance(position + 1); 
       break; 
      default: 
       break; 
     } 

     return fragment; 
    } 

    @Override 
    public int getCount() { 
     // Show 2 total pages. 
     return 2; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     switch (position) { 
      case 0: 
       return "SECTION 1"; 
      case 1: 
       return "SECTION 2"; 
     } 
     return null; 
    } 
} 
+2

爲什麼'MapFragment '包含'SupportMapFragment',而不是'SupportMapFragment'或者擴展'SupportMapFragment'?嵌套片段是麻煩的恕我直言。 FWIW,這裏是一個示例應用程序,演示了'ViewPager'中的10個地圖:https://github.com/commonsguy/cw-omnibus/tree/master/MapsV2/Pager – CommonsWare

+0

這是非常有用的迴應,它打開了我沒有經驗的眼睛,但是我有點困惑,因爲在java中術語'是SupportMapFragment'和'擴展SupportMapFragment'是一回事。 –

+1

「是一個'SupportMapFragment',我的意思是不需要繼承它。沒有要求擴展'MapFragment'或'SupportMapFragment'來使用它們。IIRC,我的任何MapsV2示例都不涉及擴展'MapFragment'。 – CommonsWare

回答

1

注:由CoomonsWare第一評論中提供的鏈接的代碼這個問題,導致我找到了解決辦法。

正如CommonsWare指出的,該溶液使MapFragment延伸SupportMapFragment,這樣getMapAsync(this);可以直接調用(而不必訪問FragmentManager)。然後在SectionsPagerAdapter的getItem()中返回此MapFragment的實例。請注意,不應該有一個呼叫/覆蓋爲onCreateView(),就引起java.lang.NullPointerException: Attempt to invoke interface method 'void maps.ei.bz.o()' on a null object reference

最終產品:

MapFragment.java

package com.example.frias19o.trackthem2; 

import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.util.Log; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.maps.CameraUpdateFactory; 
import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.OnMapReadyCallback; 
import com.google.android.gms.maps.SupportMapFragment; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.MarkerOptions; 

/******************************************************************** 
* Fragment for Map 
*********************************************************************/ 
public class MapFragment extends SupportMapFragment implements OnMapReadyCallback { 
    private static final String LOGTAG = "MapFragment"; 
    private GoogleMap mMap; 

    public MapFragment() { 
    } 

    @Override 
    public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     getMapAsync(this); 
    } 


    @Override 
    public void onMapReady(GoogleMap googleMap) { 
     mMap = googleMap; 
     Log.v(LOGTAG, "map is ready"); 

     LatLng sydney = new LatLng(-34, 151); 
     mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney")); 
     mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); 
     Log.v(LOGTAG, "Added Sydney"); 
    } 
} 

SectionsPagerAdapter.java

package com.example.frias19o.trackthem2; 

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

/*********************************************************************** 
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to 
* one of the sections/tabs/pages. 
**********************************************************************/ 
public class SectionsPagerAdapter extends FragmentPagerAdapter { 

    public SectionsPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     // getItem is called to instantiate the fragment for the given page. 
     // Return a ClusterFragment (defined as a static inner class below). 

     Fragment fragment = null; 

     switch (position) { 
      case 0: 
       fragment = new MapFragment(); 

       break; 
      case 1: 
       fragment = ClusterFragment.newInstance(position + 1); 
       break; 
      default: 
       break; 
     } 

     return fragment; 
    } 

    @Override 
    public int getCount() { 
     // Show 2 total pages. 
     return 2; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     switch (position) { 
      case 0: 
       return "SECTION 1"; 
      case 1: 
       return "SECTION 2"; 
     } 
     return null; 
    } 
} 
相關問題