更改editText提示文本的字体

30

能否更改EditText字段中显示的提示字体? 我希望在xml文件中设置字体。


6
可能是重复问题:https://dev59.com/t2445IYBdhLWcg3wustT您可以尝试以下代码来设置EditText中提示文本的字体样式:Typeface typeface = Typeface.createFromAsset(getAssets(), "font.ttf"); EditText editText = findViewById(R.id.editText); editText.setTypeface(typeface); // 设置EditText中文本的字体样式 editText.setHint("请输入内容"); // 设置EditText中提示文本的内容 editText.setHintTextColor(Color.GRAY); // 设置EditText中提示文本的颜色请注意,您需要将“font.ttf”替换为您自己的字体文件名,并将其放入“assets”文件夹中。 - thepoosh
正如指出的那样,这是一个重复的问题。你可以改变提示颜色,但不能改变字体。 - jsmith
希望这个能行。你可以在这里检查我的答案:https://dev59.com/t2445IYBdhLWcg3wustT#40695930 - Dmila Ram
10个回答

27
你可以通过使用SpannableString和自定义TypefaceSpan来更改它。
首先,创建一个自定义TypefaceSpan类:
public class CustomTypefaceSpan extends TypefaceSpan {
    private final Typeface mNewType;

    public CustomTypefaceSpan(Typeface type) {
        super("");
        mNewType = type;
    }

    public CustomTypefaceSpan(String family, Typeface type) {
        super(family);
        mNewType = type;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        applyCustomTypeFace(ds, mNewType);
    }

    @Override
    public void updateMeasureState(TextPaint paint) {
        applyCustomTypeFace(paint, mNewType);
    }

    private static void applyCustomTypeFace(Paint paint, Typeface tf) {
        int oldStyle;
        Typeface old = paint.getTypeface();
        if (old == null) {
            oldStyle = 0;
        } else {
            oldStyle = old.getStyle();
        }

        int fake = oldStyle & ~tf.getStyle();
        if ((fake & Typeface.BOLD) != 0) {
            paint.setFakeBoldText(true);
        }

        if ((fake & Typeface.ITALIC) != 0) {
            paint.setTextSkewX(-0.25f);
        }

        paint.setTypeface(tf);
    }
}

然后将TypefaceSpan设置为SpannableString:

TypefaceSpan typefaceSpan = new CustomTypefaceSpan(typeface);
SpannableString spannableString = new SpannableString(hintText);

spannableString.setSpan(typefaceSpan, 0, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

最后,只需设置您的EditText的提示:

mEditText.setHint(spannableString);

1
这对我来说是正确的答案,谢谢@francisco_ssb。它完美地运行。 - Menion Asamm
1
很棒的Span使用!在我的情况下,我不需要真正的“自定义字体”,只需要一个与常规文本不同的系统字体和外观。我在提示上使用了TextAppearanceSpan,它像魔法一样奏效。 - Lisa Wray
但是,这种方法不能使当前提示浮动到上面的字段。有什么建议可以让它浮动到上面的字段吗? @LisaWray - mochadwi
@mochadwi,你所想的“浮动”可能是TextInputLayout的效果,它是EditText的Material设计包装器。我现在正在使用移动设备,但只需谷歌一下即可 :) - Lisa Wray
我明白了,所以用这段代码,再加上 TextInputLayout 的提示,应该就可以解决问题了吧? *如有错误请指正 - mochadwi

7

我还没有找到任何有用的方法来在XML中更改提示字体。但是你可以像这样实现:

mEt.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(s.length()== 0) {
            //mEt.setTypeFace(normalFont);
        }else{
           // mEt.setTypeFace(hintFont);
        }
    }

    @Override
    public void afterTextChanged(Editable s) {
    }
});

1
简单的解决方案,就应该是这样的。 - Drake
@Darius 哈哈,实际上看起来没有更好的选择... - Renetik

5

有一种非常简单的方法来解决这个问题。我在我的应用程序中刚刚尝试了一下,它起作用了。 关键是设置TextInputLayout的Facetype,同时也要设置EditText的Facetype。

mEmailView.setTypeface(Typeface.createFromAsset(getAssets(), getString(R.string.app_font)));
((TextInputLayout) findViewById(R.id.tilEmail)).setTypeface(Typeface.createFromAsset(getAssets(), getString(R.string.app_font)));

3
@francisco_ssb的回答是正确的。但我将提供一种替代方案,它不仅可以更改提示字体,还可以更改其大小和样式。希望这个解决方案有所帮助。 1)创建自定义的 Hint 对象:
import android.graphics.Typeface;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.MetricAffectingSpan;

public class CustomHint extends SpannableString
{
    public CustomHint(final CharSequence source, final int style)
    {
        this(null, source, style, null);
    }

    public CustomHint(final CharSequence source, final Float size)
    {
        this(null, source, size);
    }

    public CustomHint(final CharSequence source, final int style, final Float size)
    {
        this(null, source, style, size);
    }

    public CustomHint(final Typeface typeface, final CharSequence source, final int style)
    {
        this(typeface, source, style, null);
    }

    public CustomHint(final Typeface typeface, final CharSequence source, final Float size)
    {
        this(typeface, source, null, size);
    }

    public CustomHint(final Typeface typeface, final CharSequence source, final Integer style, final Float size)
    {
        super(source);

        MetricAffectingSpan typefaceSpan = new CustomMetricAffectingSpan(typeface, style, size);
        setSpan(typefaceSpan, 0, source.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    }
}

2) 创建自定义的MetricAffectingSpan对象:

import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;

public class CustomMetricAffectingSpan extends MetricAffectingSpan
{
    private final Typeface _typeface;
    private final Float    _newSize;
    private final Integer  _newStyle;

    public CustomMetricAffectingSpan(Float size)
    {
        this(null, null, size);
    }

    public CustomMetricAffectingSpan(Float size, Integer style)
    {
        this(null, style, size);
    }

    public CustomMetricAffectingSpan(Typeface type, Integer style, Float size)
    {
        this._typeface = type;
        this._newStyle = style;
        this._newSize = size;
    }

    @Override
    public void updateDrawState(TextPaint ds)
    {
        applyNewSize(ds);
    }

    @Override
    public void updateMeasureState(TextPaint paint)
    {
        applyNewSize(paint);
    }

    private void applyNewSize(TextPaint paint)
    {
        if (this._newStyle != null)
            paint.setTypeface(Typeface.create(this._typeface, this._newStyle));
        else
            paint.setTypeface(this._typeface);

        if (this._newSize != null)
            paint.setTextSize(this._newSize);
    }
}

3) 使用:

Typeface newTypeface = Typeface.createFromAsset(getAssets(), "AguafinaScript-Regular.ttf");
CustomHint customHint = new CustomHint(newTypeface, "Enter some text", Typeface.BOLD_ITALIC, 60f);
        //        CustomHint customHint = new CustomHint(newTypeface, "Enter some text", Typeface.BOLD_ITALIC);
        //        CustomHint customHint = new CustomHint(newTypeface, "Enter some text", 60f);
        //        CustomHint customHint = new CustomHint("Enter some text", Typeface.BOLD_ITALIC, 60f);
        //        CustomHint customHint = new CustomHint("Enter some text", Typeface.BOLD_ITALIC);
        //        CustomHint customHint = new CustomHint("Enter some text", 60f);

customEditText.setHint(customHint);

2

我可以使用这个来更改提示字体。

编译库后,您必须创建一个应用程序类,并按照以下命令定义类:

CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
                  .setDefaultFontPath("font.ttf")
                  .setFontAttrId(R.attr.fontPath)
                  .build()
          );

在每个活动完成后,您需要使用以下命令覆盖它:
@Override
      protected void attachBaseContext(Context newBase) {
          super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
      }

1
编译库后,您必须创建一个应用程序类并按照以下命令定义类: CalligraphyConfig.initDefault(new CalligraphyConfig.Builder() .setDefaultFontPath("font.ttf") .setFontAttrId(R.attr.fontPath) .build() ); 在每个活动之后,您想要使用以下命令覆盖它:@Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase)); } - HOSHYAR Ahmadpour
@johnny5,这个答案对我很有帮助,因为我正在使用这个答案所提到的书法库。HOSHYAR Ahmadpour也解释了这个答案。谢谢你的答案,HOSHYAR Ahmadpour。 - Sakiboy
2
@Sakiboy 嗯,很好,我在审核队列中确保未来的人们能够使用这个答案,在他修正了答案后,我给他点了赞。 - johnny 5

2

在XML中不可能做到-

在XML中,文本和提示只能使用相同的字体。


1
采用文本输入布局的方法,并将文本输入编辑框放置在其中。
 <com.google.android.material.textfield.TextInputLayout
    android:id="@+id/text_input_layout_Til">

   <com.google.android.material.textfield.TextInputEditText
      android:id="@+id/editText"/>

 </com.google.android.material.textfield.TextInputLayout>

在Fragment/Activity中,将您想要用于TextInputLayout(text_input_layout_Til)的提示字体设置好。然后也在EditText(editText)上设置字体。 如果您这样做,用户输入的文本和提示将有不同的字体。

0

随着Android 8.0(API级别26)的推出,新增了一个功能,可以在EditText中更改XML中显示的提示字体。根据XML中的字体指南。

步骤:

1) 创建一个新的资源目录:右键单击res文件夹,然后转到新建-> Android资源目录

2) 将资源目录的名称设置为font

3)资源类型列表中,选择font,然后单击“确定”。

4)font文件夹中添加自定义字体(例如my_font.ttf)。

5) 在布局XML中,将fontFamily属性设置为字体文件:

<EditText
    android:id="@+id/edit_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/my_font"/>

...或者如果你想以编程的方式实现:

val typeface = resources.getFont(R.font.my_font)
edit_text.typeface = typeface

要在运行Android 4.1(API级别16)及更高版本的设备上使用XML中的字体功能,请使用Support Library 26:

注意:当您通过支持库在XML布局中声明字体系列时,请使用app命名空间以确保您的字体加载。

1)font目录中创建custom_font.xml

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
    <font app:fontStyle="normal" app:fontWeight="400" app:font="@font/my_font"/>
</font-family>

2) 设置 fontFamily 属性:

 <EditText
    android:id="@+id/edit_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/custom_font"/>

......或者如果你想以编程方式完成:

val typeface = ResourcesCompat.getFont(context, R.font.custom_font)
edit_text.typeface = typeface

0
在 Kotlin 中:
            nomeEditText.setText("New Text") //changes the text
            nomeEditText.isEnabled = false //disables editable
            nomeEditText.setBackgroundColor(Color.parseColor("#ffffff")) //changes background
            nomeEditText.setTextColor(Color.parseColor("#737373")) //changes color text
            nomeEditText.setTextSize(TypedValue.COMPLEX_UNIT_SP,28f) //changes text size
            nomeEditText.typeface = Typeface.create("@font/roboto", Typeface.BOLD) //changes font familly
            nomeEditText.gravity = Gravity.CENTER_HORIZONTAL //centralize

-3
请使用以下代码:
edittext.setAccentTypeface(typeface);

此功能不适用于EditText。 - android developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接