我按照本指南了解如何在代码段Link
中设置按钮问题是final MapWrapperLayout mapWrapperLayout = (MapWrapperLayout) findViewById(R.id.map_relative_layout);
在此行代码处返回null值和空指针异常:
mapWrapperLayout.init(map, getPixelsFromDp(getApplicationContext(), 39 + 20));
这是我的主要活动的oncreate方法的代码,它扩展了Activity:
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MapFragment mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id.map);
final MapWrapperLayout mapWrapperLayout = (MapWrapperLayout) findViewById(R.id.map_relative_layout);
final GoogleMap map = mapFragment.getMap();
// MapWrapperLayout initialization
// 39 - default marker height
// 20 - offset between the default InfoWindow bottom edge and it's content bottom edge
mapWrapperLayout.init(map, getPixelsFromDp(getApplicationContext(), 39 + 20));
// We want to reuse the info window for all the markers,
// so let's create only one class member instance
this.infoWindow = (ViewGroup)getLayoutInflater().inflate(R.layout.infowindow, null);
this.infoTitle = (TextView)infoWindow.findViewById(R.id.title);
this.infoSnippet = (TextView)infoWindow.findViewById(R.id.snippet);
this.infoButton = (Button)infoWindow.findViewById(R.id.button);
// Setting custom OnTouchListener which deals with the pressed state
// so it shows up
this.infoButtonListener = new OnInfoWindowElemTouchListener(infoButton,
getResources().getDrawable(R.drawable.common_signin_btn_icon_dark),
getResources().getDrawable(R.drawable.common_signin_btn_icon_disabled_dark))
{
@Override
protected void onClickConfirmed(View v, Marker marker) {
// Here we can perform some action triggered after clicking the button
Toast.makeText(MainActivity.this, marker.getTitle() + "'s button clicked!", Toast.LENGTH_SHORT).show();
}
};
this.infoButton.setOnTouchListener(infoButtonListener);
map.setInfoWindowAdapter(new InfoWindowAdapter() {
@Override
public View getInfoWindow(Marker marker) {
return null;
}
@Override
public View getInfoContents(Marker marker) {
// Setting up the infoWindow with current's marker info
infoTitle.setText(marker.getTitle());
infoSnippet.setText(marker.getSnippet());
infoButtonListener.setMarker(marker);
// We must call this to set the current marker and infoWindow references
// to the MapWrapperLayout
mapWrapperLayout.setMarkerWithInfoWindow(marker, infoWindow);
return infoWindow;
}
});
// Let's add a couple of markers
map.addMarker(new MarkerOptions()
.title("Prague")
.snippet("Czech Republic")
.position(new LatLng(50.08, 14.43)));
map.addMarker(new MarkerOptions()
.title("Paris")
.snippet("France")
.position(new LatLng(48.86,2.33)));
map.addMarker(new MarkerOptions()
.title("London")
.snippet("United Kingdom")
.position(new LatLng(51.51,-0.1)));
}
MapWrapperLayout与指南相同:
public class MapWrapperLayout extends RelativeLayout {
/**
* Reference to a GoogleMap object
*/
private GoogleMap map;
/**
* Vertical offset in pixels between the bottom edge of our InfoWindow
* and the marker position (by default it's bottom edge too).
* It's a good idea to use custom markers and also the InfoWindow frame,
* because we probably can't rely on the sizes of the default marker and frame.
*/
private int bottomOffsetPixels;
/**
* A currently selected marker
*/
private Marker marker;
/**
* Our custom view which is returned from either the InfoWindowAdapter.getInfoContents
* or InfoWindowAdapter.getInfoWindow
*/
private View infoWindow;
public MapWrapperLayout(Context context) {
super(context);
}
public MapWrapperLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MapWrapperLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* Must be called before we can route the touch events
*/
public void init(GoogleMap map, int bottomOffsetPixels) {
this.map = map;
this.bottomOffsetPixels = bottomOffsetPixels;
}
/**
* Best to be called from either the InfoWindowAdapter.getInfoContents
* or InfoWindowAdapter.getInfoWindow.
*/
public void setMarkerWithInfoWindow(Marker marker, View infoWindow) {
this.marker = marker;
this.infoWindow = infoWindow;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean ret = false;
// Make sure that the infoWindow is shown and we have all the needed references
if (marker != null && marker.isInfoWindowShown() && map != null && infoWindow != null) {
// Get a marker position on the screen
Point point = map.getProjection().toScreenLocation(marker.getPosition());
// Make a copy of the MotionEvent and adjust it's location
// so it is relative to the infoWindow left top corner
MotionEvent copyEv = MotionEvent.obtain(ev);
copyEv.offsetLocation(
-point.x + (infoWindow.getWidth() / 2),
-point.y + infoWindow.getHeight() + bottomOffsetPixels);
// Dispatch the adjusted MotionEvent to the infoWindow
ret = infoWindow.dispatchTouchEvent(copyEv);
}
// If the infoWindow consumed the touch event, then just return true.
// Otherwise pass this event to the super class and return it's result
return ret || super.dispatchTouchEvent(ev);
}
}
这是我的带有项目标签的xml文件
<?xml version="1.0" encoding="utf-8"?>
<com.example.testmappa.MapWrapperLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map_relative_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
</com.example.testmappa.MapWrapperLayout>
这是我的家庭活动布局:
<RelativeLayout 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"
tools:context=".MainActivity" >
<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
最后我的logcat
03-13 17:50:56.386: E/AndroidRuntime(21055): FATAL EXCEPTION: main
03-13 17:50:56.386: E/AndroidRuntime(21055): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testmappa/com.example.testmappa.MainActivity}: java.lang.NullPointerException
03-13 17:50:56.386: E/AndroidRuntime(21055): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2249)
03-13 17:50:56.386: E/AndroidRuntime(21055): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2299)
03-13 17:50:56.386: E/AndroidRuntime(21055): at android.app.ActivityThread.access$700(ActivityThread.java:154)
03-13 17:50:56.386: E/AndroidRuntime(21055): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
03-13 17:50:56.386: E/AndroidRuntime(21055): at android.os.Handler.dispatchMessage(Handler.java:99)
03-13 17:50:56.386: E/AndroidRuntime(21055): at android.os.Looper.loop(Looper.java:137)
03-13 17:50:56.386: E/AndroidRuntime(21055): at android.app.ActivityThread.main(ActivityThread.java:5306)
03-13 17:50:56.386: E/AndroidRuntime(21055): at java.lang.reflect.Method.invokeNative(Native Method)
03-13 17:50:56.386: E/AndroidRuntime(21055): at java.lang.reflect.Method.invoke(Method.java:511)
03-13 17:50:56.386: E/AndroidRuntime(21055): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
03-13 17:50:56.386: E/AndroidRuntime(21055): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
03-13 17:50:56.386: E/AndroidRuntime(21055): at dalvik.system.NativeStart.main(Native Method)
03-13 17:50:56.386: E/AndroidRuntime(21055): Caused by: java.lang.NullPointerException
03-13 17:50:56.386: E/AndroidRuntime(21055): at com.example.testmappa.MainActivity.onCreate(MainActivity.java:44)
03-13 17:50:56.386: E/AndroidRuntime(21055): at android.app.Activity.performCreate(Activity.java:5255)
03-13 17:50:56.386: E/AndroidRuntime(21055): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
03-13 17:50:56.386: E/AndroidRuntime(21055): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2213)
任何人都可以解释我为什么会有这个错误?谢谢!
答案 0 :(得分:1)
更改此
final MapWrapperLayout mapWrapperLayout = (MapWrapperLayout) findViewById(R.layout.map_relative_layout);
到
final MapWrapperLayout mapWrapperLayout = (MapWrapperLayout) findViewById(R.id.map_relative_layout);
findViewById
查找当前虚增布局中包含id的视图。
编辑:
你有
setContentView(R.layout.activity_main);
final MapWrapperLayout mapWrapperLayout = (MapWrapperLayout) findViewById(R.id.map_relative_layout);
虽然activity_main.xml
没有自定义布局。
答案 1 :(得分:0)
检查它是否为&#39; null&#39;在你分配之后。如果是这种情况,那么您可能没有适当地设置当前内容视图。
setContentView(R.layout./*nameOfTheXmlFileContainingThisLayout.xml*/);
在致电
之前final MapWrapperLayout mapWrapperLayout = (MapWrapperLayout) findViewById(R.id.map_relative_layout);
当您尝试访问MapWrapperLayout时,如果没有加载当前的xml内容视图,它将始终返回null,因为它查找的位置错误。