maui icon indicating copy to clipboard operation
maui copied to clipboard

TableView with Picker

Open sretz opened this issue 3 years ago • 3 comments
trafficstars

Description

After section an option in the Picker, instead of showing the selection the Label and the Picker disappear from the screen. image image

Steps to Reproduce

Reproduce Project: https://github.com/sretz/Reproduce.TableViewPicker

Code:

    <TableView Intent="Settings">
        <TableRoot>
            <TableSection Title="Locations">
                <ViewCell>
                    <AbsoluteLayout>
                        <Label Text="Canon: " HorizontalOptions="Start" VerticalOptions="Center" AbsoluteLayout.LayoutBounds="0,0.5" AbsoluteLayout.LayoutFlags="PositionProportional"/>
                        <Picker x:Name="canon" HorizontalOptions="End" VerticalOptions="Center" AbsoluteLayout.LayoutBounds="1,0.5" AbsoluteLayout.LayoutFlags="PositionProportional"/>
                    </AbsoluteLayout>
                </ViewCell>
            </TableSection>
        </TableRoot>
    </TableView>

Version with bug

Preview 14 (current)

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Andriod Pixel 5 - API 30 (Andriod 11)

Did you find any workaround?

No

Relevant log output

No response

sretz avatar Apr 08 '22 20:04 sretz

verified the issue on 17.2.0 Preview 2.1 [32317.152.main], it's repro. Repro project: Reproduce.TableViewPicker-master.zip

v-longmin avatar Apr 11 '22 02:04 v-longmin

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

ghost avatar Aug 30 '22 15:08 ghost

This issue is affecting my app. I have multiple pickers on multiple pages in my app. When is this issue going to be fixed?

druchti1 avatar Oct 28 '22 16:10 druchti1

Looking forward for a solution to it.

moraismateus avatar Dec 27 '22 21:12 moraismateus

This affects DatePicker as well.

brian-smith723 avatar Mar 18 '23 11:03 brian-smith723

Verified this on Visual Studio Enterprise 17.6.0 Preview 4.0. Repro on Android emulator (13.0-API 33) with below Project: 5924.zip Picker

XamlTest avatar Apr 19 '23 06:04 XamlTest

@PureWeen @jfversluis @davidortinau Ok, so this very basic issue has been reported more than 1.5 years ago (with zero progress so far), it affects .NET versions 6, 7 and 8, it's a severe regression wrt to Xamarin, has been reported more than 5 times by different people in various variations and certainly blocks many users from migrating to MAUI.

IMHO this shouldn't be tagged as delighter (it's certainly not very delighting to see this kind of problem in a supposedly stable product), but rather as regression. It seems the regression status is only used for issues that are regressions wrt earlier Maui versions, but leaves out all those things that were working perfectly in Xamarin, but broke with Maui.

Since Xamarin support expires in May 2024, and MS seems to expect everybody to migrate to Maui 8 by then, this sort of regression should clearly be a priority at this stage and should better be fixed by the end-of-support date of Xamarin, otherwise people will most likely migrate to other places than Maui (for me, primarily Flutter and React Native come to mind).

Just my 2¢ ...

janusw avatar Dec 13 '23 11:12 janusw

I agree that it's frustrating that the problem isn't patched, especially when you're doing a migration and you have to try to keep the same things in your code. However, I may have found a workaround that could help out for the moment. I tested it on @XamlTest project and it seems to work. Here is the workaround :

I took the OnMeasure from the PlatformRenderer : https://github.com/dotnet/maui/blob/8e933a7a7a46fdb586918e7414345d978cb0878d/src/Compatibility/Core/src/Android/PlatformRenderer.cs#L79

This is the workaround i found :

public class MyTableViewHandler : TableViewRenderer
    {
        public MyTableViewHandler(Context context) : base(context)
        {
        }

        //Do not call base.OnMeasure(widthMeasureSpec, heightMeasureSpec); !!!
        protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            int width = MeasureSpec.GetSize(widthMeasureSpec);
            int height = MeasureSpec.GetSize(heightMeasureSpec);

            SetMeasuredDimension(width, height);

            for (int i = 0; i < ChildCount; i++)
            {
                Android.Views.View child = GetChildAt(i);
                child.Measure(MeasureSpec.MakeMeasureSpec(width, MeasureSpecMode.Exactly),
                    MeasureSpec.MakeMeasureSpec(height, MeasureSpecMode.Exactly));
            }
        }
    }
public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            //...
            .ConfigureMauiHandlers((handlers) =>
            {
#if ANDROID
                handlers.AddHandler(typeof(TableView), typeof(MyTableViewHandler));
#endif
            });

        //...

        return builder.Build();
    }
}

Bennynation avatar Dec 13 '23 14:12 Bennynation

However, I may have found a workaround that could help out for the moment. I tested it on @XamlTest project and it seems to work. Here is the workaround :

Awesome, this might well be a good starting point for a proper fix!?! Couldn't one just add this OnMeasure method to the TableViewRenderer here?

https://github.com/dotnet/maui/blob/main/src/Controls/src/Core/Compatibility/Handlers/TableView/Android/TableViewRenderer.cs

Concerning workarounds: I've hit variations of this TableView bug in several contexts, and for some of them it was sufficient to simply set an explicit HeightRequest on the TableView, but unfortunately this did not work everywhere.

janusw avatar Dec 13 '23 14:12 janusw

However, I may have found a workaround that could help out for the moment. I tested it on @XamlTest project and it seems to work. Here is the workaround :

Awesome, this might well be a good starting point for a proper fix!?! Couldn't one just add this OnMeasure method to the TableViewRenderer here?

https://github.com/dotnet/maui/blob/main/src/Controls/src/Core/Compatibility/Handlers/TableView/Android/TableViewRenderer.cs

I have now pushed this to a branch on my fork:

https://github.com/janusw/maui/commits/TableView_fix/

And I have verified that it indeed fixes my reproducer from https://github.com/dotnet/maui/issues/19321#issuecomment-1849070994 🥳 (unless the TableView is inside a VerticalStackLayout 🤦). So this is probably not going to fix all issues with the TableView, but it's certainly a great step forward with this wretched problem.

I'd go ahead and create a PR from this now, in order to see if there'd be any review comments. Or do you prefer to do this yourself, @Bennynation (to get the credit for the commit and PR)?

janusw avatar Dec 17 '23 12:12 janusw

I have now pushed this to a branch on my fork:

https://github.com/janusw/maui/commits/TableView_fix/

And I have verified that it indeed fixes my reproducer from #19321 (comment) 🥳 (unless the TableView is inside a VerticalStackLayout 🤦).

This is PR #19473 now. Testing and feedback very welcome!

janusw avatar Dec 18 '23 12:12 janusw

Apparently a release 8.0.6 was just published. Can someone enlighten me my the fix for this issue (i.e. PR #19723) has not been included? When can we expect this fix to be available in a release? (It's a real blocker for me!) @samhouts @hartez @PureWeen @rmarinho

janusw avatar Jan 18 '24 08:01 janusw

Any progress / updates here? Why it was not released with 8.0.6? Do we need to wait another 3 months for the next maui update? This is also for me a real blocker and I can't fail to mention that this "basic" issue is almost 2 years old.

tibuprophen avatar Feb 01 '24 14:02 tibuprophen

This is also for me a real blocker

Not only for you and me, but also the other five reporters of this issue's duplicates, the ten "me-too" commenters, the twenty guys who didn't even care to comment, plus of course all the users of the apps they are building or want to build (certainly hundreds of thousands, probably millions).

So many people here spending so much time to investigate and report issues, and even trying to contribute fixes.

All I can do at this point is shake my head to all the ignorance and bad communication from the other side ... :unamused:

and I can't fail to mention that this "basic"

!!!

issue is almost 2 years old.

!!!

Wow :exploding_head:

janusw avatar Feb 02 '24 08:02 janusw

I agree that it's frustrating that the problem isn't patched, especially when you're doing a migration and you have to try to keep the same things in your code. However, I may have found a workaround that could help out for the moment. I tested it on @XamlTest project and it seems to work. Here is the workaround :

I took the OnMeasure from the PlatformRenderer :

https://github.com/dotnet/maui/blob/8e933a7a7a46fdb586918e7414345d978cb0878d/src/Compatibility/Core/src/Android/PlatformRenderer.cs#L79

This is the workaround i found :

public class MyTableViewHandler : TableViewRenderer
    {
        public MyTableViewHandler(Context context) : base(context)
        {
        }

        //Do not call base.OnMeasure(widthMeasureSpec, heightMeasureSpec); !!!
        protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            int width = MeasureSpec.GetSize(widthMeasureSpec);
            int height = MeasureSpec.GetSize(heightMeasureSpec);

            SetMeasuredDimension(width, height);

            for (int i = 0; i < ChildCount; i++)
            {
                Android.Views.View child = GetChildAt(i);
                child.Measure(MeasureSpec.MakeMeasureSpec(width, MeasureSpecMode.Exactly),
                    MeasureSpec.MakeMeasureSpec(height, MeasureSpecMode.Exactly));
            }
        }
    }
public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            //...
            .ConfigureMauiHandlers((handlers) =>
            {
#if ANDROID
                handlers.AddHandler(typeof(TableView), typeof(MyTableViewHandler));
#endif
            });

        //...

        return builder.Build();
    }
}

What motivated you to write your workaround like you did?

I tried with this and it seems to work about the same.

protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
	var spec = MeasureSpec.GetMode(heightMeasureSpec);
	if (spec == MeasureSpecMode.AtMost)
	{
		var size = MeasureSpec.GetSize(heightMeasureSpec);
		heightMeasureSpec = MeasureSpec.MakeMeasureSpec(size, MeasureSpecMode.Exactly);
	}

	base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
}

The problem seems to stem from this line here in ListView https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/widget/ListView.java;l=1321

When you have an AT_MOST (or UNSPECIFIED) measure, the listview will basically create a scrap copy of itself to measure which confuses the whole xplat system. Each call to GetView thinks that view is going to be used inside the ListView, it doesn't know that the platform is just creating an in-memory set of cells to get height measurements.

This worked "fine" in XF because in XF we didn't really restrict how many renderers you could have per xplat view. This often led to a lot of really random behavior because you'd end up with 1+ renderers for 1 cross platform view.

UNSPECIFIED is actually fixed by this code https://github.com/dotnet/maui/blob/a6c99972618fe6d042e8f066ec479cd1b41b2a67/src/Controls/src/Core/Compatibility/Handlers/TableView/Android/TableViewRenderer.cs#L91

In theory if we can get it working with the whole scrap view system, we could delete all that code.

PureWeen avatar Feb 04 '24 00:02 PureWeen

I have done several tests on the main branch, where the issue is fixed. fix-tv-picker Reviewing changes, the fix is included in this PR https://github.com/dotnet/maui/pull/20130, here https://github.com/dotnet/maui/blob/06797d6b7f1e46999257416fa612f79c6bc1eca8/src/Controls/src/Core/Compatibility/Handlers/TableView/Android/TableViewRenderer.cs#L92

jsuarezruiz avatar Feb 14 '24 07:02 jsuarezruiz

I have done several tests on the main branch, where the issue is fixed.

Awesome, thanks for testing. I hope it will also work for the other cases that have been reported, e.g. SwitchCell or a custom ViewCell (see the duplicate issues linked above).

Reviewing changes, the fix is included in this PR #20130, here

Yes, many thanks to @PureWeen for tackling this!

I guess the issue being fixed on main does not say much more than: A stable version with the fix will be available some time in the next year. Right?

But I saw that it's also included in the branch release/8.0.1xx-sr2, which gives me a bit more hope that the fix will be available timely. Will there be an 8.0.7 anytime soon?

Sorry for being so pushy, but this is really pretty urgent for me by now. It's a real blocker in the worst sense :/

janusw avatar Feb 14 '24 10:02 janusw

But I saw that it's also included in the branch release/8.0.1xx-sr2, which gives me a bit more hope that the fix will be available timely. Will there be an 8.0.7 anytime soon?

Actually I see an 8.0.7 on nuget.org already (but no tag or release notes in this repo yet).

Just tried the package, and in fact it seems to fix all the variants of this bug that I encountered (which were quite a few actually). Yay! 🥳

(Big thanks to everybody involved in fixing this!)

janusw avatar Feb 14 '24 11:02 janusw

Awesome!

jsuarezruiz avatar Feb 14 '24 14:02 jsuarezruiz