我从最新的 Android 升级中实现了 NavigationDrawer。因此,我将整个应用程序从不同的活动移动到不同的片段。我的活动使用了地图,我使用 SupportMapFragment 实现了它们,但现在我已经更改了我的最低 SDK 版本,不再需要支持库。
所以目前我已经制作了两个扩展 MapFragment 的片段,我试图通过在布局中使用片段然后调用 FragmentManager 并将其转换为 MapFragment,然后是 getMap() 来向它们添加地图。
我陷入了空指针异常,并尝试了地图无法加载的情况。所以我还检查了地图是否为空。我现在很困惑,我的代码已经变成了多种解决方案的大杂烩。有人可以指导我正确和完整的方式吗?
MainActivity.java
public class MainActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mPlanetTitles;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_activity);
mTitle = mDrawerTitle = getTitle();
mPlanetTitles = getResources().getStringArray(R.array.items_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mPlanetTitles));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
selectItem(0);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
/* Called whenever we call invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content view
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action buttons
switch(item.getItemId()) {
case R.id.action_websearch:
// create intent to perform web search for this planet
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, getActionBar().getTitle());
// catch event that there's no activity to handle intent
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
} else {
Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/* The click listner for ListView in the navigation drawer */
private class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
if(position == 0){
Fragment pf = new PickupFragment();
fragmentManager.beginTransaction().replace(R.id.content_frame, pf).commit();
}
else if(position == 1){
Fragment df = new DropFragment();
fragmentManager.beginTransaction().replace(R.id.content_frame, df).commit();
}
mDrawerList.setItemChecked(position, true);
setTitle(mPlanetTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
@Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
}
MapFragments 之一:
public class PickupFragment extends MapFragment {
public PickupFragment() {
// Empty constructor required for fragment subclasses
}
private Fragment fragment;
static GoogleMap googleMap;
static LatLng old_target;
static Address pickup = new Address(new Locale("en","INDIA"));
static Marker pickup_fav;
static boolean infoWindowIsTouched;
static boolean geocoder_working = false;
LatLng center;
Context context;
View rootView;
MapFragment pickupMapFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.activity_pickup, container, false);
return rootView;
}
@Override
public void onResume(){
super.onResume();
setupMap();
}
private void setupMap() {
if (googleMap != null)
return;
googleMap = pickupMapFragment.getMap();
if (googleMap == null)
return;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getFragmentManager();
pickupMapFragment
= (MapFragment)fm.findFragmentById(R.id.map_pickup);
if (pickupMapFragment == null) {
pickupMapFragment = MapFragment.newInstance();
fm.beginTransaction().replace(R.id.map_pickup, pickupMapFragment).commit();
}
googleMap = pickupMapFragment.getMap();
context = getActivity();
Button button = (Button) rootView.findViewById(R.id.btn_next);
button.setBackgroundColor(Color.rgb(4,180,4));
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(pickup==null || pickup.getMaxAddressLineIndex() == -1){
Toast.makeText(context, "Please select a pickup location!", Toast.LENGTH_SHORT).show();
}
else{
String full_address = "";
for(int i = 0; i < pickup.getMaxAddressLineIndex()-1;i++){
full_address += pickup.getAddressLine(i);
}
// Toast.makeText(getBaseContext(),address_text , Toast.LENGTH_SHORT).show();
CustomAddress c = new CustomAddress(full_address, Double.toString(pickup.getLatitude()), Double.toString(pickup.getLongitude()) );
Intent openDrop = new Intent(context, Drop.class);
openDrop.putExtra("pickup_address", c);
context.startActivity(openDrop);
}
}
});
TextView pickup_address = (TextView) rootView.findViewById(R.id.tv_pickup);
pickup_address.setText("");
googleMap.setMyLocationEnabled(true);
googleMap.moveCamera( CameraUpdateFactory.newLatLngZoom(new LatLng(19.1167, 72.8333),14.0f) );
center = googleMap.getCameraPosition().target;
googleMap.setOnCameraChangeListener(mOnCameraChangeListener);
pickup_fav = googleMap.addMarker(new MarkerOptions().position(center).title("Melbourne").snippet("Test").
visible(true).icon(BitmapDescriptorFactory.fromResource(R.drawable.trans)));
googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
infoWindowIsTouched = true;
Toast.makeText(context,"info Window Clicked" + marker.getSnippet() , Toast.LENGTH_SHORT).show();
Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.addbookmark_layout);
dialog.setCanceledOnTouchOutside(true);
dialog.show();
//
}
});
}
// An AsyncTask class for accessing the GeoCoding Web Service
private class GeocoderTask extends AsyncTask<LatLng, Void, List<Address>>{
@Override
protected List<Address> doInBackground(LatLng... cur_center) {
Geocoder geocoder = new Geocoder(context);
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(cur_center[0].latitude,cur_center[0].longitude, 1);
} catch (IOException e) {
e.printStackTrace();
}
return addresses;
}
@Override
protected void onPreExecute(){
geocoder_working = true;
// if(mapIsTouched)
// pickup_fav.hideInfoWindow();
}
@Override
protected void onPostExecute(List<Address> addresses) {
if(addresses==null || addresses.size()==0){
Toast.makeText(context, "No Location found", Toast.LENGTH_SHORT).show();
}
else{
pickup = addresses.get(0);
String full_address = "";
for(int i = 0; i < pickup.getMaxAddressLineIndex()-1;i++){
full_address += pickup.getAddressLine(i);
}
TextView pickup_address = (TextView) rootView.findViewById(R.id.tv_pickup);
CharSequence c = full_address;
pickup_address.setText(c);
geocoder_working = false;
// if (mapIsTouched)
// pickup_fav.hideInfoWindow();
old_target = googleMap.getCameraPosition().target;
}
}
}
private final OnCameraChangeListener mOnCameraChangeListener =
new OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
LatLng x = googleMap.getCameraPosition().target;
new GeocoderTask().execute(x);
pickup_fav.setPosition(x);
pickup_fav.showInfoWindow();
}
};
}
上述 MapFragment 的布局文件
<LinearLayout 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"
android:gravity="bottom"
android:orientation="vertical"
tools:context=".Pickup" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</RelativeLayout>
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/img_pickup"
android:layout_width="30dp"
android:layout_height="48dp"
android:layout_gravity="center_vertical"
android:paddingLeft="4dp"
android:paddingRight="8dp"
android:src="@drawable/from" />
<TextView
android:id="@+id/tv_pickup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="16dp" />
<View
android:layout_height="fill_parent"
android:layout_width="2dp"
android:id="@+id/separator"
android:visibility="visible"
android:background="@android:color/darker_gray"/>
<ImageView
android:id="@+id/img_pickup_search"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="right"
android:src="@drawable/pickup_search" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="0.4dp"
android:id="@+id/separator2"
android:visibility="visible"
android:background="@android:color/darker_gray"/>
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
tools:context=".Pickup" >
<fragment
android:id="@+id/map_pickup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
class="com.google.android.gms.maps.MapFragment"
android:name="com.sharedcab.batchcar.Pickup"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/img_center"
android:layout_width="18dp"
android:layout_height="32dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/from" />
</RelativeLayout>
</FrameLayout>
<LinearLayout
android:layout_height="50dp"
android:layout_width="match_parent"
android:gravity="bottom">
<Button
android:id="@+id/btn_next"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_margin="0dp"
android:layout_weight="1"
android:padding="0dp"
android:text="Next" />
</LinearLayout>
</LinearLayout>