Android 如何在RecyclerView中为TextView设置自定义字体?

Android 如何在RecyclerView中为TextView设置自定义字体?,android,textview,android-recyclerview,Android,Textview,Android Recyclerview,我正在使用一个RecyclerView从云计算中填充数据。但是看起来,为文本视图设置自定义字体并不容易,因为它位于视图内部。传统的方式,这是我尝试的: TextView tx = (TextView)findViewById(R.id.person_age); Typeface custom_font = Typeface.createFromAsset(getAssets(), "fonts/Dancing Script.ttf"); tx.setTypeface(cust

我正在使用一个
RecyclerView
从云计算中填充数据。但是看起来,为
文本视图设置自定义字体并不容易,因为它位于视图内部。传统的方式,这是我尝试的:

TextView tx = (TextView)findViewById(R.id.person_age);

    Typeface custom_font = Typeface.createFromAsset(getAssets(), "fonts/Dancing Script.ttf");

    tx.setTypeface(custom_font);
但在这里,它会使应用程序崩溃,因此要寻找修复方法,以下是主要活动的代码:

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Parse.initialize(this, "app-id", "clientkey");
    setContentView(R.layout.activity_big_board);
    initializeData();
    TextView tx = (TextView)findViewById(R.id.person_age);

    Typeface custom_font = Typeface.createFromAsset(getAssets(), "fonts/Dancing Script.ttf");

    tx.setTypeface(custom_font);
    adapter = new RVAdapter(persons);


    rv=(RecyclerView)findViewById(R.id.rv);

    LinearLayoutManager llm = new LinearLayoutManager(this);
    rv.setLayoutManager(llm);
    rv.setHasFixedSize(true);


    initializeAdapter();

}

private void initializeData(){
    persons = new ArrayList<>();


    ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("BigBoard");
    query.findInBackground(new FindCallback<ParseObject>() {
        public void done(List<ParseObject> credentialList, ParseException e) {
            if (e == null) {
                for(int i=0;i<credentialList.size();i++)
                {
                    a=credentialList.get(i).getString("Location");
                    b=credentialList.get(i).getString("Feed");
                    persons.add(new Person(a,b));



                    Log.d("OUT", "So the Val::------> " +a +b);


                }
            } else {
                Log.d("score", "Error: " + e.getMessage());
            }

            adapter.notifyDataSetChanged();
        }
    });


}

private void initializeAdapter(){

    rv.setAdapter(adapter);
}
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
初始化(这个“appid”、“clientkey”);
setContentView(R.layout.activity\u big\u board);
初始化数据();
TextView tx=(TextView)findViewById(R.id.person\u age);
Typeface custom_font=Typeface.createFromAsset(getAssets(),“fonts/Dancing Script.ttf”);
tx.setTypeface(自定义字体);
适配器=新适配器(人);
rv=(RecyclerView)findViewById(R.id.rv);
LinearLayoutManager llm=新的LinearLayoutManager(本);
rv.setLayoutManager(llm);
rv.setHasFixedSize(真);
初始化为apter();
}
private void initializeData(){
persons=newarraylist();
ParseQuery查询=新的ParseQuery(“BigBoard”);
findInBackground(新的FindCallback(){
已完成公共作废(列出身份证明人,e){
如果(e==null){

对于(int i=0;i将
字体
逻辑移动到
PersonViewHolder
,可能是在其构造函数中,原因有二:

  • 此时存在
    TextView

  • 您的
    RecyclerView
    可能会有多个
    PersonViewHolder
    ,在这种情况下,您需要在每个
    PersonViewHolder
    中设置
    字体,因为将有多个项目和多个
    TextView
    需要
    字体


  • 创建扩展应用程序的其他类

    public class yourApplication extends Application {
    public Typeface robotoRegular;
    public Typeface robotoLight;
    public Typeface robotoBold;
    public Typeface robotoMedium;
    
    
    @Override
    public void onCreate() {
        super.onCreate();
        robotoRegular = Typeface.createFromAsset(this.getAssets(), getResources().getString(R.string.robotoRegular));
        robotoLight = Typeface.createFromAsset(this.getAssets(), getResources().getString(R.string.robotoLight));
        robotoBold = Typeface.createFromAsset(this.getAssets(), getResources().getString(R.string.robotoBold));
        robotoMedium = Typeface.createFromAsset(this.getAssets(), getResources().getString(R.string.robotoMedium));
    
        }
    }
    
    然后把它放在活页夹上

     @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        final String name = mDataset.get(position);
    
        holder.txtHeader.setTypeface(((yourApplication) mContext.getApplicationContext()).robotoRegular);
        holder.txtFooter.setTypeface(((yourApplication) mContext.getApplicationContext()).robotoLight);
    }
    
    公共类适配器\u Recycler\u Film扩展了RecyclerView.Adapter{
    专用静态字体;
    私有上下文;
    适配器_回收器_Film.DataViewHolder viewHolder;
    公共适配器\u回收器\u胶片(上下文、列表日期数据){
    ........
    this.mContext=上下文;
    face=Typeface.createFromAsset(mContext.getAssets(),“font/IRANSansMobile(FaNum)_Medium.ttf”);
    }
    }
    公共类DataViewHolder扩展了RecyclerView.ViewHolder{
    公共文本视图tDate;
    公共数据视图持有者(视图项视图){
    超级(项目视图);
    tDate=(TextView)itemView.findViewById(R.id.txt);
    如果(tDate!=null){
    tDate.setTypeface(字体);
    }
    }
    }
    
    As@commonware的答案可能与您的具体情况最相关。从效率、可读性和事后来看,我建议创建一个自定义的
    TextView
    ,然后将
    TextView
    分配到
    RecyclerView
    的项目行或应用程序中需要为此指定的字体

    CustomFontTextView.java

    值/attrs.xml

    因此,有了这段代码,您无需更改
    RecyclerView.Adapter
    RecyclerView.ViewHolder
    中的任何内容,也无需更改已初始化TextView的任何位置

    注意:您仍然可以使用
    TextView TextView=(TextView)findViewById(R.id.TextView)初始化组件
    。XML为您完成所有工作。除非您以编程方式创建
    TextView
    组件,否则您需要将其创建为
    CustomFontTextView TextView=new CustomFontTextView();


    您还可以将相同的逻辑应用于几乎任何组件,如
    EditText
    开关
    单选按钮
    表格布局

    “它会使应用程序崩溃”--使用LogCat检查与崩溃相关的Java堆栈跟踪:我认为这不是必需的。这是一个
    NullPointerException
    ,因为我猜它试图为尚未准备好的内容设置字体,问题是:我应该选择在Adapter类中设置它吗?正确的方法是什么?在这里发布之前,我已经尝试过了,但是问题是
    getAssets()
    ,无法解决方法getAssets(),有什么想法吗?:@oblivion:
    getAssets()
    Context
    上的一个方法。在
    TextView
    上调用
    getContext()
    来获得
    上下文
    。你想用
    getContext()替换
    getAssets()
    ?,然后又是相同的错误:(@oblivion:No.您有一个
    TextView
    personAge
    )的实例。
    TextView
    类定义了一个方法,
    getContext()
    上下文定义了一个方法,
    getAssets()
    。因此,
    personAge.getContext().getAssets()
    将返回您的
    AssetManager
     @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        final String name = mDataset.get(position);
    
        holder.txtHeader.setTypeface(((yourApplication) mContext.getApplicationContext()).robotoRegular);
        holder.txtFooter.setTypeface(((yourApplication) mContext.getApplicationContext()).robotoLight);
    }
    
     public class Adapter_Recycler_Film extends RecyclerView.Adapter<Adapter_Recycler_Film.DataViewHolder> {
        private static Typeface face;
        private Context mContext;
        Adapter_Recycler_Film.DataViewHolder viewHolder;
    
        public Adapter_Recycler_Film(Context context,List<String> dateData) {
            ........
            this.mContext=context;
            face = Typeface.createFromAsset(mContext.getAssets(),"fonts/IRANSansMobile(FaNum)_Medium.ttf");
        }
    }
    
    public class DataViewHolder extends RecyclerView.ViewHolder {
        public TextView tDate;
    
        public DataViewHolder(View itemView) {
            super(itemView);
            tDate = (TextView) itemView.findViewById(R.id.txt);
            if(tDate!=null){
                tDate.setTypeface(face);
            }
    
        }
    }
    
    package icn.premierandroid.misc;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Typeface;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.widget.TextView;
    
    import icn.premierandroid.R;
    
    public class CustomFontTextView extends TextView {
        AttributeSet attr;
        public CustomFontTextView(Context context) {
            super(context);
            setCustomFont(context, attr);
        }
    
        public CustomFontTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            setCustomFont(context, attrs);
        }
    
        public CustomFontTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            setCustomFont(context, attrs);
        }
    
        private void setCustomFont(Context ctx, AttributeSet attrs) {
            String customFont = null;
            TypedArray a = null;
            if (attrs != null) {
                a = ctx.obtainStyledAttributes(attrs, R.styleable.CustomFontTextView);
                customFont = a.getString(R.styleable.CustomFontTextView_customFont);
            }
            if (customFont == null) customFont = "fonts/portrait-light.ttf";
            setCustomFont(ctx, customFont);
            if (a != null) {
                a.recycle();
            }
        }
    
        public boolean setCustomFont(Context ctx, String asset) {
            Typeface tf = null;
            try {
                tf = Typeface.createFromAsset(ctx.getAssets(), asset);
            } catch (Exception e) {
                Log.e("textView", "Could not get typeface", e);
                return false;
            }
            setTypeface(tf);
            return true;
        }
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="CustomFontTextView">
            <attr name="customFont" format="string"/>
        </declare-styleable>
    </resources >
    
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        card_view:cardUseCompatPadding="true"
        card_view:cardCornerRadius="8dp">
    
       /** Containers and other Components **/
    
        <icn.premierandroid.misc.CustomFontTextView
            android:id="@+id/comment_user_name"
            android:layout_height="match_parent"
            android:layout_width="0dp"
            android:layout_marginStart="5dp"
            android:layout_marginLeft="5dp"
            android:gravity="center_vertical"
            android:layout_weight="0.36"/>
    
        <icn.premierandroid.misc.CustomFontTextView
            android:layout_width="0dp"
            android:layout_weight="0.40"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:layout_marginStart="1dp"
            android:layout_marginLeft="1dp" />
    
        <icn.premierandroid.misc.CustomFontTextView
            android:id="@+id/comment_time"
            android:layout_width="0dp"
            android:layout_weight="0.25"
            android:gravity="center_vertical"
            android:layout_height="match_parent"/>
    
    /** Containers and other Components **/
    
    </android.support.v7.widget.CardView>