简体   繁体   English

Android子页面上的FindViewById(使用Xamarin.Forms)

[英]FindViewById on Android Subpage (using Xamarin.Forms)

I'm developing a cross-platform app using Xamarin.Forms. 我正在使用Xamarin.Forms开发跨平台应用程序。 As I want to set the background of my TabLayouts to a gradient, which isn't natively supported by XF, I've written a custom renderer for my TabbedPages: 因为我想将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);
        }
    }
}

Now as intended the renderer gets triggered every time the app loads a TabbedPage. 现在按预期,每次应用程序加载TabbedPage时,都会触发渲染器。 However, _activity.FindViewById<TabLayout>(Resource.Id.sliding_tabs) always just returns the TabLayout of my MainPage (also properly setting MyGradient as background) and I can't figure out how to get the TabLayout on one of my subpages to modify it as well. 但是, _activity.FindViewById<TabLayout>(Resource.Id.sliding_tabs)总是只返回我的MainPage的TabLayout(也将MyGradient正确设置为背景),我不知道如何在我的一个子页面上获取TabLayout进行修改它也是。

Not sure if this is a problem with Xamarin or Android... 不确定这是否与Xamarin或Android有关...

Hope you guys can help me. 希望你们能帮助我。

Thanks! 谢谢!

Jan 一月

EDIT: here's the styles.xml (I hope that's what @Code-Apprentice was referring to): 编辑:这是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>

Also a screenshot of the MainPage's top: http://i.imgur.com/VyX3YX7.png 也是MainPage顶部的屏幕截图: http : //i.imgur.com/VyX3YX7.png

And it's subpage ( MainPage.Navigation.PushAsync(new SubPage()); ): http://i.imgur.com/pRmecjE.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). 我确实(通过渲染器)在我的应用程序中都获得了两个TabbedPages,但是我需要的是TabLayout(顶部的栏,其中包含Android上的标签)。

If I correctly understand your question this time, you want to customize the tab layout in TabbedPage for each subpage. 如果我这次正确理解了您的问题,则想在TabbedPage为每个子页面自定义选项卡布局。

Then you will need to override the SetTabIcon method in TabbedPageRenderer . 然后,您将需要重写TabbedPageRendererSetTabIcon方法。 For example: 例如:

[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);          
        }
    }
}

You can also check my answer in this question , there I placed a Button in the tab to remove the matching subpage. 您也可以检查我在此问题中的答案,在此选项卡中放置了一个“ Button ”以删除匹配的子页面。

For anyone else wondering, here's how I get the result I want now (even though I guess it's not the most elegant way of doing this): 对于任何其他想知道的人,这就是我现在想要的结果的方式(即使我认为这不是最优雅的方式):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM