Change font of the floating label EditText and TextInputLayout

前端 未结 12 1078
北海茫月
北海茫月 2020-12-03 01:23

Someone tried to change the font of the floating label? I changed the source of EditText but the font of the floating label did not change, I am very grateful to those who h

12条回答
  •  醉酒成梦
    2020-12-03 01:40

    Unfortunately, you'll have to use reflection to handle this.

    The floating label is drawn by CollapsingTextHelper, which is an internal, package-private class and isn't setup to handle spans. So, using something like a custom TypefaceSpan won't work in this case.

    Because this uses reflection, it isn't guaranteed to work in the future.

    Implementation

    final Typeface tf = Typeface.createFromAsset(getAssets(), "your_custom_font.ttf");
    final TextInputLayout til = (TextInputLayout) findViewById(R.id.yourTextInputLayout);
    til.getEditText().setTypeface(tf);
    try {
        // Retrieve the CollapsingTextHelper Field
        final Field cthf = til.getClass().getDeclaredField("mCollapsingTextHelper");
        cthf.setAccessible(true);
    
        // Retrieve an instance of CollapsingTextHelper and its TextPaint
        final Object cth = cthf.get(til);
        final Field tpf = cth.getClass().getDeclaredField("mTextPaint");
        tpf.setAccessible(true);
    
        // Apply your Typeface to the CollapsingTextHelper TextPaint
        ((TextPaint) tpf.get(cth)).setTypeface(tf);
    } catch (Exception ignored) {
        // Nothing to do
    }
    

    Error view

    If you needed to change the font of the error, you could do one of two things:

    1. Use Reflection grab the error TextView and apply the Typeface much like before
    2. Use a custom span. Unlike the floating label, the error view used by TextInputLayout is just a TextView, so it's able to handle spans.

    Using reflection

    final Field errorField = til.getClass().getDeclaredField("mErrorView");
    errorField.setAccessible(true);
    ((TextView) errorField.get(til)).setTypeface(tf);
    

    Using a custom span

    final SpannableString ss = new SpannableString("Error");
    ss.setSpan(new FontSpan(tf), 0, ss.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    til.setError(ss);
    
    private static final class FontSpan extends MetricAffectingSpan {
    
        private final Typeface mNewFont;
    
        private FontSpan(Typeface newFont) {
            mNewFont = newFont;
        }
    
        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setTypeface(mNewFont);
        }
    
        @Override
        public void updateMeasureState(TextPaint paint) {
            paint.setTypeface(mNewFont);
        }
    
    }
    

    Results

    results

    The font I'm using is Smoothie Shoppe.

提交回复
热议问题