【问题标题】:Set font for all textViews in activity?为活动中的所有文本视图设置字体?
【发布时间】:2012-06-01 18:17:39
【问题描述】:

是否可以为活动中的所有 TextView 设置字体?我可以使用以下方法为单个 textView 设置字体:

    TextView tv=(TextView)findViewById(R.id.textView1); 
    Typeface face=Typeface.createFromAsset(getAssets(), "font.ttf"); 
    tv.setTypeface(face);

但我想一次更改所有 textView,而不是为每个 textView 手动设置,任何信息都将不胜感激!

【问题讨论】:

    标签: android fonts textview typeface


    【解决方案1】:

    解决方案1:: 只需通过传递父视图作为参数来调用这些方法。

    private void overrideFonts(final Context context, final View v) {
        try {
            if (v instanceof ViewGroup) {
                ViewGroup vg = (ViewGroup) v;
                for (int i = 0; i < vg.getChildCount(); i++) {
                    View child = vg.getChildAt(i);
                    overrideFonts(context, child);
             }
            } else if (v instanceof TextView ) {
                ((TextView) v).setTypeface(Typeface.createFromAsset(context.getAssets(), "font.ttf"));
            }
        } catch (Exception e) {
     }
     }
    

    Solution2:: 您可以使用自定义字体对 TextView 类进行子类化,并使用它来代替 textview。

    public class MyTextView extends TextView {
    
        public MyTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
    
        public MyTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public MyTextView(Context context) {
            super(context);
            init();
        }
    
        private void init() {
            if (!isInEditMode()) {
                Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "font.ttf");
                setTypeface(tf);
            }
        }
    
    }
    

    【讨论】:

    • 事实上,这两种解决方案都有效。但是第一个实在是太重了,每次在一个Layout上加TextView,都要回想一下方法……第二个最好,但它暗示了项目的整体重构(注意如果项目不大,可能需要几分钟...
    • @ChristopheCVB 完全是,但我有两个解决方案,他决定他想做什么,第二个是最好的解决方案
    • 是的,当然,我真的同意你的看法。感谢您提供这些解决方案!
    • 对方法 1 的改进是创建一次字体 (Typeface.createFromAsset) 并将其保存为类中的字段,而不是为每个 TextView 创建它。
    • 在性能和所有方面使用这个库mycode.restservices.org/2013/10/01/…好吗?
    【解决方案2】:

    我个人收藏的那个:

    private void setFontForContainer(ViewGroup contentLayout) {
        for (int i=0; i < contentLayout.getChildCount(); i++) {
            View view = contentLayout.getChildAt(i);
            if (view instanceof TextView)
                ((TextView)view).setTypeface(yourFont);
            else if (view instanceof ViewGroup)
                setFontForContainer((ViewGroup) view);
        }
    }
    

    【讨论】:

      【解决方案3】:

      如果您正在寻找更通用的编程解决方案,我创建了一个静态类,可用于设置整个视图(活动 UI)的字体。请注意,我正在使用 Mono (C#),但您可以使用 Java 轻松实现它。

      您可以将要自定义的布局或特定视图传递给此类。如果你想变得超级高效,你可以使用 Singleton 模式来实现它。

      public static class AndroidTypefaceUtility 
      {
          static AndroidTypefaceUtility()
          {
          }
          //Refer to the code block beneath this one, to see how to create a typeface.
          public static void SetTypefaceOfView(View view, Typeface customTypeface)
          {
          if (customTypeface != null && view != null)
          {
                  try
                  {
                      if (view is TextView)
                          (view as TextView).Typeface = customTypeface;
                      else if (view is Button)
                          (view as Button).Typeface = customTypeface;
                      else if (view is EditText)
                          (view as EditText).Typeface = customTypeface;
                      else if (view is ViewGroup)
                          SetTypefaceOfViewGroup((view as ViewGroup), customTypeface);
                      else
                          Console.Error.WriteLine("AndroidTypefaceUtility: {0} is type of {1} and does not have a typeface property", view.Id, typeof(View));
                      }
                      catch (Exception ex)
                      {
                          Console.Error.WriteLine("AndroidTypefaceUtility threw:\n{0}\n{1}", ex.GetType(), ex.StackTrace);
                          throw ex;
                      }
                  }
                  else
                  {
                      Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / view parameter should not be null");
                  }
              }
      
              public static void SetTypefaceOfViewGroup(ViewGroup layout, Typeface customTypeface)
              {
                  if (customTypeface != null && layout != null)
                  {
                      for (int i = 0; i < layout.ChildCount; i++)
                      {
                          SetTypefaceOfView(layout.GetChildAt(i), customTypeface);
                      }
                  }
                  else
                  {
                      Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / layout parameter should not be null");
                  }
              }
      
          }
      

      在您的活动中,您需要创建一个字体对象。我使用放置在我的 Resources/Assets/ 目录中的 .ttf 文件在 OnCreate() 中创建我的。确保该文件在其属性中标记为 Android 资源。

      protected override void OnCreate(Bundle bundle)
      {               
          ...
          LinearLayout rootLayout = (LinearLayout)FindViewById<LinearLayout>(Resource.Id.signInView_LinearLayout);
          Typeface allerTypeface = Typeface.CreateFromAsset(base.Assets,"Aller_Rg.ttf");
          AndroidTypefaceUtility.SetTypefaceOfViewGroup(rootLayout, allerTypeface);
      }
      

      【讨论】:

      • 在 Xamarin 中对我来说就像一个魅力,谢谢!
      • 附注EditText 和 Button 都扩展了 TextView,所以你不需要明确地检查它们
      • 这是否适用于尚未创建的视图?
      【解决方案4】:

      扩展 Agarwal 的答案...您可以通过切换 TextView 的样式来设置常规、粗体、斜体等。

      import android.content.Context;
      import android.graphics.Typeface;
      import android.util.AttributeSet;
      import android.widget.TextView;
      
      public class TextViewAsap extends TextView {
      
          public TextViewAsap(Context context, AttributeSet attrs, int defStyle) {
              super(context, attrs, defStyle);
              init();
          }
      
          public TextViewAsap(Context context, AttributeSet attrs) {
              super(context, attrs);
              init();
          }
      
          public TextViewAsap(Context context) {
              super(context);
              init();
          }
      
          private void init() {
              if (!isInEditMode()) {
                  Typeface tf = Typeface.DEFAULT;
      
                  switch (getTypeface().getStyle()) {
                      case Typeface.BOLD:
                          tf = Typeface.createFromAsset(getContext().getAssets(), "Fonts/Asap-Bold.ttf");
                          break;
      
                      case Typeface.ITALIC:
                          tf = Typeface.createFromAsset(getContext().getAssets(), "Fonts/Asap-Italic.ttf");
                          break;
      
                      case Typeface.BOLD_ITALIC:
                          tf = Typeface.createFromAsset(getContext().getAssets(), "Fonts/Asap-Italic.ttf");
                          break;
      
                      default:
                          tf = Typeface.createFromAsset(getContext().getAssets(), "Fonts/Asap-Regular.ttf");
                          break;
                  }
      
                  setTypeface(tf);
              }
          }
      
      }
      

      您可以像这样创建资产文件夹:

      您的 Assets 文件夹应如下所示:

      最后,您在 xml 中的 TextView 应该是 TextViewAsap 类型的视图。现在它可以使用您编码的任何样式...

      <com.example.project.TextViewAsap
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:text="Example Text"
                      android:textStyle="bold"/>
      

      【讨论】:

        【解决方案5】:

        最佳答案

        1.为一个 textView 设置自定义字体

        Typeface typeface = Typeface.createFromAsset(getContext().getAssets(), "Fonts/FontName.ttf");
        textView.setTypeface (typeface);
        

        2。为所有 textViews 设置自定义字体

        创建一个如下所示的 JavaClass

        public class CustomFont extends android.support.v7.widget.AppCompatTextView {
        
            public CustomFont(Context context) {
                super(context);
                init();
            }
        
            public CustomFont(Context context, AttributeSet attrs) {
                super(context, attrs);
                init();
            }
        
            public CustomFont(Context context, AttributeSet attrs, int defStyleAttr) {
                super(context, attrs, defStyleAttr);
                init();
            }
        
            private void init() {
                    Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/FontName.ttf");
                    setTypeface(tf);
            }
        }
        

        在你的 xml 页面中

        <packageName.javaClassName>
        
        ...
        
        />
        

        =>

            <com.mahdi.hossaini.app1.CustomFont
            android:id="@+id/TextView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:text="KEEP IT SIMPLE"
            android:textAlignment="center" />
        

        【讨论】:

          【解决方案6】:

          您可以使用此处提供的Calligraphy 库:
          Android Calligraphy Library

          【讨论】:

            【解决方案7】:

            使用反射的更“通用”方式的示例:

            ** 它提出了一个涉及视图组子方法 setTextSize(int,float) 的想法,但您可以像您对 setTypeFace() 的问题一样采用它

             /**
             * change text size of view group children for given class
             * @param v - view group ( for example Layout/widget)
             * @param clazz  - class to override ( for example EditText, TextView )
             * @param newSize - new font size
             */
            public static void overrideTextSize(final View v, Class<?> clazz, float newSize) {
                try {
                    if (v instanceof ViewGroup) {
                        ViewGroup vg = (ViewGroup) v;
                        for (int i = 0; i < vg.getChildCount(); i++) {
                            View child = vg.getChildAt(i);
                            overrideTextSize(child, clazz, newSize);
                        }
                    } else if (clazz.isAssignableFrom(v.getClass())) {
                        /** create array for params */
                        Class<?>[] paramTypes = new Class[2];
                        /** set param array */
                        paramTypes[0] = int.class;  // unit
                        paramTypes[1] = float.class; // size
                        /** get method for given name and parameters list */
                        Method method = v.getClass().getMethod("setTextSize",paramTypes);
                        /** create array for arguments */
                        Object arglist[] = new Object[2];
                        /** set arguments array */
                        arglist[0] = TypedValue.COMPLEX_UNIT_SP;
                        arglist[1] = newSize;
                        /** invoke method with arguments */
                        method.invoke(v,arglist);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            

            注意:

            使用反射应该非常小心。反射类非常“exceptional

            • 例如,您应该检查是否存在注释以防止出现不同类型的问题。在方法SetTextSize()的情况下最好检查注解android.view.RemotableViewMethod

            【讨论】:

              【解决方案8】:

              您可以使用样式继承。

              让活动中的每个 TextView 都通过 android:textAppearence 声明样式,而不是手动 android:typeface

              然后,让每个人的风格继承活动风格,像这样:

              <TextView ...
                    android:textAppearance="@style/item_name"/>
              <TextView ...
                    android:textAppearance="@style/item_details"/>
              

              在 style.xml 中:

              <style name="ActivityStyle">
                  <item name="android:fontFamily">@font/font</item>
              </style>
              <style name="item_name" parent="ActivityStyle">
                  <item name="android:textStyle">bold</item>
                  <item name="android:textSize">20sp</item>
              </style>
              <style name="item_details" parent="ActivityStyle">
                  <item name="android:textSize">15sp</item>
              </style>
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-06-25
                • 1970-01-01
                • 1970-01-01
                • 2014-06-12
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多