Android 子页面上的 FindViewById(使用 Xamarin.Forms)
FindViewById on Android Subpage (using Xamarin.Forms)
我正在使用 Xamarin.Forms 开发跨平台应用程序。因为我想将我的 TabLayouts 的背景设置为 XF 本身不支持的渐变,所以我为我的 TabbedPages 编写了一个自定义渲染器:
using Android.App;
using Android.Graphics;
using Android.Support.Design.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms.Platform.Android.AppCompat;
using MyApp.Droid.Renderer;
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedPageRenderer))]
namespace MyApp.Droid.Renderer
{
public class CustomTabbedPageRenderer : TabbedPageRenderer
{
private Activity _activity;
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
_activity = this.Context as FormsAppCompatActivity;
}
protected override void DispatchDraw(Canvas canvas)
{
base.DispatchDraw(canvas);
TabLayout tabs = _activity.FindViewById<TabLayout>(Resource.Id.sliding_tabs);
var gradient = new MyGradient();
tabs.SetBackground(gradient);
}
}
}
现在,每次应用程序加载 TabbedPage 时,渲染器都会按预期触发。
但是,_activity.FindViewById<TabLayout>(Resource.Id.sliding_tabs)
总是只是 returns 我的 MainPage 的 TabLayout(也正确地将 MyGradient 设置为背景),我不知道如何在我的一个子页面上获取 TabLayout 来修改它。
不确定这是 Xamarin 的问题还是 Android...
希望大家能帮帮我。
谢谢!
一月
编辑:这是 styles.xml(我希望那是@Code-Apprentice 所指的):
<resources>
<style name="MainTheme" parent="MainTheme.Base">
</style>
<!-- Base theme applied no matter what API -->
<style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<!--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="colorPrimary">#2196F3</item>
<!-- colorPrimaryDark is used for the status bar -->
<!--<item name="colorPrimaryDark">#1976D2</item>-->
<item name="colorPrimaryDark">#FF8630</item>
<!--<item name="android:windowTranslucentStatus">true</item>-->
<!-- colorAccent is used as the default value for colorControlActivated
which is used to tint widgets -->
<item name="colorAccent">#FF4081</item>
<!-- You can also set colorControlNormal, colorControlActivated
colorControlHighlight and colorSwitchThumbNormal. -->
<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>
还有主页首页的截图:http://i.imgur.com/VyX3YX7.png
它是子页面 ( MainPage.Navigation.PushAsync(new SubPage()); ): http://i.imgur.com/pRmecjE.png
I do get both TabbedPages in my App just fine (via the renderer), but what I need is the TabLayout (the bar on top that contains the tabs on Android).
如果我这次没有正确理解你的问题,你想在 TabbedPage
中为每个子页面自定义选项卡布局。
然后您需要重写 TabbedPageRenderer
中的 SetTabIcon
方法。例如:
[assembly: ExportRenderer(typeof(MyTabbedPage), typeof(MyTabbedPageRenderer))]
namespace YourNameSpace.Droid
{
public class MyTabbedPageRenderer : TabbedPageRenderer
{
protected override void SetTabIcon(TabLayout.Tab tab, FileImageSource icon)
{
base.SetTabIcon(tab, icon);
//set your custom layout for tab. The layout resource "mytablayout" is placed in the layout folder of android project.
tab.SetCustomView(Resource.Layout.mytablayout);
}
}
}
您也可以在这个 中查看我的回答,我在选项卡中放置了一个 Button
以删除匹配的子页面。
对于其他想知道的人,这是我现在如何获得我想要的结果(尽管我猜这不是最优雅的方法):
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Views;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms.Platform.Android.AppCompat;
using MyApp.Droid.Renderer;
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedPageRenderer))]
namespace MyApp.Droid.Renderer
{
public class CustomTabbedPageRenderer : TabbedPageRenderer
{
protected override void OnVisibilityChanged(Android.Views.View changedView, [GeneratedEnum] ViewStates visibility)
{
base.OnVisibilityChanged(changedView, visibility);
if (visibility == ViewStates.Visible)
{
var tabs = changedView.FindViewById<TabLayout>(Resource.Id.sliding_tabs);
var gradient = new MyGradient();
tabs.SetBackground(gradient);
}
}
}
}
我正在使用 Xamarin.Forms 开发跨平台应用程序。因为我想将我的 TabLayouts 的背景设置为 XF 本身不支持的渐变,所以我为我的 TabbedPages 编写了一个自定义渲染器:
using Android.App;
using Android.Graphics;
using Android.Support.Design.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms.Platform.Android.AppCompat;
using MyApp.Droid.Renderer;
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedPageRenderer))]
namespace MyApp.Droid.Renderer
{
public class CustomTabbedPageRenderer : TabbedPageRenderer
{
private Activity _activity;
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
_activity = this.Context as FormsAppCompatActivity;
}
protected override void DispatchDraw(Canvas canvas)
{
base.DispatchDraw(canvas);
TabLayout tabs = _activity.FindViewById<TabLayout>(Resource.Id.sliding_tabs);
var gradient = new MyGradient();
tabs.SetBackground(gradient);
}
}
}
现在,每次应用程序加载 TabbedPage 时,渲染器都会按预期触发。
但是,_activity.FindViewById<TabLayout>(Resource.Id.sliding_tabs)
总是只是 returns 我的 MainPage 的 TabLayout(也正确地将 MyGradient 设置为背景),我不知道如何在我的一个子页面上获取 TabLayout 来修改它。
不确定这是 Xamarin 的问题还是 Android...
希望大家能帮帮我。
谢谢!
一月
编辑:这是 styles.xml(我希望那是@Code-Apprentice 所指的):
<resources>
<style name="MainTheme" parent="MainTheme.Base">
</style>
<!-- Base theme applied no matter what API -->
<style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<!--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="colorPrimary">#2196F3</item>
<!-- colorPrimaryDark is used for the status bar -->
<!--<item name="colorPrimaryDark">#1976D2</item>-->
<item name="colorPrimaryDark">#FF8630</item>
<!--<item name="android:windowTranslucentStatus">true</item>-->
<!-- colorAccent is used as the default value for colorControlActivated
which is used to tint widgets -->
<item name="colorAccent">#FF4081</item>
<!-- You can also set colorControlNormal, colorControlActivated
colorControlHighlight and colorSwitchThumbNormal. -->
<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>
还有主页首页的截图:http://i.imgur.com/VyX3YX7.png
它是子页面 ( MainPage.Navigation.PushAsync(new SubPage()); ): http://i.imgur.com/pRmecjE.png
I do get both TabbedPages in my App just fine (via the renderer), but what I need is the TabLayout (the bar on top that contains the tabs on Android).
如果我这次没有正确理解你的问题,你想在 TabbedPage
中为每个子页面自定义选项卡布局。
然后您需要重写 TabbedPageRenderer
中的 SetTabIcon
方法。例如:
[assembly: ExportRenderer(typeof(MyTabbedPage), typeof(MyTabbedPageRenderer))]
namespace YourNameSpace.Droid
{
public class MyTabbedPageRenderer : TabbedPageRenderer
{
protected override void SetTabIcon(TabLayout.Tab tab, FileImageSource icon)
{
base.SetTabIcon(tab, icon);
//set your custom layout for tab. The layout resource "mytablayout" is placed in the layout folder of android project.
tab.SetCustomView(Resource.Layout.mytablayout);
}
}
}
您也可以在这个 Button
以删除匹配的子页面。
对于其他想知道的人,这是我现在如何获得我想要的结果(尽管我猜这不是最优雅的方法):
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Views;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms.Platform.Android.AppCompat;
using MyApp.Droid.Renderer;
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedPageRenderer))]
namespace MyApp.Droid.Renderer
{
public class CustomTabbedPageRenderer : TabbedPageRenderer
{
protected override void OnVisibilityChanged(Android.Views.View changedView, [GeneratedEnum] ViewStates visibility)
{
base.OnVisibilityChanged(changedView, visibility);
if (visibility == ViewStates.Visible)
{
var tabs = changedView.FindViewById<TabLayout>(Resource.Id.sliding_tabs);
var gradient = new MyGradient();
tabs.SetBackground(gradient);
}
}
}
}