問題
使用 Xamarin.Forms 開發一個導航抽屜頁面 ( MasterDetailPage ) ,您會發現到在 Android 平台下,當抽屜從左往右滑動出來,狀態列會被遮蓋掉,若想解決這類抽屜上的相關問題 ( 變更抽屜寬度、暫時隱藏狀態列 ),這些需求該如何處理呢?
解答
底下的螢幕截圖將會在 Android 平台下執行的結果,這裡範例專案中,一開始是提供一個 MasterDetailPage / NavigationPage / ContentPage,執行結果如下:
若沒有特別設定的情況下,當我們點選了左上方的漢堡按鈕,會推出一個面板,但是,這個面板會佔據調螢幕最上方的狀態列。
此時,若想要設計出這樣的效果,當導航抽屜推出來的時候,不要遮蔽掉最上方的狀態列,甚至上方的工具列的工具列,您可以在
MasterDetailPage.Master
這個屬性內的 ContentPage
來指定抽屜的上方要內縮一小段距離,這樣就不會把狀態列或者工具列給遮蔽掉了。例如,底下的 XAML 範例中,就是使用了 ContentPage.Padding
屬性來設定;經過這樣的設定,導航抽屜的顯示效果如下圖所示。<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="XFMDStatusBar.Views.MDPadding">
<MasterDetailPage.Master>
<ContentPage
Title="Master"
BackgroundColor="Transparent"
Padding="0,80,0,0">
<Grid>
<BoxView
Color="Pink"/>
<Label Text="「多奇數位創意」是一群擁有理想與信念的網際網路資源整合團隊,致力於達成「數位創意服務」的願景,追求不斷的卓越創新是我們的信念"
HorizontalOptions="Center" VerticalOptions="Center"
Margin="20"
TextColor="White"
/>
</Grid>
</ContentPage>
</MasterDetailPage.Master>
</MasterDetailPage>
接下來的需求那就是想要做到導航抽屜面板寬度不要這麼寬,此時,您可以參考底下的 XAML 宣告;此時,我們的最上方的工具列與狀態列不用被遮蔽掉的需求,可以在 ContentPage 內的 Grid 控制巷內,設定 Padding 的屬性值,定義上方內縮值。至於寬度上,同樣可以在 Grid 控制項上設定右側內縮,此時,這樣的執行效果會如下圖所示。
<?xml version="1.0" encoding="utf-8" ?>
<local:MyMD xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
xmlns:local="clr-namespace:XFMDStatusBar"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="XFMDStatusBar.Views.MDRenderer">
<MasterDetailPage.Master>
<ContentPage
Title="Master"
BackgroundColor="Transparent">
<Grid
Margin="0,55,150,0"
>
<BoxView
Color="Yellow"/>
<Label Text="「多奇數位創意」是一群擁有理想與信念的網際網路資源整合團隊,致力於達成「數位創意服務」的願景,追求不斷的卓越創新是我們的信念"
HorizontalOptions="Center" VerticalOptions="Center"
Margin="10"
TextColor="Black"
/>
</Grid>
</ContentPage>
</MasterDetailPage.Master>
</local:MyMD>
不過,在這個範例中您可以發現到,這個 XAML 頁面的根項目是
local:MyMD
,不過,這個項目是個客製化控制項,這個類別是繼承 MasterDetailPage
類別,並且在 Android 平台下宣告一個 Renderer ,讓這個導航抽屜頁面執行的時候,是沒有狀態列;像是這樣的需求就可以透過底下程式碼來做到。[assembly: ExportRenderer(typeof(MyMD), typeof(MyMDRenderer))]
namespace XFMDStatusBar.Droid
{
public class MyMDRenderer : MasterDetailPageRenderer
{
public override void AddView(Android.Views.View child)
{
child.GetType().GetRuntimeProperty("TopPadding").SetValue(child, 0);
var padding = child.GetType().GetRuntimeProperty("TopPadding").GetValue(child);
base.AddView(child);
}
}
}