androidblazormauihybridflyout

Why does my MAUI Blazor hybrid app put an input box over the flyout button?


I have a very basic MAUI Blazor hybrid app I've been building according to this video series. When debugged under "Windows Machine", it shows the left-side nav bar with 4 options. Until recently, running it under the Android emulator or my Android phone, the flyout ("hamburger") button would pop out this menu (then with 3 options) on top. I added the "To-Dos" option per part 4 of the video series, and the Windows version still looks right but now on Android emulator and phone, some kind of transparent input box with white text is sitting on top of the flyout button. If I try to click on the button, the keyboard pops up and I can enter text and can't make the options fly out.

enter image description here

My code is pretty basic, but here's the ToDo.razor I added just before this problem started appearing. I added the "Data" folder to the project root:

@page "/todo"
@using MyProjBlazorHybrid.Data
@inject ToDoService ToDoSvc

<h3>To-Do! (@toDos.Count(todo => !todo.IsDone))</h3>

<ul>
    @foreach(var todo in toDos) {
        <li>
            <input type="checkbox" @bind="todo.IsDone" />
            <input @bind="todo.Title" />
        </li>
    }
</ul>

<input placeholder="Sumthin' to do'" @bind="newToDo" />
<button @onclick="AddToDo">Add To-Do</button>
<button @onclick="Save">Save</button>

@code {
    List<ToDoItem> toDos = new List<ToDoItem>();
    string newToDo;

    protected override void OnInitialized() {
        base.OnInitialized();
        var items = ToDoSvc.LoadItems();
        toDos.AddRange(items);
    }

    void Save() {
        ToDoSvc.SaveItems(toDos);
    }

    void AddToDo() {
        if (string.IsNullOrWhiteSpace(newToDo)) {
            return;
        }

        toDos.Add(new ToDoItem {
                Title = newToDo
            });
        newToDo = string.Empty;
    }
}

Data\ToDoItem.cs:

namespace MyProjBlazorHybrid.Data {
    public class ToDoItem {
        public string? Title { get; set; } = string.Empty;
        public bool IsDone { get; set; } = false;
    }
}

Data\ToDoService.cs:

using System.Text.Json;

namespace MyProjBlazorHybrid.Data {
    public class ToDoService {
        string _file = string.Empty;

        public ToDoService() {
            _file = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "items.json");
        }

        public void SaveItems(IEnumerable<ToDoItem> items) {
            File.WriteAllText(_file, JsonSerializer.Serialize(items));
        }

        public IEnumerable<ToDoItem> LoadItems() {
            if (!File.Exists(_file)) {
                return Enumerable.Empty<ToDoItem>();
            }

            var itemsJSON = File.ReadAllText(_file);
            return JsonSerializer.Deserialize<IEnumerable<ToDoItem>>(itemsJSON) ?? Enumerable.Empty<ToDoItem>();
        }
    }
}

Components\Layout\MainLayout.razor:

@inherits LayoutComponentBase

<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <main>
        <div class="top-row px-4">
            <a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
        </div>

        <article class="content px-4">
            @Body
        </article>
    </main>
</div>

Components\Layout\NavMenu.razor:

<div class="top-row ps-3 navbar navbar-dark">
    <div class="container-fluid">
        <a class="navbar-brand" href="">MyProjBlazorHybrid</a>
    </div>
</div>

<input https://0.0.0.0/countertype="checkbox" title="Navigation menu" class="navbar-toggler" />

<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
    <nav class="flex-column">
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
            </NavLink>
        </div>
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="counter">
                <span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
            </NavLink>
        </div>
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="weather">
                <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather
            </NavLink>
        </div>
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="todo">
                <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> To-Dos
            </NavLink>
        </div>
    </nav>
</div>

EDIT: Here, have my MainPage.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MyProjBlazorHybrid"
             x:Class="MyProjBlazorHybrid.MainPage"
             BackgroundColor="{DynamicResource PageBackgroundColor}">

    <BlazorWebView x:Name="blazorWebView" HostPage="wwwroot/index.html">
        <BlazorWebView.RootComponents>
            <RootComponent Selector="#app" ComponentType="{x:Type local:Components.Routes}" />
        </BlazorWebView.RootComponents>
    </BlazorWebView>

</ContentPage>

Also, if I resize my Windows window so it's too narrow for the left-side nav bar, I see it then, too: enter image description here

Please let me know what else you need to see to help me. Thanks...


Solution

  • You wrote an input elemment in the Components\Layout\NavMenu.razor: and this is why you have an input box over the flyout button.

    You can remove the input below.

    <input https://0.0.0.0/countertype="checkbox" title="Navigation menu" class="navbar-toggler" />