dotnet / android

.NET for Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#
MIT License
1.93k stars 531 forks source link

LayoutCodeBehind Should Support Fragments #3616

Open adamhewitt627 opened 5 years ago

adamhewitt627 commented 5 years ago

Steps to Reproduce

  1. Enable layout bindings: <AndroidGenerateLayoutBindings>true</AndroidGenerateLayoutBindings>
  2. Add xamarin:classes to a layout used by a fragment, with the contents being the fragment's class.
  3. Rebuild, and see it fail.

Expected Behavior

It should compile and give the Fragment the layout binding partial code.

Actual Behavior

Because the generated partial assumes it's an Activity, It includes override void SetContentView which doesn't exist on fragments. I can see why it is built like this (so the layout binding is correctly initialized as the view changes) but It would still be nice to see support for fragments.

Version Information

Microsoft Visual Studio Enterprise 2019 Version 16.2.5 VisualStudio.16.Release/16.2.5+29306.81 Microsoft .NET Framework Version 4.8.03752

Installed Version: Enterprise

Mono Debugging for Visual Studio 16.2.6 (4cfc7c3) Support for debugging Mono processes with Visual Studio.

VisualStudio.Mac 1.0 Mac Extension for Visual Studio

Xamarin 16.2.0.95 (d16-2@37df81894) Xamarin Designer 16.2.0.375 (remotes/origin/d16-2@357d38ef4) Xamarin Templates 16.3.117 (59a59e8) Xamarin.Android SDK 9.4.1.1 (d16-2/cec9eb4) Xamarin.Android Reference Assemblies and MSBuild support. Mono: mono/mono/2019-02@e6f5369c2d2 Java.Interop: xamarin/java.interop/d16-2@d64ada5 LibZipSharp: grendello/LibZipSharp/d16-2@caa0c74 LibZip: nih-at/libzip/rel-1-5-1@b95cf3f ProGuard: xamarin/proguard/master@905836d SQLite: xamarin/sqlite/3.27.1@8212a2d Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-2@6f6c969

Xamarin.iOS and Xamarin.Mac SDK 12.14.0.114 (c669116) Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

gugavaro commented 5 years ago

@adamhewitt627 Can you take a look on this: https://github.com/xamarin/xamarin-android/blob/master/Documentation/guides/LayoutCodeBehind.md#code-behind

We believe it is missing xamarin:managedType

Could you please provide us a repro?

thanks, Gustavo.

adamhewitt627 commented 5 years ago

Reproduction project: LayoutCodeBehind.zip - the generated classes have been left in the zip, but the rest of the obj folder was removed.

You can see in fragment.xml that trying to generate a code-behind fails for the class that is a fragment. Compile errors in LayoutCodeBehind.ReproFragment.fragment.g.cs:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:xamarin="http://schemas.xamarin.com/android/xamarin/tools"
    xamarin:classes="LayoutCodeBehind.ReproFragment"

Adding managedType as you suggest produces crazier compile errors around resources, attributes, etc. Which makes sense, because LinearLayout != ReproFragment.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:xamarin="http://schemas.xamarin.com/android/xamarin/tools"
    xamarin:classes="LayoutCodeBehind.ReproFragment"
    xamarin:managedType="LayoutCodeBehind.ReproFragment"

Additionally

This project illustrates two other issues I have with the existing implementation. These likely deserve their own issues, but I will briefly describe them because of the reproduction project right here.

Fragment type

AndroidFragmentType appears to be ignored.

<!-- LayoutCodeBehind.csproj -->
<AndroidFragmentType>Android.Support.V4.App.Fragment</AndroidFragmentType>
<!-- content_main.xml -->
<fragment
    class="LayoutCodeBehind.ReproFragment"
    android:id="@+id/repro"
// Binding.content_main.g.cs
global::Android.App.Fragment __repro;

Also, decorating the <fragment /> with xamarin:managedType produces a compile error: 1>C:\Users\...\content_main.xml(13,108,13,115): error CS1503: Argument 2: cannot convert from 'LayoutCodeBehind.ReproFragment' to 'Android.App.Fragment'

Warnings

Out of the box, this produces compiler warnings, largely because of it trying to use the now-deprecated Android.App.Fragment. This causes trouble in projects with <TreatWarningsAsErrors>true</TreatWarningsAsErrors>.

1>------ Build started: Project: LayoutCodeBehind, Configuration: Debug Any CPU ------
1>C:\Users\...\content_main.xml(12,10,12,38): warning CS0618: 'Fragment' is obsolete: 'This class is obsoleted in this android platform'
1>C:\Users\...\content_main.xml(12,10,12,38): warning CS0618: 'Fragment' is obsolete: 'This class is obsoleted in this android platform'
1>C:\Users\...\content_main.xml(11,3,11,31): warning CS0618: 'Fragment' is obsolete: 'This class is obsoleted in this android platform'
1>C:\Users\...\content_main.xml(11,3,11,31): warning CS0618: 'Fragment' is obsolete: 'This class is obsoleted in this android platform'
1>C:\Program Files (x86)\...\LayoutBinding.cs(77,48,77,76): warning CS0618: 'Fragment' is obsolete: 'This class is obsoleted in this android platform'
1>C:\Program Files (x86)\...\LayoutBinding.cs(77,117,77,145): warning CS0618: 'Fragment' is obsolete: 'This class is obsoleted in this android platform'
1>C:\Users\...\LayoutCodeBehind.MainActivity.activity_main.g.cs(80,10,80,38): warning CS0618: 'Fragment' is obsolete: 'This class is obsoleted in this android platform'
1>C:\Program Files (x86)\...\LayoutBinding.cs(79,56,79,80): warning CS0618: 'Activity.FragmentManager' is obsolete: 'deprecated'
1>  LayoutCodeBehind -> C:\Users\...\LayoutCodeBehind.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========