How can I place a button in the the tabs of a Tabb

2020-02-06 17:51发布

问题:

I am using a Tabbed Page combined with a Master Detail Page for navigation in my Xamarin.Forms app. Currently when a menu option is selected from the Master Detail Page a new tabbed page is added with the page's content. I want to place a button to close the tab in the title field of the tab. Is this possible? Currently I just have a button within the content page for the tab, but this is less than ideal. I want it to be very web browser like. Thanks in advance!

Edit: I have added the image. Basically, I just want to add an "X" button to the right of each item in the tab bar that would allow me to close that tab. Just like you would in Chrome or something.

回答1:

You can use custom renderer to create your custom TabbedPage in android platform. Disagree with Yuri, on android we can add an image to tab, in fact we can customize the layout of tab.

Since in your image, I saw you didn't use the Icon property for each tab, I use this icon as a close button. But sure you can also not use this, it is self customized.

In PCL, create a MyTabbedPage:

public class MyTabbedPage : TabbedPage
{
}

In Android platform create a renderer for it:

[assembly: ExportRenderer(typeof(MyTabbedPage), typeof(MyTabbedPageRenderer))]

namespace YOURNAMESPACE.Droid
{
    public class MyTabbedPageRenderer : TabbedPageRenderer
    {
        private ObservableCollection<Xamarin.Forms.Element> children;
        private IPageController controller;

        protected override void SetTabIcon(TabLayout.Tab tab, FileImageSource icon)
        {
            base.SetTabIcon(tab, icon);

            tab.SetCustomView(Resource.Layout.mytablayout);

            var imagebtn = tab.CustomView.FindViewById<ImageButton>(Resource.Id.closebtn);
            imagebtn.SetBackgroundDrawable(tab.Icon);

            var title = tab.CustomView.FindViewById<TextView>(Resource.Id.tabtitle);
            title.Text = tab.Text;

            imagebtn.Click += (sender, e) =>
            {
                var closebtn = sender as ImageButton;
                var parent = closebtn.Parent as Android.Widget.RelativeLayout;
                var closingtitle = parent.FindViewById<TextView>(Resource.Id.tabtitle);
                foreach (var child in children)
                {
                    var page = child as ContentPage;
                    if (page.Title == closingtitle.Text)
                    {
                        children.Remove(child);
                        break;
                    }
                }
            };
        }

        protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement != null)
            {
                controller = Element as IPageController;
                children = controller.InternalChildren;
            }
        }
    }
}

Use it like this:

<local:MyTabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:TabbedPageForms"
             x:Class="TabbedPageForms.MainPage">

    <local:TodayPage Title="Today" Icon="hamburger.jpg" />

    <local:SchedulePage Title="Schedule" Icon="hamburger.jpg" />
</local:MyTabbedPage>

Code behind, don't forget to change MainPage to inherit from MyTabbedPage:

public partial class MainPage : MyTabbedPage
{
    public MainPage()
    {
        InitializeComponent();
    }
}

Please pay attention here, if you look closer to my code, you will find that I used Title of each tab for the comparing and removing the matching item, it will find the first matched title and remove the page of that title. This may cause a problem if you have several tabs with the same title. This is a potential bug of this demo, you may try to solve it.

Update:

Forgot to post the code of mytablayout, here is it:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <TextView android:id="@+id/tabtitle"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_centerInParent="true"
            android:gravity="center_horizontal" />

  <ImageButton
    android:id="@+id/closebtn"
    android:layout_height="30dp"
    android:layout_width="30dp"
    android:scaleType="fitCenter"
    android:layout_alignParentRight="true"
    android:gravity="center" />
</RelativeLayout>