Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion samples/MauiPdfViewerSample/AppShell.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiPdfViewerSample"
FlyoutBehavior="Flyout"
Title="MauiPdfViewerSample">

<!-- Make PdfTestPage the app's main ShellContent -->
<!-- Dedicated repro harness for layering / composition issues (e.g. issue #8).
Listed first so the app lands here on launch. -->
<ShellContent
Title="Repro Lab"
ContentTemplate="{DataTemplate local:LayoutReproPage}"
Route="LayoutReproPage" />

<!-- Main viewer -->
<ShellContent
Title="PDF Viewer"
ContentTemplate="{DataTemplate local:PdfTestPage}"
Expand Down
107 changes: 107 additions & 0 deletions samples/MauiPdfViewerSample/LayoutReproPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?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:pdf="http://eightbot.com/maui/pdfview"
x:Class="MauiPdfViewerSample.LayoutReproPage"
Title="Repro Lab">

<!--
░░ REPRO LAB ░░
A dedicated harness for reproducing and validating layering/composition
issues. Today it targets GitHub issue #8 (row-0 / overlapping content is
hidden unless BackgroundColor is set, plus scroll-time flicker), but it is
intended to grow: add a new repro scenario by extending the controls below.

How to use:
• Layout – switch between "Overlay" (header shares the PdfView cell, the
faithful #8 repro) and "Stacked" (header in a separate row, the
control case that should always work).
• BG – cycle the PdfView background: (unset) → Transparent → White.
#8 says row-0 content vanishes when the background is unset.
• Header Z – bump the overlay header's ZIndex (the commenter's flicker
workaround) to test scroll-time flicker.
-->

<Grid RowDefinitions="*,Auto" BackgroundColor="#0F172A">

<!-- ══════════════ REPRO REGION (the thing under test) ══════════════ -->
<Grid x:Name="ReproHost" Grid.Row="0" RowDefinitions="*">

<!-- PdfView fills the cell. Deliberately NO BackgroundColor set in XAML
so the page opens in the exact failing state from issue #8. -->
<pdf:PdfView x:Name="PdfViewer"
Grid.Row="0"
HorizontalOptions="Fill"
VerticalOptions="Fill"
FitPolicy="Width"
EnableSwipe="True"
EnableZoom="True"
EnableTapGestures="False"
DocumentLoaded="OnDocumentLoaded"
Error="OnError" />

<!-- "Row 0" content. In Overlay mode it shares the cell with the PdfView
and should remain visible. InputTransparent so it never blocks PDF
scroll/zoom gestures underneath it. -->
<Border x:Name="HeaderBand"
Grid.Row="0"
InputTransparent="True"
VerticalOptions="Start"
BackgroundColor="#CC1D4ED8"
StrokeThickness="0"
Padding="16,12">
<VerticalStackLayout Spacing="2">
<Label Text="ROW 0 HEADER — must stay visible"
TextColor="White"
FontAttributes="Bold"
FontSize="16" />
<Label x:Name="HeaderSubLabel"
Text="If you can't see this over the PDF, issue #8 is reproducing."
TextColor="#DBEAFE"
FontSize="12" />
</VerticalStackLayout>
</Border>
</Grid>

<!-- ══════════════ CONTROL PANEL ══════════════ -->
<VerticalStackLayout Grid.Row="1"
Padding="12,10"
Spacing="10"
BackgroundColor="#111826">
<BoxView HeightRequest="1" Color="#1E293B" VerticalOptions="Start" />

<Label x:Name="StateLabel"
Text=""
TextColor="#94A3B8"
FontSize="12" />

<Grid ColumnDefinitions="*,*,*" ColumnSpacing="8">
<Button Grid.Column="0"
x:Name="LayoutButton"
Text="Layout: Overlay"
FontSize="13"
Padding="8,10"
TextColor="White"
BackgroundColor="#1D2437"
Clicked="OnToggleLayout" />
<Button Grid.Column="1"
x:Name="BgButton"
Text="BG: (unset)"
FontSize="13"
Padding="8,10"
TextColor="White"
BackgroundColor="#1D2437"
Clicked="OnCycleBackground" />
<Button Grid.Column="2"
x:Name="ZIndexButton"
Text="Header Z: 0"
FontSize="13"
Padding="8,10"
TextColor="White"
BackgroundColor="#1D2437"
Clicked="OnToggleZIndex" />
</Grid>
</VerticalStackLayout>

</Grid>
</ContentPage>
144 changes: 144 additions & 0 deletions samples/MauiPdfViewerSample/LayoutReproPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
using MauiNativePdfView;
using MauiNativePdfView.Abstractions;

namespace MauiPdfViewerSample;

/// <summary>
/// Dedicated repro harness for layering / composition issues.
///
/// Primary target: GitHub issue #8 — content placed in the same Grid region as a
/// <c>PdfView</c> ("row 0") is invisible unless <c>BackgroundColor</c> is set, and
/// overlapping content flickers while the PDF scrolls.
///
/// This page is intentionally self-contained and toggle-driven so new layering
/// scenarios can be added over time without disturbing the main viewer page.
/// </summary>
public partial class LayoutReproPage : ContentPage
{
private enum BackgroundMode { Unset, Transparent, Opaque }

private BackgroundMode _backgroundMode = BackgroundMode.Unset;
private bool _overlayLayout = true; // true = Overlay (faithful #8 repro), false = Stacked (control case)
private bool _headerOnTop; // true = header ZIndex bumped (flicker workaround)

public LayoutReproPage()
{
InitializeComponent();

// Open in the exact failing state from issue #8: overlay layout, background unset.
ApplyLayout();
ApplyBackground();
ApplyZIndex();

PdfViewer.Source = PdfSource.FromAsset("sample.pdf");
}

// ── Layout: Overlay vs Stacked ────────────────────────────────────────────
private void OnToggleLayout(object? sender, EventArgs e)
{
_overlayLayout = !_overlayLayout;
ApplyLayout();
}

private void ApplyLayout()
{
if (_overlayLayout)
{
// Header and PdfView share a single cell — the faithful issue #8 repro.
ReproHost.RowDefinitions = new RowDefinitionCollection(
new RowDefinition { Height = GridLength.Star });

Grid.SetRow(PdfViewer, 0);
Grid.SetRow(HeaderBand, 0);
HeaderBand.VerticalOptions = LayoutOptions.Start;
LayoutButton.Text = "Layout: Overlay";
}
else
{
// Header in its own row above the PdfView — the control case that
// should always render correctly regardless of background.
ReproHost.RowDefinitions = new RowDefinitionCollection(
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Star });

Grid.SetRow(HeaderBand, 0);
HeaderBand.VerticalOptions = LayoutOptions.Fill;
Grid.SetRow(PdfViewer, 1);
LayoutButton.Text = "Layout: Stacked";
}

UpdateStateLabel();
}

// ── Background: (unset) → Transparent → Opaque ─────────────────────────────
private void OnCycleBackground(object? sender, EventArgs e)
{
_backgroundMode = _backgroundMode switch
{
BackgroundMode.Unset => BackgroundMode.Transparent,
BackgroundMode.Transparent => BackgroundMode.Opaque,
_ => BackgroundMode.Unset,
};
ApplyBackground();
}

private void ApplyBackground()
{
switch (_backgroundMode)
{
case BackgroundMode.Unset:
// Closest thing to "never set in XAML": reset to the property default (null).
PdfViewer.ClearValue(VisualElement.BackgroundColorProperty);
BgButton.Text = "BG: (unset)";
break;
case BackgroundMode.Transparent:
PdfViewer.BackgroundColor = Colors.Transparent;
BgButton.Text = "BG: Transparent";
break;
case BackgroundMode.Opaque:
PdfViewer.BackgroundColor = Colors.White;
BgButton.Text = "BG: White";
break;
}

UpdateStateLabel();
}

// ── Header ZIndex (flicker workaround toggle) ──────────────────────────────
private void OnToggleZIndex(object? sender, EventArgs e)
{
_headerOnTop = !_headerOnTop;
ApplyZIndex();
}

private void ApplyZIndex()
{
HeaderBand.ZIndex = _headerOnTop ? 10 : 0;
ZIndexButton.Text = _headerOnTop ? "Header Z: 10" : "Header Z: 0";
UpdateStateLabel();
}

// ── Status readout ─────────────────────────────────────────────────────────
private void UpdateStateLabel()
{
var layout = _overlayLayout ? "Overlay" : "Stacked";
var bg = _backgroundMode switch
{
BackgroundMode.Unset => "unset",
BackgroundMode.Transparent => "Transparent",
_ => "White (opaque)",
};
StateLabel.Text = $"Layout={layout} • Background={bg} • Header ZIndex={HeaderBand.ZIndex}";
}

// ── PdfView events ─────────────────────────────────────────────────────────
private void OnDocumentLoaded(object? sender, DocumentLoadedEventArgs e)
{
HeaderSubLabel.Text = $"{e.PageCount} pages loaded — scroll to test flicker.";
}

private async void OnError(object? sender, PdfErrorEventArgs e)
{
await DisplayAlert("PDF Error", e.Message, "OK");
}
}
14 changes: 7 additions & 7 deletions src/MauiNativePdfView/Platforms/Android/PdfViewAndroid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class PdfViewAndroid : IPdfView, IDisposable
public PdfViewAndroid(Context context)
{
_pdfView = new PDFView(context, null);
_pdfView.SetBackgroundColor(global::Android.Graphics.Color.Transparent);
}

/// <summary>
Expand Down Expand Up @@ -227,16 +228,15 @@ public Color? BackgroundColor
set
{
_backgroundColor = value;
if (value != null)
{
var androidColor = global::Android.Graphics.Color.Argb(
var androidColor = value != null
? global::Android.Graphics.Color.Argb(
(int)(value.Alpha * 255),
(int)(value.Red * 255),
(int)(value.Green * 255),
(int)(value.Blue * 255));
_pdfView.SetBackgroundColor(androidColor);
_pdfView.Invalidate();
}
(int)(value.Blue * 255))
: global::Android.Graphics.Color.Transparent;
_pdfView.SetBackgroundColor(androidColor);
_pdfView.Invalidate();
}
}

Expand Down