0

我開始了我的第一個Xamarin Forms應用程序 - 目前只比Hello World多 - 但是我需要能夠將標題欄中的文本居中。我使用的MasterDetailPage有一個ContentPage作爲主和一個NavigationPage作爲細節。從下面的屏幕截圖中,我希望能夠將「主頁」居中。Xamarin Forms MasterDetail中心標題

我試過標記,就像Changing Actionbar Tab Text Size in AppCompact Theme的答案,但是沒有任何東西似乎影響文本的位置。我也試過了一個自定義渲染器,但是沒有奏效。

有沒有人能夠做到這一點?

用一些代碼更新我的問題。我MasterDeatil.cs:

public class MasterDetail : MasterDetailPage 
    { 
     Master master; 

     public MasterDetail() 
     { 
      master = new Master(); 

      Master = master; 
      Detail = new NavigationPage(new Home()); 

      master.ListView.ItemSelected += ListView_ItemSelected; 

      ToolbarItem cart = new ToolbarItem() 
      { 
       Text = "Test", 
       Icon = "shoppingcart.png" 
      }; 

      cart.Clicked += async (object sender, System.EventArgs e) => 
      { 
       await DisplayAlert("Done", "Msg", "Ok", "Can"); 
      }; 

      ToolbarItems.Add(cart); 
     } 

     private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e) 
     { 
      MasterItem item = e.SelectedItem as MasterItem; 

      if (item != null) 
      { 
       Detail = new NavigationPage((Page)Activator.CreateInstance(item.TargetType)); 
       master.ListView.SelectedItem = null; 
       IsPresented = false; 
      } 
     } 
    } 

代碼Master.cs:

public class MasterDetail : MasterDetailPage 
    { 
     Master master; 

     public MasterDetail() 
     { 
      master = new Master(); 

      Master = master; 
      Detail = new NavigationPage(new Home()); 

      master.ListView.ItemSelected += ListView_ItemSelected; 

      ToolbarItem cart = new ToolbarItem() 
      { 
       Text = "Test", 
       Icon = "shoppingcart.png" 
      }; 

      cart.Clicked += async (object sender, System.EventArgs e) => 
      { 
       await DisplayAlert("Done", "Msg", "Ok", "Can"); 
      }; 

      ToolbarItems.Add(cart); 
     } 

     private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e) 
     { 
      MasterItem item = e.SelectedItem as MasterItem; 

      if (item != null) 
      { 
       Detail = new NavigationPage((Page)Activator.CreateInstance(item.TargetType)); 
       master.ListView.SelectedItem = null; 
       IsPresented = false; 
      } 
     } 
    } 

代碼Detail.cs:

public class Detail : ContentPage 
    { 
     public Detail() 
     { 
      Title = "Shaves2U"; 
      Content = new StackLayout 
      { 
       Children = { 
        new Label { 
         Text = "Detail data goes here", 
         HorizontalOptions = LayoutOptions.Center, 
         VerticalOptions = LayoutOptions.CenterAndExpand 
        } 
       } 
      }; 
     } 
    } 

style.xml:

<?xml version="1.0" encoding="utf-8" ?> 
<resources> 
    <!-- Base theme applied no matter what API --> 
    <style name="MainTheme" parent="Theme.AppCompat"> 
    <!--If you are using revision 22.1 please use just windowNoTitle. Without android:--> 
    <item name="windowNoTitle">true</item> 
    <!--We will be using the toolbar so no need to show ActionBar--> 
    <item name="windowActionBar">false</item> 
    <!-- Set theme colors from http://www.google.com/design/spec/style/color.html#color-color-palette --> 
    <!-- colorPrimary is used for the default action bar background --> 
    <item name="windowActionModeOverlay">true</item> 

    <item name="android:datePickerDialogTheme">@style/AppCompatDialogStyle</item> 
    </style> 

    <style name="AppCompatDialogStyle" parent="Theme.AppCompat.Light.Dialog"> 
    <item name="colorAccent">#FF4081</item> 
    </style> 
</resources> 

我已經嘗試了以下style.xml:

<?xml version="1.0" encoding="utf-8" ?> 
<resources> 
    <!-- Base theme applied no matter what API --> 
    <style name="MainTheme" parent="Theme.AppCompat"> 
    <!--If you are using revision 22.1 please use just windowNoTitle. Without android:--> 
    <item name="windowNoTitle">true</item> 
    <!--We will be using the toolbar so no need to show ActionBar--> 
    <item name="windowActionBar">false</item> 
    <!-- Set theme colors from http://www.google.com/design/spec/style/color.html#color-color-palette --> 
    <!-- colorPrimary is used for the default action bar background --> 
    <item name="windowActionModeOverlay">true</item> 

    <item name="android:datePickerDialogTheme">@style/AppCompatDialogStyle</item> 
    <item name="android:actionBarTabTextStyle">@style/CustomTab</item> 
    </style> 

    <style name="AppCompatDialogStyle" parent="Theme.AppCompat.Light.Dialog"> 
    <item name="colorAccent">#FF4081</item> 
    </style> 
    <style name="CustomTab" parent="@android:style/Widget.AppCompat.ActionBar.TabText"> 
     <item name="android:gravity">center</item> 
    </style> 
</resources> 

我希望我剛剛拿到了XML錯誤

enter image description here

+1

你能否包含一些如何構建你的'MasterDetailPage'的代碼?只需附上您的問題的截圖,我們很難知道我們如何爲您提供幫助。另外,請注意'Xamarin.Forms'使用相應平臺的默認行爲。當涉及到Android的主細節頁面的標題時,標題通常始終保持對齊。 – Demitrian

+0

@Demitrian,我用一些源代碼更新了這個問題 – markpirvine

+0

看一下這個: https://forums.xamarin.com/discussion/59722/toolbar-title-set-center-align –

回答

0

在這裏,我將張貼我對這個問題的研究,所以我們可以繼續挖掘這一問題,避免使我再次犯錯。

請記住這種情況下的兩個重要條件:1.主控/細節佈局的MasterDetailPage控制; 2. ContentPage控制詳細頁面的佈局。

  1. Title是不是在Android項目的Toolbar的標題,它是ContentPage稱號。您可以通過在MainActivityOnCreate方法中註釋掉代碼ToolbarResource = Resource.Layout.Toolbar;來檢查該方法,或者通過刪除Title的值爲每個ContentPage進行檢查。所以修改Toolbar的樣式在這裏將不會有效。

  2. 基礎上的第一個結果,這個想法來自大自然,我們可以爲每個ContentPage去除Title的價值,共同修改的Toolbar這樣的佈局。

Toolbar.axml:

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/toolbar" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:background="?attr/colorPrimary" 
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
    android:popupTheme="@style/ThemeOverlay.AppCompat.Light"> 
    <TextView 
     android:id="@+id/mytitle" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerInParent="true" 
     android:layout_gravity="center" 
     android:text="11111" 
     android:textColor="@android:color/white" 
     android:textSize="20sp" 
     android:textStyle="bold" /> 
</android.support.v7.widget.Toolbar> 

它看起來很好,標題爲中心,但現在它來了第二個問題:選擇詳細信息頁面時如何更改標題文本。

  1. 爲了解決第二個問題,我爲3個細節ContentPage創建了一個客戶渲染併爲此渲染添加了程序集。

對於自定義的一部分ContentPage渲染,你可以參考Customizing a ContentPage,我說這樣的組件:

[assembly: ExportRenderer(typeof(ContactsPage), typeof(MyPageRenderer))] 
[assembly: ExportRenderer(typeof(ReminderPage), typeof(MyPageRenderer))] 
[assembly: ExportRenderer(typeof(TodoListPage), typeof(MyPageRenderer))] 

它解決的問題,我們可以在OnElementChanged方法得到ContentPage的名字像這樣:

var pageName = e.NewElement.GetType().FullName; 

似乎OK,現在來到我們的最後一個問題:如何將網頁名稱設置爲Toolbar,一個標題d這是我現在堅持的確切關鍵問題。

MainActivity我編寫這樣的:

var factory = LayoutInflater.From(this); 
var bar = factory.Inflate(ToolbarResource, null); 
var tv = (TextView)bar.FindViewById(Resource.Id.mytitle); 
tv.SetText("sdff", TextView.BufferType.Normal); 

它可以找到TextView,和TextView文字是「11111」,這是在XML的測試集,但新Text永遠不能被設置成功。

首先我以爲UI操作應該在UIThread中完成,所以我把代碼放在RunOnUiThreadnew Handler(Looper.MainLooper)中,但是仍然不起作用。然後,我想也許我得到了錯誤的Toolbar,由於錯誤的Contextvar factory = LayoutInflater.From(this);,但我永遠找不到正確的上下文。我也嘗試使用MasterDetailPage的源代碼Fragment找到這些片段,都失敗了。

然後我開始想,爲什麼不創建我們的工具欄,不用ToolbarResource = Resource.Layout.Toolbar;來創建工具欄。但通過檢查FormsAppCompatActivity的源代碼,我發現這個代碼:

if (ToolbarResource != 0) 
{ 
    bar = LayoutInflater.Inflate(ToolbarResource, null).JavaCast<AToolbar>(); 
    if (bar == null) 
     throw new InvalidOperationException("ToolbarResource must be set to a Android.Support.V7.Widget.Toolbar"); 
} 
else 
    bar = new AToolbar(this); 

SetSupportActionBar(bar); 

我永遠不會成功通過我們的自我,當我們MainActivityFormsAppCompatActivity繼承設置工具欄。

最後,我想也許我可以MainActivity繼承global::Xamarin.Forms.Platform.Android.FormsApplicationActivity而不是從global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity改變,我們也能做到設定的Toolbar由我們自己,還是失敗了,它將在該行LoadApplication(new App());拋出NullReferenceException和我在一個死衚衕再次。

所以涉及到我的解決辦法是創建一個自定義的渲染MasterDetailPage,並在OnElementChanged,創建TextView或東西,躺在頂部中心這種控制,更改文本也從自定義渲染的ContentPage

但我會稱這是一個愚蠢的,固執的想法,而不是一個解決方法,通過做所有這些工作,爲什麼不建立我們自己的視圖使用原生的android控件而不是使用xamarin的MasterDetailPage?除非我們能找到方法來設置原始ToolbarText,否則爲android應用程序創建我們自己的主細節視圖也應該是一種解決方法,我認爲這是一個更好的解決方案。

+0

嗨,Grace,很好的發現,你已經在那裏節省了數小時的研究工作,你有沒有找到任何其他解決方案? – Fahadsk