ProjectJourneyman
ProjectJourneyman

Reputation: 3606

How to make TextInputLayout hint asterisk red for required fields

Is it possible to make just the asterisk in the hint red when using a TextInputLayout from the design support library? I have seen information on styling the entire hint, but this is a little more complex since only the * should be red, not the whole message.

The Material Design example shows this, but the design library doesn't seem to have any option to style it this way using a TextInputLayout and EditText.

Reference: https://www.google.com/design/spec/components/text-fields.html#text-fields-required-fields

Example (the top, with focus, has the red asterisk; the bottom without focus does not have a red asterisk):

Example of hint text with red asterisk

I looked into setting the hint to a SpannableString (see here How to get a red asterisk in a <string> entry) in an OnFocusChangeListener (see here Having the mandatory symbol to the edit text (red color asterisk) which is inside the textinputlayout), but the hint is a CharSequence.

Is there any way to do this without extending TextInputLayout?

Upvotes: 49

Views: 26345

Answers (10)

Vijay
Vijay

Reputation: 1388

is this what you want?

enter image description here

Do this: Copy this and paste it in any Kotlin file


@Composable
fun MandatoryFieldTextForLabel(
    label: String = "Label", color: Color? = null,
    modifier: Modifier? = Modifier
) {
    Text(
        color = color.takeIf { color != null } ?: MaterialTheme.colorScheme.onSurface,
        modifier = modifier ?: Modifier,
        text = buildAnnotatedString {
            append(label)
            withStyle(style = SpanStyle(color = MaterialTheme.colorScheme.error)) {
                append(" *") // Superscript asterisk
            }
        }
    )
}

Example for you


OutlinedTextField(
                    label = { MandatoryFieldTextForLabel("Fee Amount") },
                    value = viewModel.feeAmount,
                    onValueChange = { viewModel.feeAmount = it }
                )

FYI: I am using Material 3

Upvotes: 1

K M Rejowan Ahmmed
K M Rejowan Ahmmed

Reputation: 1267

Let's set the two text first, one is with asterisk and another without.

 val enterEmailHint = "Enter your email <font color=\"#FF0000\">*</font>"
 val enterEmailNormal = "Enter your email"

Then we need to add focus changed listener to the textInputEditText (not the TextInputLayout). When the editText is in focus, it'll show the asterisk in red color, otherwise no astericks.

binding.emailEditText.setOnFocusChangeListener { v, hasFocus ->
    if (hasFocus) {
        binding.emailTextInputLayout.hint =
            Html.fromHtml(enterEmailHint, Html.FROM_HTML_MODE_LEGACY)
    } else {
        binding.emailTextInputLayout.hint = enterEmailNormal
    }
}

Upvotes: 0

Amitoj
Amitoj

Reputation: 191

This worked for me

textinputlayout.setHint(Html.fromHtml("Project Title <font color =\"#cc0029\" >*</font>"));

Upvotes: 0

Gabriele Mariotti
Gabriele Mariotti

Reputation: 363469

You can use the Material Components Library.
Starting from the 1.2.0-alpha05 you can format the hint text.

For example you can just use something like:

<com.google.android.material.textfield.TextInputLayout
    android:hint="@string/hint_test"
    ...>

with:

<string name="hint_test">Legal name <font color='#FF0000'>*</font></string>

enter image description hereenter image description here

Upvotes: 32

Zon
Zon

Reputation: 19880

Change TextInputLayout hint by adding a postfix wrapped in html:

public void setRequired(boolean required) {

  componentField.setHint(TextUtils.concat(
      componentField.getHint(),
      Html.fromHtml(getContext().getString(
          R.string.required_asterisk))));
}

Asterisk code should be stored in android strings.xml for correct escaping:

<string name = "required_asterisk"><![CDATA[<font color=\'#cc0029\'>&nbsp*</font>]]></string>

Upvotes: 0

Louis CAD
Louis CAD

Reputation: 11529

Material Design specify an asterisk for the required fields that is part of the hint text, and of the same color (not in red like you showed in your question).

In Kotlin this is really simple:

1.Define this extension method:

fun TextInputLayout.markRequired() {
    hint = "$hint *"
}

2.Use it:

input_first_name.markRequired()

If you still want the asterisk red, despite being discouraged by Material Design guidelines, you can use AndroidX Core KTX that way:

fun TextInputLayout.markRequiredInRed() {
    hint = buildSpannedString {
        append(hint)
        color(Color.RED) { append(" *") } // Mind the space prefix.
    }
}

Upvotes: 23

don
don

Reputation: 144

Could you be adding a spanned string From Html?

   String grey = "Legal first name*";
   Spanned redStar;
   String html = "<string style="color:grey;">Legal first name<span style="color:red;">*</span></string>";

   if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
   redStar = Html.fromHtml(html,Html.FROM_HTML_MODE_LEGACY);
   } else {
   redStar = Html.fromHtml(html);
   }

And change the hint upon focus.

   textInput.setOnFocusChangeListener(new View.OnFocusChangeListener() {
   public void onFocusChange(View v, boolean hasFocus) {
    if (hasFocus)
        myEditText.setHint(redStar.toString);
    else
        myEditText.setHint(grey);
}

Upvotes: 3

Zuhad
Zuhad

Reputation: 22

I have been through the same process and it worked for me

 TextView text = (TextView) rootView.findViewById(R.id.name_textview);

 SpannableStringBuilder builder1 = setStarToLabel("Name");

 text.setText(builder1);

  @NonNull
private SpannableStringBuilder setStarToLabel(String text) {
    String simple = text;
    String colored = "*";
    SpannableStringBuilder builder = new SpannableStringBuilder();
    builder.append(simple);
    int start = builder.length();
    builder.append(colored);
    int end = builder.length();
    builder.setSpan(new ForegroundColorSpan(Color.RED), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return builder;
}

Upvotes: -1

Anantha Babu
Anantha Babu

Reputation: 216

Yes Its possible , because i am doing same thing in my current application. and for focus and unfocus you have to do some logic to remove asterisk.

String mm = "Legal first name";
Spannable WordtoSpan = new SpannableString(mm);
WordtoSpan.setSpan(
        new ForegroundColorSpan(Color.parseColor("#e62e6c")), 
        16, 
        mm.length(), 
        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
WordtoSpan.setSpan(new RelativeSizeSpan(0.9f), 16, mm.length(), 0);
view.setText(WordtoSpan);

Upvotes: -1

Dhara Patel
Dhara Patel

Reputation: 359

 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/black</item>
</style>

change you theme colorAccent and see

Upvotes: 2

Related Questions