0

Я начинаю свое первое приложение Xamarin Forms - немного больше, чем Hello World на данный момент - однако мне нужно иметь возможность центра текста в строке заголовка. Я использую MasterDetailPage, который имеет ContentPage как Master и NavigationPage как Detail. На снимок экрана ниже я хотел бы иметь возможность центрировать «Дом».Xamarin Forms MasterDetail Center Название

Я пробовал разметку, как ответ от 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> 

I попробовали следующий стиль.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 не название Toolbar в андроиде проекта, это название ContentPage. Вы можете проверить это, комментируя код ToolbarResource = Resource.Layout.Toolbar; в методе MainActivityOnCreate или удалив значение Title за каждые ContentPage. Поэтому изменение стиля Toolbar здесь никогда не будет работать.

  2. на основе первого результата, идея приходит природа, что мы можем удалить значение Title для каждого ContentPage, и вместе изменяющее макет 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))] 

Это решить эту проблему, мы можем получить имя ContentPage «s в методе OnElementChanged как это:

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

Кажется ОК и теперь приходит на наш последний вопрос: Как установить название страницы с названием 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, поэтому я поместил код в RunOnUiThread или в new Handler(Looper.MainLooper), но все-таки не работает. Тогда я думаю, что, может быть, я ошибаюсь Toolbar из-за неправильного Context: var 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); 

Я никогда не успех, чтобы установить панель инструментов нашей самости, когда наш MainActivity наследуется от FormsAppCompatActivity.

Наконец, я думаю, что, может быть, я могу изменить MainActivity наследовать от global::Xamarin.Forms.Platform.Android.FormsApplicationActivity вместо от global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, поэтому мы можем установить Toolbar нашей собственной личностью, до сих пор не удалось, он будет бросать NullReferenceException на линии LoadApplication(new App()); и я в тупике еще раз.

Так приходит мне обходной путь, создать пользовательские визуализации для MasterDetailPage, и в OnElementChanged, создать TextView или что-то и лежал этот контроль в верхней части, изменить текст также от обычая визуализации ContentPage.

Но я бы назвал это глупой, упрямой идеей, а не обходным путем, потому что, выполняя всю эту работу, почему бы не построить наш собственный взгляд, используя собственный контроль андроида вместо использования xamarin's MasterDetailPage? Если мы не сможем найти способ установить Text оригинала Toolbar, создание нашего собственного детального представления для приложения для Android также должно быть обходным решением, лучшим из которых я считаю.

+0

Привет, Грейс, отличная находка, вы сохранили часы исследовательской работы там, нашли ли вы какое-нибудь другое решение для этого? – Fahadsk

Смежные вопросы