Bug 28957 - Can't override GenerateLayoutParams
Summary: Can't override GenerateLayoutParams
Status: CONFIRMED
Alias: None
Product: Android
Classification: Xamarin
Component: BCL Class Libraries ()
Version: 4.20.0
Hardware: Macintosh Mac OS
: Normal normal
Target Milestone: ---
Assignee: dean.ellis
URL:
Depends on:
Blocks:
 
Reported: 2015-04-09 19:02 UTC by Frank A. Krueger
Modified: 2015-09-25 14:46 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Test Sample (35.55 KB, application/zip)
2015-06-30 11:35 UTC, Rajneesh Kumar
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 28957 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
CONFIRMED

Description Frank A. Krueger 2015-04-09 19:02:13 UTC
If I try to override GenerateLayoutParams then I get the error:

error: generateLayoutParams(AttributeSet) in InspectActivity_InfoView cannot override generateLayoutParams(AttributeSet) in LinearLayout
	public android.view.ViewGroup.LayoutParams generateLayoutParams (android.util.AttributeSet p0)
  return type android.view.ViewGroup.LayoutParams is not compatible with android.widget.LinearLayout.LayoutParams

If I change the return type, the compiler complains.

		class InfoView : LinearLayout
		{
			public InfoView (Context context)
				: base (context)
			{
			}

			public override ViewGroup.LayoutParams GenerateLayoutParams (IAttributeSet attrs)
			{
				var p = base.GenerateLayoutParams (attrs);
				return p;
			}
		}

=== Xamarin Studio ===

Version 5.8.3 (build 1)
Installation UUID: fce13fdd-e8e3-48ef-99f1-4acbb06f0240
Runtime:
	Mono 3.12.1 ((detached/0849ec7)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 312010003

=== Xamarin.Android ===

Version: 4.20.2.1 (Enterprise Edition)
Android SDK: /Users/fak/Library/Developer/Xamarin/android-sdk-mac_x86
	Supported Android versions:
		2.1   (API level 7)
		2.2   (API level 8)
		2.3   (API level 10)
		3.1   (API level 12)
		4.0   (API level 14)
		4.0.3 (API level 15)
		4.3   (API level 18)
		4.4   (API level 19)
		5.0   (API level 21)
Java SDK: /usr
java version "1.8.0_20-ea"
Java(TM) SE Runtime Environment (build 1.8.0_20-ea-b23)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b22, mixed mode)

=== Xamarin Android Player ===

Version: Unknown version
Location: /Applications/Xamarin Android Player.app

=== Apple Developer Tools ===

Xcode 6.2 (6776)
Build 6C131e

=== Xamarin.iOS ===

Version: 8.8.2.7 (Enterprise Edition)
Hash: 9795e22
Branch: 
Build date: 2015-04-06 17:34:16-0400

=== Xamarin.Mac ===

Version: 1.12.0.14 (Enterprise Edition)

=== Build Information ===

Release ID: 508030001
Git revision: 6e8e725e0d689351901c2c70453bfa4ea25e293b
Build date: 2015-04-06 20:31:47-04
Xamarin addins: 051cd5f8c1b5dbfc87eaef80a74aec03f34c60a8

=== Operating System ===

Mac OS X 10.10.2
Darwin muon.local 14.1.0 Darwin Kernel Version 14.1.0
    Thu Feb 26 19:26:47 PST 2015
    root:xnu-2782.10.73~1/RELEASE_X86_64 x86_64
Comment 1 Jonathan Pryor 2015-04-09 22:08:51 UTC
@fak: Thank you for the report.

This is a limitation in our support for covariant return types.

As a workaround, use Java.Interop.ExportAttribute and the Mono.Android.Export.dll assembly:

    partial class InfoView {
        [Export]
        public new LinearLayout.LayoutParams GenerateLayoutParams (IAttributeSet attrs)
        {
            var p = base.GenerateLayoutParams (attrs);
            return p;
        }
    }
Comment 2 Rajneesh Kumar 2015-06-30 11:35:56 UTC
Created attachment 11791 [details]
Test Sample

I have checked this issue and able to reproduce this issue. To reproduce this issue I have followed the instruction provided in bug description.

I have created the test sample and  attached here. 

Steps to reproduce:

1. Open attached test case sample in XS.
2. Try to build the sample.
3. Observed that you will get following build error:

Error Details: https://gist.github.com/Rajneesh360Logica/b90dd64310dc818a6833

Screencast: http://www.screencast.com/t/Jq9iHgj3RWk
Build Output: https://gist.github.com/Rajneesh360Logica/780c768646d8d802cd0b
Ide Logs: https://gist.github.com/Rajneesh360Logica/20acde468f24413f782f

Please let me know if I have't followed the correct way to reproduce this issue..?

Thanks..!

Environment Info:

=== Xamarin Studio ===

Version 5.9.4 (build 5)
Installation UUID: 011d70a5-dede-428b-ab04-ef451c2e539d
Runtime:
	Mono 4.0.2 ((detached/c99aa0c)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 400020005

=== Xamarin.Android ===

Version: 5.1.4.16 (Business Edition)
Android SDK: /Users/MM/Desktop/android-sdk-macosx
	Supported Android versions:
		2.3    (API level 10)
		4.0.3  (API level 15)
		4.1    (API level 16)
		4.2    (API level 17)
		4.3    (API level 18)
		4.4    (API level 19)
		4.4.87 (API level 20)
		5.0    (API level 21)
Java SDK: /usr
java version "1.7.0_65"
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

=== Xamarin Android Player ===

Version: Unknown version
Location: /Applications/Xamarin Android Player.app

=== Apple Developer Tools ===

Xcode 6.2 (6776)
Build 6C131e

=== Xamarin.iOS ===

Version: 8.10.2.39 (Business Edition)
Hash: 4e8928a
Branch: master
Build date: 2015-06-29 11:03:42-0400

=== Xamarin.Mac ===

Version: 2.0.2.39 (Business Edition)

=== Build Information ===

Release ID: 509040005
Git revision: 8010a90f6e246b32364e3fb46ef2c9d1be9c9a2b
Build date: 2015-06-08 16:52:06-04
Xamarin addins: 7e93e9c3503f28770f23ce1b7eafd829919f18e8

=== Operating System ===

Mac OS X 10.9.5
Darwin MacMini.local 13.4.0 Darwin Kernel Version 13.4.0
    Sun Aug 17 19:50:11 PDT 2014
    root:xnu-2422.115.4~1/RELEASE_X86_64 x86_64
Comment 3 Jamie Mutton 2015-09-16 12:59:26 UTC
Hi, we are experiencing the same issue. 

I've tried the suggested workaround from Jonathan Pryor and whilst it allows the app to compile, setting breakpoints on the 'overridden'/exported GenerateDefaultLayoutParams and GenerateLayoutParams are never reached implying the export hasn't caused these methods to be called. 

What am i missing or are there alternative suggestions? I've already had to construct one layout using ViewGroup as a base instead and duplicate a fair bit of the Java class and i don't particularly fancy doing this a few more times.

Thanks in advance.


Extract of implemented code:

        [Export()]
        protected new LinearLayout.LayoutParams GenerateDefaultLayoutParams()
        {
            throw new NotImplementedException();
        }


        [Export()]
        public new LinearLayout.LayoutParams GenerateLayoutParams(IAttributeSet attrs)
        {
            throw new NotImplementedException();
        }


        [Export()]
        protected new LinearLayout.LayoutParams GenerateLayoutParams(ViewGroup.LayoutParams p)
        {
            throw new NotImplementedException();
        }
Comment 4 Jamie Mutton 2015-09-17 06:12:32 UTC
The workaround i've taken is to write a smaller wrapper class in Java which calls new methods from the ones which it appears can be overridden in c# currently. Not ideal, but it does seem to work.
Comment 5 Jon Douglas [MSFT] 2015-09-25 14:46:10 UTC
It seems that your current code doesn't play nicely with Java's method naming convention:

Compose method names using mixed case letters, beginning with a lower case letter and starting each subsequent word with an upper case letter.

1) Current Code:

        [Export()]
        protected new LinearLayout.LayoutParams GenerateDefaultLayoutParams()
        {
            throw new NotImplementedException();
        }


        [Export()]
        public new LinearLayout.LayoutParams GenerateLayoutParams(IAttributeSet
attrs)
        {
            throw new NotImplementedException();
        }


        [Export()]
        protected new LinearLayout.LayoutParams
GenerateLayoutParams(ViewGroup.LayoutParams p)
        {
            throw new NotImplementedException();
        }

None of these methods are "Java" friendly when they are exported, they need to have a lowercase "g" instead of "G" as that's what Java wants.

i.e.

protected android.widget.LinearLayout.LayoutParams generateDefaultLayoutParams ()

public android.widget.LinearLayout.LayoutParams generateLayoutParams (android.util.AttributeSet p0)

You can fix this with one of two ways:

1) Give a name to the Export such as:

[Export("generateDefaultLayoutParams")]
       protected new LinearLayout.LayoutParams GenerateDefaultLayoutParams()
        {
            throw new NotImplementedException();
        }

[Export("generateLayoutParams")]
        public new LinearLayout.LayoutParams GenerateLayoutParams(IAttributeSet
attrs)
        {
            throw new NotImplementedException();
        }

2) Rename your methods to the lower case first letter and then call [Export()]

i.e.

[Export()]
       protected new LinearLayout.LayoutParams generateDefaultLayoutParams()
        {
            throw new NotImplementedException();
        }

[Export()]
        public new LinearLayout.LayoutParams generateLayoutParams(IAttributeSet
attrs)
        {
            throw new NotImplementedException();
        }

You can see what the current signature looks like via going to the

obj\Debug\android\src\ folder and finding your respective .java class.