我也跟着上如何有一個片段Link自定義佈局返回NULL
問題按鈕內本指南是,在final MapWrapperLayout mapWrapperLayout = (MapWrapperLayout) findViewById(R.id.map_relative_layout);
返回空值,並且在該行的代碼,一個空指針異常:
mapWrapperLayout.init(map, getPixelsFromDp(getApplicationContext(), 39 + 20));
這是我的我的主要活動的方法的OnCreate的代碼擴展的活動:
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 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>
的標籤,這我家活動佈局我的XML文件:
<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)
任何人都可以解釋爲什麼我有這個錯誤嗎?謝謝!
編輯後問題是一樣的:/ – Frank
@Frank有什麼問題?發佈活動代碼和堆棧跟蹤 – Raghunandan
空指針異常 – Frank