Czy istnieje sposób na stylizowanie TextView do wielkich liter wszystkich jego liter?

239

Chciałbym móc przypisać atrybut lub styl xml do TextViewtego, który utworzy dowolny tekst we WSZYSTKICH LITERACH.

Atrybuty android:inputType="textCapCharacters"i android:capitalize="characters"nic nie robią i wyglądają tak, jakby były dla tekstu wprowadzonego przez użytkownika, a nie TextView.

Chciałbym to zrobić, aby oddzielić styl od treści. Wiem, że mógłbym to zrobić programowo, ale znów chcę zachować styl z dala od treści i kodu.

cottonBallPaws
źródło
1
ani inputType = "textCapCharacters", textAllCaps = „true” działa w przypadku smili famili ^^. Dodałem TextWatcher do mojego EditText że Caps wszystkie słowa
Murt

Odpowiedzi:

359

Myślałem, że to dość rozsądna prośba, ale wygląda na to, że nie możesz tego zrobić w tej chwili. Co za totalna awaria. lol

Aktualizacja

Możesz teraz użyć textAllCaps do wymuszenia wszystkich wielkich liter .

Terrance
źródło
14
Zdecydowanie brakuje atrybutów widoku tekstu. fajnie byłoby również przypisać ttf z folderu atrybutów!
Nathan Schwermann,
8
Jedna z odpowiedzi na połączone pytanie sugeruje „android: textAllCaps =" true "'To zadziałało dla mnie.
blaffie
@blaffie Dzięki za aktualizację. Sprawdzę, czy android: textAllCaps = "true" działa poprawnie.
Terrance
1
Możesz to zrobić za pomocą atrybutu „textAllCaps”, stąd opinia negatywna.
JaydeepW
1
Wygląda na to, textAllCapsże powoduje awarię aplikacji, jeśli podałeś android:fontFamilyw themes.xml.
Alaa M.,
142

Co z Androidem: textAllCaps ?

Murphy
źródło
8
@ larham1 Jest to atrybut xml, więc nie widzę, jak inaczej można go użyć. Jeśli nie działa, zgłoś to do Google. Przypuszczam, że jest ograniczony do poziomu API 14, jak setAllCaps (boolean).
Murphy
1
Właśnie to przetestowałem i działa. Mam plik zewnętrznego stylu
7heViking,
1
@Murphy tak, jest to problem z wersją. SDK 14 i nowsze wersje dla setAllCaps (); nie jest jasne, kiedy dodano xml, ale zakładam również SDK 14.
larham1
To dziwne, textAllCaps działa w prostym projekcie testowym, ale kiedy widok jest tworzony w ArrayAdapter.getView (), nie działa. Wszystko działa: tło, textStyle itp., Ale textAllCaps nie :(
Y2i
1
@JawadLeWywadi nie możesz użyć tego atrybutu xml przed API 14. Musisz to zrobić ręcznie w kodzie Java.
Murphy
63

Za pomocą AppCompat textAllCaps w aplikacjach na Androida obsługujących starsze API (mniej niż 14)

Istnieje jeden widżet interfejsu użytkownika dostarczany z AppCompat o nazwie CompatTextView to niestandardowe rozszerzenie TextView, które dodaje obsługę textAllCaps

W przypadku nowszego interfejsu API Androida> 14 możesz użyć:

android:textAllCaps="true"

Prosty przykład:

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

Źródło: developer.android

Aktualizacja:

Tak się składa CompatTextView został zastąpiony przez AppCompatTextView w najnowszej bibliotece appcompat-v7 ~ Eugen Pechanec

LOG_TAG
źródło
Czy zauważyłeś wewnętrzny w android.support.v7.internal? Wewnętrzne jak w może już nie być w następnej wersji biblioteki wsparcia?
Emanuel Moecklin
1
To jest niesamowite! @EmanuelMoecklin Gdy znajdziesz go w swoim projekcie, nie będzie on magicznie przebiegać.
Eugen Pechanec
@eugen oczywiście nigdy nie aktualizujesz biblioteki pomocy technicznej do najnowszej wersji, ponieważ Google nigdy nie dodaje niczego przydatnego, prawda?
Emanuel Moecklin
@EmanuelMoecklin Właściwie często aktualizuję tak szybko, że psuje mój kod: DI całkowicie zgadzam się, że powinieneś uważać na korzystanie z wewnętrznych zasobów, ALE właśnie rzuciłem okiem na źródło appcompat-v7 i CompatTextViewjest ono używane w ScrollingTabCointainerViewktórym jest używane ToolbarWidgetWrapper, co brzmi całkiem nowe i tak długo, jak nazwa utrzymuje „v7” w nazwie, jest to dla mnie wystarczająco dobra gwarancja, że CompatTextViewpozostanie tam, gdzie jest.
Eugen Pechanec
2
@EmanuelMoecklin Tak się składa, że CompatTextViewzostał zastąpiony przez AppCompatTextViewnajnowszą bibliotekę appcompat-v7. Miałeś całkowitą rację.
Eugen Pechanec
30

Bardzo rozczarowujące jest to, że nie można tego zrobić za pomocą styles ( <item name="android:textAllCaps">true</item>) lub każdego pliku układu XML z atrybutem textAllCaps , a jedynym sposobem na to jest użycie metodyString.toUpperCase () na każdym z ciągów znaków, gdy to zrobisz textViewXXX.setText (theString).

W moim przypadku nie chciałem mieć plikuString.toUpperCase () wszędzie w moim kodzie, ale mieć scentralizowane miejsce, aby to zrobić, ponieważ miałem pewne działania i wyświetlałem układy elementów za pomocą TextViews, które zawsze powinny być pisane wielkimi literami (a tytuł) i inni, którzy nie ... więc ... niektórzy mogą myśleć, że to przesada, ale stworzyłem własną klasę CapitalizedTextView rozszerzającą android.widget.TextView i przesłoniłem metodę setText pisanie wielkimi literami na bieżąco.

Przynajmniej jeśli projekt się zmieni lub będę musiał usunąć tekst pisany wielkimi literami w przyszłych wersjach, po prostu muszę przejść do normalnego TextView w plikach układu.

Teraz weź pod uwagę, że to zrobiłem, ponieważ projektant aplikacji tak naprawdę chciał tego tekstu (tytułów) w CAPS w całej aplikacji bez względu na oryginalną wielkość liter, a także miałem inne normalne TextViews, w których wielkie litery pochodziły z rzeczywistej treści .

To jest klasa:

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

}

I ilekroć musisz go użyć, po prostu zadeklaruj go z całym pakietem w układzie XML:

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

Niektórzy twierdzą, że poprawnym sposobem na stylizowanie tekstu w TextView jest użycie SpannableString , ale myślę, że byłaby to jeszcze większa nadwyżka, nie mówiąc już o większym zużyciu zasobów, ponieważ utworzysz instancję innej klasy niż TextView.

Oscar Salguero
źródło
9

Wymyśliłem rozwiązanie podobne do RacZo, ponieważ stworzyłem również podklasę, TextViewktórej uchwyty sprawiają, że tekst jest pisany wielkimi literami.

Różnica polega na tym, że zamiast zastąpić jedną z setText()metod, zastosowałem podobne podejście do tego, co TextViewfaktycznie robi w API 14+ (co jest moim zdaniem czystszym rozwiązaniem).

Jeśli spojrzysz na źródło , zobaczysz implementację setAllCaps():

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

AllCapsTransformationMethodKlasa nie jest (obecnie) publicznego, ale wciąż źródłem jest również dostępna . Uprościłem nieco tę klasę (usunąłem setLengthChangesAllowed()metodę), więc kompletne rozwiązanie jest następujące:

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
źródło
2

Wygląda na to, że na klawiaturze telefonu jest zezwolenie, więc najłatwiej to zrobić:

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

mam nadzieję, że to zadziała

Dhiren Hamal
źródło
1

Projekt PixlUI pozwala na użycie textAllCaps w dowolnym widoku tekstowym lub podklasie widoku tekstowego, w tym: Button, EditText AutoCompleteEditText Checkbox RadioButton i kilka innych.

Będziesz musiał utworzyć swoje widoki tekstowe przy użyciu wersji pixlui zamiast tych ze źródła Android, co oznacza, że ​​musisz to zrobić:

<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 pozwala również ustawić niestandardowy krój / czcionkę, który umieszczasz w folderze zasobów.

Pracuję nad rozwidleniem Gradle frameworku PixlUI, który wykorzystuje gradle i pozwala określić tekstAllCaps, a także krój pisma ze stylów, zamiast wymagać ich wstawiania tak, jak robi to oryginalny projekt.

Matt Wolfe
źródło