270

I would like to be able to assign a xml attribute or style to a TextView that will make whatever text it has in ALL CAPITAL LETTERS.

The attributes android:inputType="textCapCharacters" and android:capitalize="characters" do nothing and look like they are for user inputed text, not a TextView.

I would like to do this so I can separate the style from the content. I know I could do this programmically but again I want keep style out of the content and the code.

LOG_TAG
  • 19,894
  • 12
  • 72
  • 105
cottonBallPaws
  • 21,220
  • 37
  • 123
  • 171
  • 1
    neither inputType="textCapCharacters", textAllCaps="true" works in smasung famili^^. I've added TextWatcher to my EditText that Caps all words – murt Aug 11 '17 at 07:28

8 Answers8

397

I though that was a pretty reasonable request but it looks like you cant do it at this time. What a Total Failure. lol

Update

You can now use textAllCaps to force all caps.

Community
  • 1
  • 1
Terrance
  • 11,764
  • 4
  • 54
  • 80
154

What about android:textAllCaps?

Pratik Butani
  • 60,504
  • 58
  • 273
  • 437
Murphy
  • 4,858
  • 2
  • 24
  • 31
  • 8
    @larham1 It is a xml attribute so I don't see how else it can be used. If not working report it to Google. I suppose it's limited to API level 14 like setAllCaps(boolean). – Murphy May 01 '12 at 00:08
  • 1
    I have just tested this and it is working. I have an external style file – 7heViking Jul 23 '12 at 11:31
  • 1
    @Murphy yes, this is a versioning issue. SDK 14 and above for setAllCaps(); not clear when the xml was added, but I assume SDK 14 also. – larham1 Jul 30 '12 at 21:19
  • This is strange, textAllCaps works in a simple test project, but when the view is created inside ArrayAdapter.getView(), it does not. Everything works: background, textStyle, etc., but textAllCaps does not :( – Y2i Mar 09 '13 at 03:06
  • Hi how can we use it for API 11. Thanks –  Sep 12 '15 at 21:03
  • 1
    @JawadLeWywadi you can't use this xml attribute before API 14. You need to do it manually in Java code. – Murphy Sep 14 '15 at 23:42
72

By using AppCompat textAllCaps in Android Apps supporting older API's (less than 14)

There is one UI widgets that ships with AppCompat named CompatTextView is a Custom TextView extension that adds support for textAllCaps

For newer android API > 14 you can use :

android:textAllCaps="true"

A simple example:

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

Source:developer.android

Update:

As it so happens CompatTextView was replaced by AppCompatTextView in latest appcompat-v7 library ~ Eugen Pechanec

DolDurma
  • 15,753
  • 51
  • 198
  • 377
LOG_TAG
  • 19,894
  • 12
  • 72
  • 105
  • Did you notice the internal in android.support.v7.internal? Internal as in might not be there any more in the next version of the support library? – Emanuel Moecklin Mar 26 '14 at 15:57
  • 1
    This is awesome! @EmanuelMoecklin Once you have it in your project it's not going to magically run a way. – Eugen Pechanec Feb 26 '15 at 01:00
  • @eugen of course you never update the support library to the latest version since Google never adds anything useful, right? – Emanuel Moecklin Feb 26 '15 at 21:32
  • @EmanuelMoecklin Actually I often update so quickly it breaks my code :D I totally agree that you should be wary of using internal resources *BUT* I just took a glance at appcompat-v7 source and `CompatTextView` is used in `ScrollingTabCointainerView` which is used in `ToolbarWidgetWrapper`, which sounds pretty new and as long the name keeps "v7" in its name, this is a good enough guarantee for me the `CompatTextView` is going to stay where it is. – Eugen Pechanec Feb 26 '15 at 21:46
  • BTW if you take [`Button`'s source code](http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.2_r1/android/widget/Button.java#Button) copy it as a new class but extend `CompatTextView` instead of `TextView` you can add `textAllCaps` support to buttons. Apparently a button is just a glorified text view with different styling and some accesibility stuff slapped onto it. – Eugen Pechanec Feb 26 '15 at 21:49
  • 2
    @EmanuelMoecklin As it so happens `CompatTextView` was replaced by `AppCompatTextView` in latest appcompat-v7 library. You were quite correct. – Eugen Pechanec Apr 29 '15 at 01:46
31

It is really very disappointing that you can't do it with styles (<item name="android:textAllCaps">true</item>) or on each XML layout file with the textAllCaps attribute, and the only way to do it is actually using theString.toUpperCase() on each of the strings when you do a textViewXXX.setText(theString).

In my case, I did not wanted to have theString.toUpperCase() everywhere in my code but to have a centralized place to do it because I had some Activities and lists items layouts with TextViews that where supposed to be capitalized all the time (a title) and other who did not... so... some people may think is an overkill, but I created my own CapitalizedTextView class extending android.widget.TextView and overrode the setText method capitalizing the text on the fly.

At least, if the design changes or I need to remove the capitalized text in future versions, I just need to change to normal TextView in the layout files.

Now, take in consideration that I did this because the App's Designer actually wanted this text (the titles) in CAPS all over the App no matter the original content capitalization, and also I had other normal TextViews where the capitalization came with the the actual content.

This is the class:

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

}

And whenever you need to use it, just declare it with all the package in the XML layout:

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

Some will argue that the correct way to style text on a TextView is to use a SpannableString, but I think that would be even a greater overkill, not to mention more resource-consuming because you'll be instantiating another class than TextView.

Oscar Salguero
  • 10,275
  • 5
  • 49
  • 48
9

I've come up with a solution which is similar with RacZo's in the fact that I've also created a subclass of TextView which handles making the text upper-case.

The difference is that instead of overriding one of the setText() methods, I've used a similar approach to what the TextView actually does on API 14+ (which is in my point of view a cleaner solution).

If you look into the source, you'll see the implementation of setAllCaps():

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

The AllCapsTransformationMethod class is not (currently) public, but still, the source is also available. I've simplified that class a bit (removed the setLengthChangesAllowed() method), so the complete solution is this:

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
  • 14,017
  • 7
  • 54
  • 69
8

Basically, write this in TextView of XML file:

android:textAllCaps="true"
canerkaseler
  • 6,204
  • 45
  • 38
2

It seems like there is permission on mobile keypad setting, so the easiest way to do this is:

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

hope this will work

Dhiren Hamal
  • 874
  • 1
  • 12
  • 31
1

PixlUI project allows you to use textAllCaps in any textview or subclass of textview including: Button, EditText AutoCompleteEditText Checkbox RadioButton and several others.

You will need to create your textviews using the pixlui version rather than the ones from the android source, meaning you have to do this:

<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 also allows you to set a custom typeface/font which you put in your assets folder.

I'm working on a Gradle fork of the PixlUI framework which uses gradle and allows one to specify textAllCaps as well as the typeface from styles rather than requiring them inline as the original project does.

Matt Wolfe
  • 8,924
  • 8
  • 60
  • 77