如何在XML布局中设置TextView的字体?

3

我创建了一个名为def_list的XML布局。我已经为它分配了一个ID,即def_list_textview。我在资产文件夹中放置了一个名为bn.ttf的字体。

XML布局如下:

<?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/def_list_textview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="right" >
    </TextView>

但是当我使用以下代码设置字体时:
def_list_tv = (TextView)findViewById(R.id.def_list_textview);
Typeface tf = Typeface.createFromAsset(this.getAssets(), "fonts/bn.ttf");
def_list_tv.setTypeface(tf);

我在LogCat中得到了一个NullPointerException。我不知道原因。

这是我的LogCat:

12-26 17:14:56.496: E/AndroidRuntime(1254): FATAL EXCEPTION: main
12-26 17:14:56.496: E/AndroidRuntime(1254): java.lang.RuntimeException: Unable to start activity ComponentInfo{net.adeveloper.handydic/net.adeveloper.dic.PortDef}: java.lang.NullPointerException
12-26 17:14:56.496: E/AndroidRuntime(1254):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at android.os.Looper.loop(Looper.java:123)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at android.app.ActivityThread.main(ActivityThread.java:3683)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at java.lang.reflect.Method.invokeNative(Native Method)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at java.lang.reflect.Method.invoke(Method.java:507)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at dalvik.system.NativeStart.main(Native Method)
12-26 17:14:56.496: E/AndroidRuntime(1254): Caused by: java.lang.NullPointerException
12-26 17:14:56.496: E/AndroidRuntime(1254):     at net.adeveloper.dic.PortDef.onCreate(PortDef.java:53)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at     android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-26 17:14:56.496: E/AndroidRuntime(1254):     at     android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
12-26 17:14:56.496: E/AndroidRuntime(1254):     ... 11 more

请发布您的 LogCat。 - Rehan
你在哪里遇到了NPE?请发布你的stackTrace。同时,请发布你的代码,并告诉我们在哪一行出现了NPE?请发布第53行。 - Piyush
告诉我portdef类中的第53行是哪一行。 - Kailash Dabhi
在添加这些代码之前,我的应用程序运行良好。我注释了前两行,它就可以工作了。但是当我添加第三行代码:def_list_tv.setTypeface(tf); 时,它出现了错误。 - Ali Allahyar
第53行是我发布的代码的第三行:def_list_tv.setTypeface(tf); - Ali Allahyar
9个回答

3
可能出现问题的地方在于:
this.getAssets()

getAssets()是Context(上下文)中的一个方法,因此请尝试传递上下文对象而不是this

尝试:

Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/bn.ttf");

或者
Typeface tf = Typeface.createFromAsset(mContext.getAssets(), "fonts/bn.ttf");

这里的mContext是Context对象。
编辑:
请检查以下自定义TextView是否对您有帮助。
public class CustomTextView extends TextView{
  public CustomTextView(Context context,AttributeSet attrs,int defStyle){
    super(context,attrs,defStyle);
    init();
  }
  public CustomTextView(Context context,AttributeSet attrs){
    super(context,attrs);
    init();
  }
  public CustomTextView(Context context){
    super(context);
    init();
  }

  private void init(){
    if(!isInEditMode()){
        Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/bn.ttf");
        setTypeface(tf);
    }
  }
}

我曾在之前的项目中使用过这个类。

我有另一个类似的代码用于另一个在不同XML文件中的文本视图,并通过设置字体类型可以正常工作。但是对于这个整个XML布局作为文本视图,它就是不起作用。你难道不认为我无法在我的代码中访问XML Text-View id吗? - Ali Allahyar

0
尝试创建一个类似下面的CustomTextView:
public class CustomTextView extends TextView {

public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
}

public CustomTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public CustomTextView(Context context) {
    super(context);
    init();
}

private void init() {
    if (!isInEditMode()) {
        Typeface typeFace = Typeface.createFromAsset(getContext().getAssets(), "fonts/arial.ttf");
        setTypeface(typeFace,Typeface.NORMAL);
    }
}

}

请将您的字体文件放置于 assets/fonts/arial.ttf 文件夹中,并确保字体名称与 CustomTextView.java 文件相同。若需从 XML 中调用 CustomTextView,请使用以下代码:
<com.package.name.CustomTextView
//fill in the details
/>

谢谢


0
def_list_tv = (TextView)findViewById(R.id.def_list_textview);   //line no 1
System.out.println("Textview==="+def_list_tv);
Typeface tf = Typeface.createFromAsset(this.getAssets(), "fonts/bn.ttf");
def_list_tv.setTypeface(tf); 

如果你在Logcat中看到Textview===null,请在第1行中指定正确的textview id。当我犯了这个错误时,我得到了与你相同的错误。希望对你有所帮助。

0

请尝试一下这个...我认为你的路径有问题,请检查路径

def_list_tv = (TextView)findViewById(R.id.def_list_textview);
Typeface tf = Typeface.createFromAsset(this.getAssets(), "bn.ttf");
def_list_tv.setTypeface(tf,null);

0

我找到了答案。正如silwar所指出的,这是因为我没有将一个活动与我的XML布局的内容视图分配。我只是使用了另一个具有不同内容视图的活动。

但还有一个问题。文本视图似乎仍然没有应用所注意到的字体。它只使用默认字体。我有一个用于列表视图的注意到的XML布局,我想使用我分配的字体。它将字符串添加到ArrayList中,并且列表视图的适配器使用以下代码:

defListAdapter = new ArrayAdapter<String>(this, R.layout.def_list, list);
defListView.setAdapter(defListAdapter);

def_list是我在之前的问题中指出的XML布局。defListView是列表视图。为什么我看不到所需的字体?


0
你应该注意 "fonts/bn.ttf"。所有字必须是原型。
bn.ttf 可能会是 BN.TTF。所以请注意 assets 文件夹,并确保与原型名称相同。

0

你的代码看起来完美无缺。 请检查一下,字体名称是否与你在资产文件夹中写的一样 -> 字体文件夹。如果是一样的话,尝试直接将字体移动到资产文件夹中,并在这里设置“bn.ttf”,而不是“fonts/bn.ttf”。


我认为这是针对XML布局的。对于不仅仅是整个XML的文本视图,它可以工作。但对于这个,它不能。我是正确的吗? - Ali Allahyar
@AliAllahyar 请看我的回答。 - Piyush
@AliAllahyar:将您的TextView放置在LinearLayout或RelativeLayout中,然后尝试一下...它肯定会起作用...我已经尝试过了。我认为问题出在您的XML文件中。 - user2551221

0
将您的字体文件从fonts/文件夹中移除,直接放入Assets文件夹中,应该就可以了!希望能帮到您。

0
public class TextViewPlus extends TextView {
    private static final String TAG = "TextView";

    public TextViewPlus(Context context) {
        super(context);
    }

    public TextViewPlus(Context context, AttributeSet attrs) {
        super(context, attrs);
        setCustomFont(context, attrs);
    }

    public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setCustomFont(context, attrs);
    }

    private void setCustomFont(Context ctx, AttributeSet attrs) {
        TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
        String customFont = a.getString(R.styleable.TextViewPlus_customFont);
        setCustomFont(ctx, customFont);
        a.recycle();
    }

    public boolean setCustomFont(Context ctx, String asset) {
        Typeface tf = null;
        try {
            tf = Typeface.createFromAsset(ctx.getAssets(), asset);  
        } catch (Exception e) {
            Log.e(TAG, "Could not get typeface: "+e.getMessage());
            return false;
        }

        setTypeface(tf);  
        return true;
    }
}

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