Есть ли способ оформить TextView в верхнем регистре всех его букв?

239

Я хотел бы иметь возможность назначить атрибут или стиль xml для объекта, TextViewкоторый будет делать любой текст, который он имеет во ВСЕХ ЗАГЛАВНЫХ БУКВАХ.

Атрибуты android:inputType="textCapCharacters"и android:capitalize="characters"ничего не делают и выглядят так, как будто они предназначены для пользовательского текста, а не для TextView.

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

cottonBallPaws
источник
1
none inputType = "textCapCharacters", textAllCaps = "true" работает в smasung famili ^^. Я добавил к моему TextWatcher EditText что Колпачки все слова
murt

Ответы:

359

Хотя это была довольно разумная просьба, но похоже, что вы не можете сделать это в настоящее время. Что за полный провал. ржунимагу

Обновить

Теперь вы можете использовать textAllCaps, чтобы форсировать все заглавные буквы.

Терренс
источник
14
атрибуты textview определенно отсутствуют. было бы неплохо назначить ttf из папки атрибутов!
Натан Шверманн
8
Один из ответов на связанный вопрос предлагает 'android: textAllCaps = "true"' Это сработало для меня.
блаффи
@blaffie Спасибо за обновление. Я проверю, правильно ли работает android: textAllCaps = "true".
Терренс
1
Вы можете сделать это, используя атрибут «textAllCaps», отсюда и downvote.
JaydeepW
1
Похоже, textAllCapsвызывает приложение сбой, если вы указали android:fontFamilyв themes.xml.
Алаа М.
142

А как насчет Android: textAllCaps ?

Мерфи
источник
8
@ larham1 Это атрибут xml, поэтому я не вижу, как еще его можно использовать. Если не работает, сообщите об этом в Google. Я предполагаю, что он ограничен уровнем API 14, таким как setAllCaps (логическое значение).
Мерфи
1
Я только что проверил это, и это работает. У меня есть внешний файл стиля
7heViking
1
@ Мерфи, да, это проблема с версиями. SDK 14 и выше для setAllCaps (); не ясно, когда был добавлен XML, но я предполагаю, SDK 14 также.
larham1
Это странно, textAllCaps работает в простом тестовом проекте, но когда представление создается внутри ArrayAdapter.getView (), это не так. Все работает: background, textStyle и т. Д., Но textAllCaps нет :(
Y2i
1
@JawadLeWywadi, вы не можете использовать этот атрибут xml до API 14. Вы должны сделать это вручную в коде Java.
Мерфи
63

Используя AppCompat textAllCaps в приложениях для Android, поддерживающих более старые API (менее 14)

Существует один виджет пользовательского интерфейса, который поставляется вместе с AppCompat. Он называется CompatTextView. Это пользовательское расширение TextView, которое добавляет поддержку textAllCaps.

Для более нового Android API> 14 вы можете использовать:

android:textAllCaps="true"

Простой пример:

<android.support.v7.internal.widget.CompatTextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:textAllCaps="true"/>

Источник: developer.android

Обновить:

Как это случилось, CompatTextView был заменен AppCompatTextView в последней библиотеке appcompat-v7 ~ Eugen Pechanec

LOG_TAG
источник
Вы заметили внутреннее в android.support.v7.internal? Возможно, в следующей версии библиотеки поддержки больше не будет внутреннего, как в?
Эмануэль Меклин
1
Это круто! @EmanuelMoecklin Как только он появится в вашем проекте, он не будет волшебным путем.
Евгений Печанец
@eugen Конечно, вы никогда не обновляете библиотеку поддержки до последней версии, так как Google никогда не добавляет ничего полезного, верно?
Эмануэль Меклин,
@EmanuelMoecklin На самом деле я часто обновляюсь так быстро, что это нарушает мой код: Я полностью согласен, что вам следует опасаться использования внутренних ресурсов, НО я только что взглянул на источник appcompat-v7 и CompatTextViewиспользуется в ScrollingTabCointainerViewкотором используется ToolbarWidgetWrapper, что звучит довольно ново и пока имя держит «v7» в своем названии, это достаточно хорошая гарантия для меня, что CompatTextViewон останется там, где он есть.
Евгений Печанец
2
@EmanuelMoecklin Как это случилось, CompatTextViewбыл заменен AppCompatTextViewв последней библиотеке appcompat-v7. Вы были совершенно правы.
Евгений Печанец
30

Это действительно очень разочаровывает, что вы не можете сделать это с помощью styles ( <item name="android:textAllCaps">true</item>) или для каждого XML-файла макета с атрибутом textAllCaps , и единственный способ сделать это - на самом деле использовать theString.toUpperCase () для каждой из строк, когда вы делаете textViewXXX.setText (theString).

В моем случае я не хотел, чтобы везде в моем коде был метод theString.toUpperCase (), но имелось централизованное место для этого, потому что у меня были некоторые действия и списки макетов элементов с TextViews, которые должны быть написаны с заглавной буквы все время (a title) и другие, которые этого не сделали ... так что ... некоторые люди могут подумать, что это излишнее, но я создал свой собственный класс CapitalizedTextView, расширяющий android.widget.TextView, и переопределил метод setText, пишущий заглавные буквы на лету.

По крайней мере, если дизайн изменится или мне нужно удалить заглавные буквы в будущих версиях, мне просто нужно перейти на обычный TextView в файлах макета.

Теперь, примите во внимание, что я сделал это, потому что Дизайнер приложения действительно хотел, чтобы этот текст (заголовки) был в CAPS по всему приложению независимо от капитализации исходного содержимого, а также у меня были другие обычные TextView, где капитализация шла с фактическим содержимым. ,

Это класс:

package com.realactionsoft.android.widget;

import android.content.Context; 
import android.util.AttributeSet; 
import android.view.ViewTreeObserver; 
import android.widget.TextView;


public class CapitalizedTextView extends TextView implements ViewTreeObserver.OnPreDrawListener {

    public CapitalizedTextView(Context context) {
        super(context);
    }

    public CapitalizedTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CapitalizedTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        super.setText(text.toString().toUpperCase(), type);
    }

}

И всякий раз, когда вам нужно его использовать, просто объявите его со всем пакетом в макете XML:

<com.realactionsoft.android.widget.CapitalizedTextView 
        android:id="@+id/text_view_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

Некоторые утверждают, что правильный способ стилизации текста в TextView - это использование SpannableString , но я думаю, что это будет еще большим излишним, не говоря уже о том, что он потребляет больше ресурсов, потому что вы будете создавать экземпляр другого класса, чем TextView.

Оскар Сальгуэро
источник
9

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

Разница заключается в том, что вместо переопределения одного из setText()методов я использовал подход, аналогичный тому, что на TextViewсамом деле делает API 14+ (что, на мой взгляд, является более чистым решением).

Если вы посмотрите на источник , вы увидите реализацию setAllCaps():

public void setAllCaps(boolean allCaps) {
    if (allCaps) {
        setTransformationMethod(new AllCapsTransformationMethod(getContext()));
    } else {
        setTransformationMethod(null);
    }
}

AllCapsTransformationMethodКласс не является ( в настоящее время) общественности, но тем не менее, источник также доступен . Я немного упростил этот класс (убрал setLengthChangesAllowed()метод), поэтому полное решение таково:

public class UpperCaseTextView extends TextView {

    public UpperCaseTextView(Context context) {
        super(context);
        setTransformationMethod(upperCaseTransformation);
    }

    public UpperCaseTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTransformationMethod(upperCaseTransformation);
    }

    public UpperCaseTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setTransformationMethod(upperCaseTransformation);
    }

    private final TransformationMethod upperCaseTransformation =
            new TransformationMethod() {

        private final Locale locale = getResources().getConfiguration().locale;

        @Override
        public CharSequence getTransformation(CharSequence source, View view) {
            return source != null ? source.toString().toUpperCase(locale) : null;
        }

        @Override
        public void onFocusChanged(View view, CharSequence sourceText,
                boolean focused, int direction, Rect previouslyFocusedRect) {}
    };
}
Natix
источник
2

Кажется, что есть разрешение на настройку мобильной клавиатуры, поэтому самый простой способ сделать это:

editText.setFilters(new InputFilter[]{new InputFilter.AllCaps()});

надеюсь это сработает

Дирен Хамаль
источник
1

Проект PixlUI позволяет использовать textAllCaps в любом текстовом представлении или подклассе текстового представления, в том числе: Button, EditText AutoCompleteEditText, флажок RadioButton и несколько других.

Вам нужно будет создать свои текстовые представления, используя версию pixlui, а не из Android-источника, что означает, что вы должны сделать это:

<com.neopixl.pixlui.components.textview.TextView

        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world"
        pixlui:textAllCaps="true" />

PixlUI также позволяет вам установить пользовательский шрифт / шрифт, который вы поместите в вашу папку ресурсов.

Я работаю над вилкой Gradle платформы PixlUI, которая использует gradle и позволяет указывать textAllCaps, а также гарнитуру из стилей, вместо того, чтобы требовать их встраивания, как это делает исходный проект.

Мэтт Вулф
источник