Xamarin Android добавляет пространство между значком и текстом на вкладке TabbedPage

Я хочу, чтобы мое приложение Xamarin.Forms отображало значок и текст на вкладках. Я могу отображать значки FontAwesome с помощью TabbedRenderer, но значок и текст слишком близки друг к другу. Вот как это выглядит: введите здесь описание изображения

Другие раньше хотели добавить пространство между иконкой и текстом. Я понял, как визуализировать CustomView для содержимого вкладки с помощью TabbedRenderer, но я не могу получить желаемый результат. Ответов здесь недостаточно (многословные не обработанные тексты и т. д.). Ответ здесь от Маюреш Дешмукх звучит хорошо, но когда я пытаюсь создать представление со свойством app:tabInlineLabel, я получаю сообщение об ошибке, префикс пространства имен «приложение» не разрешается. Если бы я мог пройти мимо этого, я бы попытался настроить CustomView ActionBar на использование тега TabLayout, подобного тому, который включен в сообщение.

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

Я хочу, чтобы ширина вкладок увеличивалась по мере необходимости, чтобы соответствовать полному тексту, с горизонтальной прокруткой, если это необходимо. Некоторый перенос длинных текстов на 2-ю строку, как это иногда происходит по умолчанию, был бы в порядке, если бы интервал работал, но это необязательно - вот лучшая версия с переносом, которую я мог придумать... обрезано, поэтому непригодно для использования:

введите здесь описание изображения

Из этого кода представления:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_tab"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center_horizontal">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="centerInside"
        android:id="@+id/nav_icon"
        android:contentDescription=""
        android:layout_marginBottom="5px"
        android:layout_marginTop="5px"
        android:layout_weight="3"
    />

    <TextView
        android:id="@+id/nav_label"

        android:shadowColor="@android:color/black" 
        android:paddingLeft="5px"
        android:layout_marginBottom="5px"
        android:layout_marginTop="5px"
        
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="3"
        android:textColor="@android:color/white"
        

    />
</LinearLayout>

Вот версия, в которой текст не переносится... но вкладка не расширяется, чтобы соответствовать тексту:

введите здесь описание изображения

И код представления, который производит это:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_tab"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center_horizontal">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="centerInside"
        android:gravity="center_vertical"
        android:id="@+id/nav_icon"
        android:contentDescription=""
        android:paddingBottom="5px"
        android:paddingTop="5px"
        android:layout_marginTop="15px"
    />

    <TextView
        android:id="@+id/nav_label"

        android:shadowColor="@android:color/black" 
        android:paddingLeft="15px"
        android:paddingBottom="5px"
        android:paddingTop="20px"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:gravity="center_vertical"
        android:textColor="@android:color/white"
        android:singleLine="true"
        android:textAllCaps="true"

    />
</LinearLayout>

Это мой Android TabbedPageRenderer (который, я думаю, работает нормально — это макет, который, по моему мнению, нуждается в исправлении (я играл с жестко запрограммированным текстом, поэтому он не одинаков на всех моих скриншотах здесь, но в остальном это согласуется между скриншоты):

using System.Linq;

using Android.App;
using Android.Content;
using Android.Views;
using Android.Widget;
using Origami.MobileForms.Droid.Renderers;
using Origami.MobileForms.Droid.Utility;
using Origami.MobileForms.Pages;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;


[assembly: ExportRenderer(typeof(FormTabbedPage), typeof(ExtendedTabbedPageRenderer))]
namespace Origami.MobileForms.Droid.Renderers
{
    public static class DebugViewContents
    {

        public static void DebugLayout(this Android.Views.View self, int indent = 0)
        {
            // write info about me first
            var indents = new string('\t', indent);
            System.Diagnostics.Debug.WriteLine(indents + self.GetType().Name);

            // check if I'm a view group
            var vg = self as ViewGroup;
            if (vg == null) return;

            // enumerate my children
            var children = Enumerable.Range(0, vg.ChildCount).Select(x => vg.GetChildAt(x));

            // recurse on each child
            foreach (var child in children)
                DebugLayout(child, indent + 1);
        }
    }
    public class ExtendedTabbedPageRenderer : TabbedRenderer
    {
        public ExtendedTabbedPageRenderer(Context context) : base(context) { }

        protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
        {
            Activity activity = this.Context as Activity;
            if (activity.ActionBar.TabCount > 0)
            {
                SetTabIcons();
            }

            base.DispatchDraw(canvas);
        }

        private void SetTabIcons()
        {

            var element = this.Element;
            if (null == element)
            {
                return;
            }

            Activity activity = this.Context as Activity;
            if ((null != activity && null != activity.ActionBar && activity.ActionBar.TabCount > 0))
            {
                for (int i = 0; i < element.Children.Count; i += 1)
                {
                    Android.App.ActionBar.Tab tab = activity.ActionBar.GetTabAt(i);

                    var page = element.Children[i];
                    if ((null != tab) && (null != page) && (null != page.IconImageSource))
                    {
                        if (tab.CustomView == null)
                        {
                            var iconKey = "\uf15c";
                            int fontSize = 30;
                            string fontName = "FontAwesome.otf";
                            // IconDrawable class copied from https://github.com/winstongubantes/Xamarin.Forms/blob/master/CustomIconizeFont/CustomIconizeFont/CustomIconizeFont.Android/Custom/Utils/IconDrawable.cs, with slight modifications to how it loads the typeface
                            var drawable = new IconDrawable(this.Context, iconKey, fontName).Color(Xamarin.Forms.Color.White.ToAndroid()).SizeDp(fontSize);
                            tab.SetIcon(drawable);
                            if (tab.Text.Contains("Child"))
                                tab.SetText("The Child Tab");
                            else
                                tab.SetText("The Parent Tab");

                            LayoutInflater layoutInflater = LayoutInflater.From(this.Context);
                            Android.Views.View view = layoutInflater.Inflate(Resource.Layout.IconAndText, null);

                            TextView tab_label = (TextView)view.FindViewById(Resource.Id.nav_label);
                            tab_label.SetText(tab.Text.ToCharArray(), 0, tab.Text.ToCharArray().Length);
                            ImageView tab_icon = (ImageView)view.FindViewById(Resource.Id.nav_icon);
                            tab_icon.SetImageDrawable(tab.Icon);

                            tab.SetCustomView(view);
                        }

                    }
                }
            }
        }
    }


}

Я играл с макетом больше дня, но так и не смог стать лучше, чем этот. Любая идея, как я могу увидеть макет по умолчанию и/или изменить свой макет, чтобы он выглядел как по умолчанию, за исключением отступов между значком и текстом?

В качестве альтернативы, совершенно другая стратегия заключается в добавлении отступов к значку. Учитывая, что я использую значки FontAwesome и отображаю их в виде рисунков, используя этот класс, который кажется потенциально выполнимым. В методе Draw этого класса я попытался добавить пробелы после _iconChar при установке textValue. Это создало пространство справа от значка, но сместило значок влево и обрезало левую часть значка. Это показывает его с 3 конечными пробелами. С одним выглядит довольно хорошо с некоторыми иконками, но ужасно/явно обрезано с другими.

введите здесь описание изображения

Помощь с любым или всеми из следующих будет очень полезно!

  1. с помощью приложения: варианты на мой взгляд и/или
  2. просмотр содержимого представления по умолчанию и/или
  3. настройка моего представления, чтобы оно работало правильно и/или
  4. Изменение функциональности IconDrawable для небольшого уменьшения значка, чтобы он помещался с одним или двумя завершающими пробелами в пространстве, отведенном значку на вкладке Android.

person user756366    schedule 22.10.2020    source источник