XAML in Xamarin.Forms 基礎篇 電子書

特別說明

2017/01/30

Xamarin FAQ 1-29 : 如何客製導航抽屜的抽屜面板

問題

使用 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);
        }
    }
}


沒有留言:

張貼留言