我正在开始我的第一个Xamarin Forms应用程序 - 目前只比Hello World更多 - 但是我需要能够将标题栏中的文本居中。我正在使用MasterDetailPage,其中ContentPage为Master,NavigationPage为Detail。从下面的屏幕截图中,我希望能够以'Home'为中心。
我尝试过标记,就像来自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错误
答案 0 :(得分:0)
在这里,我将发表关于这个问题的研究,因此我们可以继续挖掘这个问题,避免再犯错误。
请记住这种情况的两个重要条件:1。MasterDetailPage
控制主/细节布局; 2. ContentPage
控制详细页面的布局。
Title
不是android项目中Toolbar
的标题,它是ContentPage
的标题。您可以通过在ToolbarResource = Resource.Layout.Toolbar;
的{{1}}方法中注释掉代码MainActivity
或删除每个OnCreate
的{{1}}值来检查此问题。因此,修改Title
的样式将永远不会在这里工作。
根据第一个结果,我们可以删除每个ContentPage
Toolbar
的值,然后一起修改Title
的布局。
Toolbar.axml:
ContentPage
看起来很好,标题位于中心,但现在它出现了第二个问题:如何在选择详细信息页面时更改标题文本。
Toolbar
创建了一个客户渲染,并为此渲染添加了程序集。对于自定义<?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>
渲染的部分,您可以参考Customizing a ContentPage,我添加了这样的程序集:
ContentPage
它解决了问题,我们可以在ContentPage
方法中获取[assembly: ExportRenderer(typeof(ContactsPage), typeof(MyPageRenderer))]
[assembly: ExportRenderer(typeof(ReminderPage), typeof(MyPageRenderer))]
[assembly: ExportRenderer(typeof(TodoListPage), typeof(MyPageRenderer))]
的名称,如下所示:
ContentPage
似乎没问题,现在回答我们的最后一个问题:如何将页面名称设置为OnElementChanged
的标题,这是我现在坚持的确切关键问题。
在我编码的var pageName = e.NewElement.GetType().FullName;
中:
Toolbar
它可以找到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);
的文本是“11111”,它在xml中设置用于测试,但新的TextView
永远不能成功设置。
首先我认为UI操作应该在UIThread中完成,因此我将代码放在TextView
或Text
中,但仍然无效。然后我想可能由于错误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
的自定义渲染。
但我会称这是一个愚蠢的,顽固的想法,而不是一个解决方法,因为做了所有这些工作,为什么不使用本机android控件而不是使用xamarin的TextView
来构建我们自己的视图?除非我们能找到设置原始ContentPage
的{{1}}的方法,否则为Android应用创建我们自己的主要详细信息视图也应该是一种解决方法,我认为这是一个更好的方法。
答案 1 :(得分:0)
我知道这是一个非常老的问题,我在寻找其他东西时发现了它。该解决方案在Xamarin Forms中非常简单。只需在您的 ContentPage 中添加一个 NavigationPage.TitleView 标记。这样,您可以将任何样式的所需内容添加到导航栏:
ContentPage
<NavigationPage.TitleView>
<Label Text="Centered Title" Style="{StaticResource TitleStyle}" />
</NavigationPage.TitleView>
样式可以是全局的(即:在App.xaml中):
<Style TargetType="Label" x:Key="TitleStyle">
<Setter Property="TextColor" Value="WhiteSmoke" />
<Setter Property="FontSize" Value="Medium" />
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>