谷歌地图片段内的片段可以操纵我的地图
Posted
技术标签:
【中文标题】谷歌地图片段内的片段可以操纵我的地图【英文标题】:google maps fragment inside a fragment cant maipulate my map 【发布时间】:2016-03-25 16:55:29 【问题描述】:我正在尝试在另一个片段中显示一个谷歌地图片段,但是我无法操纵地图,我已经把我看到的所有步骤都放在了上面 the documentation,但我无法操作我的地图。
XML 代码:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context=".FragmentoPrincipalUsuario">
<!-- TODO: Update blank fragment layout -->
<LinearLayout
android:orientation="horizontal"
android:layout_
android:layout_
android:layout_gravity="center_horizontal|top">
<fragment
android:id="@+id/map"
android:layout_
android:layout_
class="com.google.android.gms.maps.MapFragment"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_marginTop="60dp" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_
android:layout_
android:layout_gravity="center_horizontal|bottom">
<Button
android:layout_
android:layout_
android:text="pedir taxi"
android:id="@+id/pedirTaxi"
android:layout_gravity="center_horizontal" />
</LinearLayout>
类片段代码:
public class FragmentoPrincipalUsuario extends Fragment implements OnMapReadyCallback
private OnFragmentInteractionListener mListener;
private List<ParseUser> mChoferes;
private ParseUser mUsuarioActual;
private Button mPedido;
private GoogleMap map;
public FragmentoPrincipalUsuario()
// Required empty public constructor
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
//conseguir usuario actual
// mUsuarioActual = ParseUser.getCurrentUser();
View x = inflater.inflate(R.layout.fragmento_principal_usuario, container, false);
//evento boton pedir taxi
mPedido.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereEqualTo("tipoUsuario", "chofer");
query.findInBackground(new FindCallback<ParseUser>()
public void done(List<ParseUser> choferes, com.parse.ParseException e)
if (e == null)
mChoferes = choferes;
String nombreChofer;
for (ParseUser chofer : mChoferes)
nombreChofer = chofer.getUsername();
ParseObject gameScore = new ParseObject("Viaje");
gameScore.put("cliente", "hola");
gameScore.put("chofer", nombreChofer);
gameScore.put("tomado", false);
gameScore.saveInBackground();
else
// Something went wrong.
);
);
// Inflate the layout for this fragment
return x;
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri)
if (mListener != null)
mListener.onFragmentInteraction(uri);
@Override
public void onAttach(Context context)
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener)
mListener = (OnFragmentInteractionListener) context;
else
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
@Override
public void onDetach()
super.onDetach();
mListener = null;
@Override
public void onMapReady(GoogleMap map)
LatLng sydney = new LatLng(-27.7933121, -64.2574857);
map.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
map.moveCamera(CameraUpdateFactory.newLatLng(sydney));
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
主要活动类代码:
public class DrawerPrincipal extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener,FragmentoPrincipalUsuario.OnFragmentInteractionListener
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawer_principal);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//cargar fragment principal usuario
Fragment fragmento= null;
fragmento = new FragmentoPrincipalUsuario();
getSupportFragmentManager().beginTransaction()
.replace(R.id.content_main, fragmento)
.commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
@Override
public void onBackPressed()
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START))
drawer.closeDrawer(GravityCompat.START);
else
super.onBackPressed();
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.pantalla_principal_usuario, 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);
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item)
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.cuenta)
// Handle the camera action
else if (id == R.id.historial_viajes)
else if (id == R.id.contacto)
else if (id == R.id.compartir)
else if (id == R.id.version)
else if (id == R.id.salir)
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
@Override
public void onFragmentInteraction(Uri uri)
编辑,调用 getMapAsync() 后,这里是堆栈跟踪:
空指针错误:
12-18 19:51:50.056 11265-11265/ar.com.taxiexpress.taxiexpress E/AndroidRuntime: 致命异常: main java.lang.RuntimeException: 无法开始活动 组件信息ar.com.taxiexpress.taxiexpress/ar.com.taxiexpress.taxiexpress.DrawerPrincipal: java.lang.NullPointerException 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 在 android.app.ActivityThread.access$600(ActivityThread.java:141) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os.Looper.loop(Looper.java:137) 在 android.app.ActivityThread.main(ActivityThread.java:5041) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:511) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 在 dalvik.system.NativeStart.main(Native Method) 原因: java.lang.NullPointerException 在 ar.com.taxiexpress.taxiexpress.FragmentoPrincipalUsuario.onCreateView(FragmentoPrincipalUsuario.java:61) 在 android.support.v4.app.Fragment.performCreateView(Fragment.java:1962) 在 android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) 在 android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248) 在 android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738) 在 android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613) 在 android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:330) 在 android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547) 在 android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1164) 在 android.app.Activity.performStart(Activity.java:5114) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2153) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 在 android.app.ActivityThread.access$600(ActivityThread.java:141) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os.Looper.loop(Looper.java:137) 在 android.app.ActivityThread.main(ActivityThread.java:5041) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:511) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 在 dalvik.system.NativeStart.main(Native Method)
【问题讨论】:
【参考方案1】:看起来主要问题是您没有调用 getMapAsync()。
由于您在 Fragment 中使用嵌套的 SupportMapFragment,因此您需要使用 getChildFragmentManager()
来获取 Map Fragment,然后调用 getMapAsync()
。
SupportMapFragment mapFragment = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.map));
mapFragment.getMapAsync(this);
不过,虽然这样可行,但最好让 Fragment 扩展 SupportMapFragment,这样就不需要嵌套 Fragments:
public class MyMapFragment extends SupportMapFragment
implements OnMapReadyCallback
private GoogleMap mMap;
private Marker marker;
public MyMapFragment ()
@Override
public void onResume()
super.onResume();
setUpMapIfNeeded();
private void setUpMapIfNeeded()
if (mMap == null)
getMapAsync(this);
@Override
public void onMapReady(GoogleMap googleMap)
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)
//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)));
);
【讨论】:
嗨伙计,感谢您的回答,1 个问题我只是添加了调用 getChildFragmentManager() 和 getMapAsync() 的行,但我收到编译错误(NullPointerException)'你知道可能是什么问题吗? @GastonDelaCruzBayugar 将 NullPointerException 的堆栈跟踪添加到问题中,我来看看。 @GastonDelaCruzBayugar 你在扩展布局后调用 getMapAsync() 吗? 我把代码放在后面: View x = inflater.inflate(R.layout.fragmento_principal_usuario, container, false); @GastonDelaCruzBayugar 这很奇怪,它应该可以工作(前提是您在 Android 4.2 或更高版本上进行测试)。看看这个答案中完整的示例代码:***.com/a/31461334/4409409 请注意,那里的代码使用 getMap() 而不是 getMapAsync(),您应该使用 getMapAsync()。以上是关于谷歌地图片段内的片段可以操纵我的地图的主要内容,如果未能解决你的问题,请参考以下文章