2016-10-23 21 views
1

目前,我想對我的浮動文本InputTextLayout有一個大膽的影響。這是我在做什麼是否可以爲浮動文本提示不同的字體並提示InputTextLayout文本

this.usernameTextInputLayout.setTypeface(Utils.ROBOTO_BOLD_TYPE_FACE); 

它按預期工作。浮動文本(用戶名)變成了粗體。

enter image description here

然而,這會爲我創造另一個不良影響。提示文字也將變得粗體。

enter image description here

您可以比較上述2個圖像。請注意,爲了比較目的,我只保留passwordTextInputLayout原樣。

是否可以有不同的字體,用於浮動文本和提示文本InputTextLayout

+0

是的,這是可能的,但我很確定這將需要反思去做。我最近寫了一些自定義的'TextInputLayout'子類,而且,從我的頭頂開始,我想不出沒有反思的方法。如果這是可以接受的,我可以把東西放在一起。 –

+0

我曾嘗試反射技術http://stackoverflow.com/a/30767869/72437它也會影響提示文本。 –

+0

嗯,我相信它可以做到。給我一點點做一些測試。我會讓你知道的。 –

回答

3

如您所知,TextInputLayout使用私有助手類來處理提示文本樣式和動畫。此類 - CollapsingTextHelper - 爲其摺疊展開狀態維護單獨的字體。我們只需要設置正確的,我們將使用反射。

我通常將這些類型的功能包裝到自定義子類中,所以我會在這裏做同樣的事情。如果你不想使用子類,反射的東西可以很容易地拉入一些簡單的方法,你可以把它放在你的Activity或工具類。

public class CustomTextInputLayout extends TextInputLayout { 

    private Object collapsingTextHelper; 
    private Method setCollapsedTypefaceMethod; 
    private Method setExpandedTypefaceMethod; 

    public CustomTextInputLayout(Context context) { 
     this(context, null); 
    } 

    public CustomTextInputLayout(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public CustomTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 

     init(); 
    } 

    private void init() { 
     try { 
      Field cthField = TextInputLayout.class 
       .getDeclaredField("mCollapsingTextHelper"); 
      cthField.setAccessible(true); 
      collapsingTextHelper = cthField.get(this); 

      setCollapsedTypefaceMethod = collapsingTextHelper 
       .getClass().getDeclaredMethod("setCollapsedTypeface", Typeface.class); 
      setCollapsedTypefaceMethod.setAccessible(true); 

      setExpandedTypefaceMethod = collapsingTextHelper 
       .getClass().getDeclaredMethod("setExpandedTypeface", Typeface.class); 
      setExpandedTypefaceMethod.setAccessible(true); 
     } 
     catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException e) { 
      collapsingTextHelper = null; 
      setCollapsedTypefaceMethod = null; 
      setExpandedTypefaceMethod = null; 
      e.printStackTrace(); 
     } 
    } 

    public void setCollapsedTypeface(Typeface typeface) { 
     if (collapsingTextHelper == null) { 
      return; 
     } 

     try { 
      setCollapsedTypefaceMethod.invoke(collapsingTextHelper, typeface); 
     } 
     catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void setExpandedTypeface(Typeface typeface) { 
     if (collapsingTextHelper == null) { 
      return; 
     } 

     try { 
      setExpandedTypefaceMethod.invoke(collapsingTextHelper, typeface); 
     } 
     catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

有點直覺相反,TextInputLayout摺疊狀態是當所述提示是EditText上方的浮動標籤。它的擴展狀態是當提示是在「正常」的位置,內EditText。上面給出了設置兩種狀態字體的方法。

這是對TextInputLayout的直接替換,您可以像使用它那樣在佈局中使用它。例如:

<com.mycompany.myapp.CustomTextInputLayout 
    android:id="@+id/username_til" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    app:hintTextAppearance="@style/TextLabel"> 

    <android.support.design.widget.TextInputEditText 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:textSize="24sp" 
     android:hint="Username" /> 

</com.mycompany.myapp.CustomTextInputLayout> 

在代碼中,設置浮動文本提示的字體:

CustomTextInputLayout usernameTextInputLayout = 
    (CustomTextInputLayout) findViewById(R.id.username_til); 

usernameTextInputLayout.setCollapsedTypeface(Utils.ROBOTO_BOLD_TYPE_FACE); 

上面使用的CollapsingTextHelper方法在支持的23.1.0版本中加入圖書館。如果您使用的是以前的版本,或者出於某種其他原因而獲得NoSuchMethodException,則無論版本如何,直接設置字體字段的the original version of my answer都應該可以工作。

+0

感謝您的代碼。我意識到提示文本不符合'EditText'中的字體。但是,通過在mExpandedTypeface上使用反射,我可以更改提示文本的字體。 –

+1

哦,不是嗎?我將不得不再次看看源代碼。我可能已經在我的主題中設置了相同的內容,並且我只是假定從另一個設置了一個。謝謝(你的)信息!我會在重新檢查代碼後再更正答案,以確定發生了什麼。真高興你做到了。乾杯! –

+0

我只是對最新的源代碼進行了挖掘,並且提示字體似乎仍然從「EditText」中設置,但風格僅限於「NORMAL」。不過,我意識到,在通貨膨脹之後,您可能會在運行時設置EditText的字體,在這種情況下,您是對的; 'TextInputLayout'不會改變它的字體。它只在首次將「EditText」添加到它時初始化它自己。之後,它將不會對您在「EditText」上所做的更改作出反應。這與提示字符串,顏色等相同。 –