Есть отличный пример проекта Xamarin.Forms под названием Empirical Font Size , который вычисляет максимально возможный размер шрифта для Label
в содержащем его представлении. Он берет рассматриваемую метку, использует VisualElement.Measure()
для получения некоторых запросов размера для метки на основе ее свойств и сравнивает запрошенные размеры с размером контейнера, чтобы увидеть, подойдет ли метка к этому размеру шрифта. Он выполняет пересчет до тех пор, пока не будет найден наиболее подходящий. Он отлично работает, но я хочу изменить его, чтобы сделать больше.
К сожалению, я столкнулся с некоторыми неприятными препятствиями в моих модификациях, и я не уверен, связаны ли они с C# или Xamarin . Вот что я хотел бы сделать.
- Извлечь вычисления в их собственную функцию для использования где угодно. -> Оригинал этого не делает. Этот бит на самом деле уже выполнен, но следующие цели не работают, поэтому хорошо использовать его в качестве отправной точки.
- (ФОКУСИРОВАТЬ ЗДЕСЬ) Избегайте использования исходных данных метки в функции. (Сделайте копию.) -> Я добавляю некоторые функции, которые требуют от меня активного изменения текстовых данных метки во время расчета размера, но изменение метки, которую я изменяю, может вызвать проблемы (не всегда с размером, но другими способами). Мне нужен способ дублировать метку для изменения размера шрифта, чтобы защитить исходные данные. (Подробнее о том, что я пробовал ниже).
- Абстрагируйте функцию, чтобы разрешить изменение размеров других представлений. -> Прямо сейчас рассчитывается только максимальный размер шрифта метки. Если возможно, я хотел бы поддерживать автоматическое изменение размера шрифта для других представлений, таких как сборщик, запись и т. Д. c. Пища для размышлений при выяснении №2.
Цель №2 - вот где у меня проблемы. Я не могу найти способ дублировать этикетку, а затем выполнить калибровку расчеты по временной копии. Вот что я пробовал и как каждая попытка не удалась.
- Сделайте мелкую копию. (например,
Label copyLabel = origLabel;
) -> Как и ожидалось, это не работает, потому что новая копия этикетки все еще ссылается на те же исходные данные этикетки в памяти. Так что если я установлю copyLabel.Text = "hello"
, тогда origLabel.Text
также изменится на «привет». Не очень хорошо. - JSON копировать -> Я видел рекомендаций по использованию JSON преобразователей для сериализации, а затем десериализации представления, чтобы выполнить быстрое глубокое копирование, но я получил исключение, когда попробовал это. Что-то о
self-referencing loop
в дочерних элементах метки. (У меток вообще есть дочерние элементы ??) - ICloneable -> Я буду запускать эту функцию в классе stati c, поэтому я не могу этого сделать. Однако это может не иметь значения из-за следующей попытки.
- Создайте новый объект Label и скопируйте некоторые значения. -> Кажется, это почти работает, но загвоздка здесь -
VisualElement.Measure()
расчет. На новой этикетке отсутствует что-то, что требуется для правильной работы расчетов, и я не знаю, что это такое.
Чтобы любой из них работал, мне нужно было бы скопировать этикетку немедленно выполнить вычисления на копии и применить полученный размер шрифта к оригиналу. Потом копия исчезает. Пуф! К сожалению, любая копия, которую я делаю, приводит к различным вычислениям, так что именно здесь я и застрял.
Кто-то упомянул в другом месте, что, возможно, размер не работает, потому что новая метка не является частью макета и таким образом, размер не может быть изменен, но они не объяснили, поэтому я не понимаю, к чему они пришли.
Чтобы увидеть, что работает, а что нет, вот небольшой пример проекта Xamarin с измененным версия проекта Empirical Font Size. Это простой A / B-тест. Две метки с одинаковым текстом имеют размер двух почти идентичных функций: одна использует исходную метку, а другая пытается использовать копию. Они должны заполнить верхнюю и нижнюю половины предоставленного макета стека, но копия не работает. Я бы хотел помочь в этой работе.
ИЗМЕНЕННЫЙ ОБРАЗЕЦ ПРОЕКТА: https://drive.google.com/file/d/1mWxE3p6u53jkIdaIEFVFnkI7BC-kfske/view?usp=sharing