I'm building an application which relies on the Google Maps API, but running into some problems when I subclass MapView. The reason I'm trying to subclass MapView is that I want to detect and use double taps and long presses on the map to perform some functions. I've subclassed both MapActivity and MapView as I did in another application, where this seems to be working properly, but I can't seem to get it to work in this new application as I keep getting an exception when the application runs:
Exception data: android.view.InflateException: Binary XML file line #6: Error inflating class java.lang.reflect.Constructor
My MapView subclass is fairly simple:
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
import com.google.android.maps.MapView;
public class TSMapView extends MapView {
private Context TSctx;
private GestureDetector gDetector;
public TSMapView(Context context, AttributeSet attrs) {
super(context, attrs);
this.TSctx = context;
this.gDetector = new GestureDetector((OnGestureListener) TSctx);
this.gDetector.setOnD开发者_开发知识库oubleTapListener((OnDoubleTapListener)TSctx);
this.gDetector.setIsLongpressEnabled(false);
}
public boolean onTouchEvent(MotionEvent ev) {
if(this.gDetector.onTouchEvent(ev))
return true;
else
return super.onTouchEvent(ev);
}
}
As is the XML layout for my MapActivity which instantiates it:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.badlucksoft.thisspot.TSMapView android:id="@+id/tsmapview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:enabled="true" android:clickable="true" android:apiKey="<key>" />
</RelativeLayout>
The odd thing is that if I replace my application's package/view name in the XML with default/normal "com.google.android.maps.MapView" my code seems to work just fine, but I can't detect double clicks or long presses. Comparing the code over and over again to the working application has left me with nothing but a headache. I imagine I'm doing something simple really wrong, but I can't figure out what at the moment. Here's the exception's stack trace if it matters, the MapActivity subclass is TSMapAct, and the primary activity is a TabHost subclass called ThisSpot:
Exception data: android.view.InflateException: Binary XML file line #6: Error inflating class java.lang.reflect.Constructor
Stack Trace 0: android.view.LayoutInflater.createView(LayoutInflater.java:512)
Stack Trace 1: android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:564)
Stack Trace 2: android.view.LayoutInflater.rInflate(LayoutInflater.java:617)
Stack Trace 3: android.view.LayoutInflater.inflate(LayoutInflater.java:407)
Stack Trace 4: android.view.LayoutInflater.inflate(LayoutInflater.java:320)
Stack Trace 5: android.view.LayoutInflater.inflate(LayoutInflater.java:276)
Stack Trace 6: com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:313)
Stack Trace 7: android.app.Activity.setContentView(Activity.java:1620)
Stack Trace 8: com.badlucksoft.thisspot.TSMapAct.onCreate(TSMapAct.java:43)
Stack Trace 9: android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
Stack Trace 10: android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
Stack Trace 11: android.app.ActivityThread.startActivityNow(ActivityThread.java:2242)
Stack Trace 12: android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)
Stack Trace 13: android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339)
Stack Trace 14: android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:631)
Stack Trace 15: android.widget.TabHost.setCurrentTab(TabHost.java:317)
Stack Trace 16: android.widget.TabHost.addTab(TabHost.java:210)
Stack Trace 17: com.badlucksoft.thisspot.ThisSpot.onCreate(ThisSpot.java:35)
Stack Trace 18: android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
Stack Trace 19: android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
Stack Trace 20: android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
Stack Trace 21: android.app.ActivityThread.access$2100(ActivityThread.java:116)
Stack Trace 22: android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
Stack Trace 23: android.os.Handler.dispatchMessage(Handler.java:99)
Stack Trace 24: android.os.Looper.loop(Looper.java:123)
Stack Trace 25: android.app.ActivityThread.main(ActivityThread.java:4203)
Stack Trace 26: java.lang.reflect.Method.invokeNative(Native Method)
Stack Trace 27: java.lang.reflect.Method.invoke(Method.java:521)
Stack Trace 28: com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
Stack Trace 29: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
Stack Trace 30: dalvik.system.NativeStart.main(Native Method)
Thank you for your time, Raymond
You are not implementing the constructor that the inflation logic is expecting. I suggest that you implement all three constructors that you see on MapView
.
I just solved this little mystery. While I did need use a constructor that I didn't specifically implement, this doesn't appear to be the cause of the exception. The actual cause appears to be that two different OnGestureListeners were being utilized: TSMapView defaulted to using
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
While TSMapAct was using
import android.gesture.GestureOverlayView;
import android.gesture.GestureOverlayView.OnGestureListener;
The import statements in both cases were added automatically by Eclipse when I cut and pasted critical lines from the other project into this project. Needless to say, the OnGestureListener interfaces aren't compatible.
Thanks for your help!
精彩评论