Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[regression/8.0.3] Disabling RefreshView disables the keyboard #19091

Open
kanadaj opened this issue Nov 28, 2023 · 13 comments
Open

[regression/8.0.3] Disabling RefreshView disables the keyboard #19091

kanadaj opened this issue Nov 28, 2023 · 13 comments
Labels
area-controls-refreshview RefreshView area-keyboard Keyboard, soft keyboard platform/android 🤖 potential-regression This issue described a possible regression on a currently supported version., verification pending t/bug Something isn't working
Milestone

Comments

@kanadaj
Copy link

kanadaj commented Nov 28, 2023

Description

This might be related to a change in the Android SDK or maybe in the MAUI keyboard/View implementation, but disabling a RefreshView with refreshView.IsEnabled = false disables keyboard entry into textareas (and probably inputs too) in MAUI Blazor. Haven't had the chance to try if native inputs were affected yet.

Steps to Reproduce

  1. Create a new MAUI Blazor Hybrid project
  2. Wrap the BlazorWebView in a RefreshView
  3. Set IsEnabled on the RefreshView to false
  4. Add a textarea to the Razor view
  5. Run the application, tap into the textarea and start typing
  6. Caret doesn't appear, input is ignored

Link to public reproduction project repository

No response

Version with bug

8.0.3

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

7.0.101

Affected platforms

Android

Affected platform versions

Android 11 and Android 14 confirmed

Did you find any workaround?

Yes, we're currently using the following workaround:

// Platforms/Android/CustomDisableSwipeRefreshLayout.cs
public class CustomDisableSwipeRefreshLayout : MauiSwipeRefreshLayout
{
    public bool DisableRefresh { get; set; }

    public CustomDisableSwipeRefreshLayout(Context context) : base(context)
    {
    }

    public override bool CanChildScrollUp()
    {
        if (DisableRefresh)
            return true;

        return base.CanChildScrollUp();
    }
}

with a custom ViewHandler, we are abusing CanChildScrollUp to disable refresh without disabling the Control itself, and then setting it directly:

// Platforms/Android/ViewHandlers/RefreshViewHandler.cs
public class RefreshViewHandler : Microsoft.Maui.Handlers.RefreshViewHandler
{
    protected override MauiSwipeRefreshLayout CreatePlatformView()
    {
        return new CustomDisableSwipeRefreshLayout(Context);
    }
}
// MauiProgram.cs
handlers.AddHandler<RefreshView, RefreshViewHandler>();
// Usage
#if ANDROID
    if (RefreshViewInstance.Handler?.PlatformView is CustomDisableSwipeRefreshLayout platformView)
    {
        platformView.DisableRefresh = !isReloadable;   
    }
    else
    {
        RefreshViewInstance.IsEnabled = isReloadable;
    }
#else
    RefreshViewInstance.IsEnabled = isReloadable;
#endif

Obviously, it would be nicer to inherit from RefreshView and fully implement this in the MAUI view itself, but this works as a quick and dirty patch.

Relevant log output

No response

@kanadaj kanadaj added the t/bug Something isn't working label Nov 28, 2023
@jsuarezruiz jsuarezruiz added area-controls-refreshview RefreshView area-keyboard Keyboard, soft keyboard labels Nov 29, 2023
@ghost ghost added the legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor label Nov 29, 2023
@mattleibow
Copy link
Member

I think disabling a control/layout also disables all the children. So this feels expected. If it worked in net7 that sounds like a bug. @PureWeen thoughts?

Also, pull to refresh a blazor webview will refresh and reload the whole app? @Eilon ?

Maybe you are needing a refresh view in the blazor view, not wrapping it.

@mattleibow mattleibow added area-blazor Blazor Hybrid / Desktop, BlazorWebView and removed legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor area-keyboard Keyboard, soft keyboard labels Nov 29, 2023
@mattleibow mattleibow added this to the Backlog milestone Nov 29, 2023
@ghost
Copy link

ghost commented Nov 29, 2023

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

@kanadaj
Copy link
Author

kanadaj commented Nov 29, 2023

@mattleibow pull to refresh doesn't really work properly inside the browser to be honest. JavaScript implementations are extremely buggy. Using the RefreshView as a wrapper works much better - it doesn't reload the browser, but we have tied our own logic inside the Blazor views to the event.

Disabling the RefreshView doesn't actually disable the browser either, just text input inside it. This wasn't the case previously either, so I'm not sure what changed to cause this. Couldn't find any relevant code changes.

@Eilon
Copy link
Member

Eilon commented Nov 29, 2023

@mattleibow indeed, I'm also surprised this ever worked. But probably not many people tried. I would normally expect that if a container is disabled, then everything inside it should all be disabled unconditionally. And if it isn't, that would be a bug.

@kanadaj indeed, I think pull-to-refresh is more of a 'web browser' thing and not a 'webview' thing, so it wouldn't work in a BlazorWebView by default (please correct me if I am wrong).

@kanadaj
Copy link
Author

kanadaj commented Nov 29, 2023

@kanadaj indeed, I think pull-to-refresh is more of a 'web browser' thing and not a 'webview' thing, so it wouldn't work in a BlazorWebView by default (please correct me if I am wrong).

Browsers typically implement it just like we did - by wrapping a native RefreshView around the WebView. The issue is that we only need the mechanism selectively. Until now, IsEnabled has actually worked for this and there are actually a number of posts and articles online suggesting to do this to disable refresh.

See:
https://stackoverflow.com/a/30328196
https://stackoverflow.com/a/34092085

And from the Android docs:
https://developer.android.com/reference/androidx/swiperefreshlayout/widget/SwipeRefreshLayout

To disable the gesture and progress animation, call setEnabled(false) on the view.

So I'm reasonably sure that disabling the RefreshView isn't meant to disable its children. Which would mean that the IsEnabled flag being propagated to its children is the bug here.

@Eilon Eilon added legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor and removed area-blazor Blazor Hybrid / Desktop, BlazorWebView labels Dec 1, 2023
@Eilon
Copy link
Member

Eilon commented Dec 1, 2023

Hmm interesting. I'm not sure if I was trying the exact same thing with the WindowsAppSDK (WinUI3) RefreshContainer (which is what .NET MAUI uses on Windows), but setting RefreshContainer.IsEnabled = false seems to disable elements currently in the refresh container, but if more items are added to the container, they don't seem to inherit being disabled.

I'm not quite sure what to make of that, but it seems already inconsistent between platforms (at least Android and Windows).

I've updated the labels on this issue to indicate it's likely a problem with the .NET MAUI RefreshView and not with the BlazorWebView. The BlazorWebView doesn't enable/disable itself or even listen to such events - it's presumably up to either the developer to set such a thing, or that it 'inherits' it from a parent container, such as a RefreshView.

@samhouts samhouts added the potential-regression This issue described a possible regression on a currently supported version., verification pending label Dec 6, 2023
@samhouts samhouts changed the title Disabling RefreshView disables the keyboard [regression/8.0.3] Disabling RefreshView disables the keyboard Dec 7, 2023
@BPriceKB
Copy link

This is causing major issues for our app at the moment, it's also worth noting that it prevents SwipeViews from functioning as well as the Entries. The CollectionView functionality bugs really could do with some attention.

We're in the process of figuring out whether it's worth writing a workaround that just picks up and hides the refresh functionality, but I also feel as though this shouldn't be an issue that we have to bodge to fix.

@samhouts samhouts added area-keyboard Keyboard, soft keyboard platform/android 🤖 and removed legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor labels Jan 31, 2024
@noahgabel
Copy link

noahgabel commented Feb 11, 2024

It also seems to have an effect on the system back button on android. We have both the problems. The one with the keyboard not working and navigationlock which no longer work on .net 8, and just closes the app.
image

It does no longer react when disabling refreshview.

@Rebrandsoft
Copy link

Hello @kanadaj ,

I hope this message finds you well. I recently came across the issue you reported.

Could you possibly share more details on how you implemented this workaround? I'm particularly interested in your "Usage" example.

To manage which pages utilize the RefreshView in my application, I control it through a bound boolean, managed by the following code snippet:

public class RefreshViewState : INotifyPropertyChanged
{
    public bool IsRefreshing { get; private set; }
    public bool IsEnabled { get; private set; }

    public event PropertyChangedEventHandler PropertyChanged;

    public void SetIsRefreshing(bool isRefreshing)
    {
        IsRefreshing = isRefreshing;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsRefreshing)));
    }

    public void SetIsEnabled(bool isEnabled)
    {
        IsEnabled = isEnabled;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsEnabled)));
    }
}

This RefreshViewState class is injected as a service into my pages to dynamically control the RefreshView's state.
Could you elaborate on how I might integrate your "Usage" example in your workaround please ?

@kanadaj
Copy link
Author

kanadaj commented Feb 23, 2024

@Rebrandsoft To be honest your usage is likely better. We reference the RefreshView directly in a singleton service and set the property on it. But your method should also work and it's honestly a bit better if we're being honest. The goal is to get the variable to a custom implementation which overrides CanChildScrollUp either way.

@RickFrankel
Copy link

Has there been any progress on resolving this issue with the actual component. It does seem to be fundamentally broken that when you set is IsEnabled to false it disables all child components.

@abivelj
Copy link

abivelj commented May 16, 2024

I am working on a mobile app using Blazor Hybrid and have implemented the pull to refresh.
In Android it works without any issues when I set it to "IsEnabled = false", but running as a desktop application it does not.
My workaround is to set a "IsWindows" field and if it's windows don't do anything with the refresh and keep it enabled.

@samanson123
Copy link

It also seems to have an effect on the system back button on android. We have both the problems. The one with the keyboard not working and navigationlock which no longer work on .net 8, and just closes the app. image

It does no longer react when disabling refreshview.

Just noticed this as part of an issue in my application when trying to implement the RefreshView it stopped my NavigationLock from working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-controls-refreshview RefreshView area-keyboard Keyboard, soft keyboard platform/android 🤖 potential-regression This issue described a possible regression on a currently supported version., verification pending t/bug Something isn't working
Projects
None yet
Development

No branches or pull requests