On Feb 22, 2012, at 10:50 AM, Chris Tacke wrote:
> Later on in my app, I'd like to get hold of this MapView so I can zoom in on 
> it, but I'm having difficulty.
> 
> My first attempt returned null:
> 
>            var m = m_layout.FindViewById<MapView>(Resource.Id.DriverMap);
...
> So I tried this:
> var m = m_layout.FindViewById(Resource.Id.DriverMap);

This doesn't make sense to me. :-/

View.FindViewById<T>(int) is (incorrectly!) this:

        public T FindViewById<T> (int id)
        {
                object view = this.FindViewById (id);

                return (T)view;
        }

I have no idea why View.FindViewById<T>(int) would return null while 
View.FindViewById(int) returns a non-null instance. I'd expect an 
InvalidCastException, since FindViewById<T>(int) is calling FindViewById(int)...

As I said, that implementation is incorrect. (Thanks for finding the bug! I 
fixed Activity but forgot about View...) It will be fixed in the 4.2 series so 
that FindViewById<MapView>() will work as expected. In the mean time...

> I run this:
> 
> var mt = m.GetType().Name;
> 
> And I get back "ViewGroupInvoker"

The problem here is a leaky abstraction: at present, our Java instance wrapper 
logic only knows about types from android.jar/Mono.Android.dll, and MapView 
isn't in android.jar, so it's not known. So we check the base type of MapView, 
find ViewGroup, which we _do_ know about, but it's abstract. "Fortunately" our 
plumbing generates "Invoker" types for abstract types and interfaces, so we 
construct a ViewGroupInvoker to hold thew MapView, as a MapView IS-A ViewGroup, 
and we return the invoker.

This still isn't entirely useful to you. The missing part you want/need is the 
Extensions.JavaCast<T>() extension method:

        
http://androidapi.xamarin.com/?link=M:Android.Runtime.Extensions.JavaCast{TResult}

Extensions.JavaCast<T>() is used to traverse (and type-check) the Java type 
system when the Mono for Android type system is dealing with incomplete 
information. You could thus do:

        MapView m = 
m_layout.FindViewById(Resource.Id.DriverMap).JavaCast<MapView>();

This would return a (far more useful) MapView instance instead of a 
ViewGroupInvoker instance.

Thanks,
 - Jon

_______________________________________________
Monodroid mailing list
Monodroid@lists.ximian.com

UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid

Reply via email to