2

I am trying to apply a custom font in different Activities, right now I have the following code in the onCreate() in my MainActivity:

String fontTitle = "fonts/OpenSans-Bold.ttf";
Typeface titleFont = Typeface.createFromAsset(getAssets(), fontTitle);
page_title.setTypeface(titleFont);

I want to know if it is possible to make the Typeface public so I can access it in other activities.

I created a class called FontHelper:

public class FontHelper extends MainActivity {

    // path for the fonts
    String fontTitle = "fonts/OpenSans-Bold.ttf";

    Typeface titleFont = Typeface.createFromAsset(getAssets(), fontTitle);

}

but in other Activities when I use textView.setTypeface(FontHelper.titleFont) I get an error. How can I fix this error?

Xaver Kapeller
  • 49,491
  • 11
  • 98
  • 86
Rain Man
  • 1,163
  • 2
  • 16
  • 49
  • 1
    What's wrong with creating a new Typeface instance in every Activity? Or a static factory method which creates the Typeface? What you are trying to do is technically possible, but would only serve to create a memory leak - which I hope you know is a bad thing. – Xaver Kapeller May 04 '16 at 02:38
  • @XaverKapeller I want to use the typeface in different activities but I thought it would be redundant, so I decided to create a helper class. How does this create a memory leak? I just read [this post](http://martin.cubeactive.com/android-how-to-use-a-custom-font/) in the last example it kind of does what I was looking for, will this still create a memory leak? – Rain Man May 04 '16 at 02:42
  • Yes it does, don't blindly follow random blog posts on the Internet. Having a helper class is not a bad thing, but the implementation of the helper class in this post is problematic since it leaks the Context with which the Typeface was created. The way to fix this simple: don't have a static variable which keeps a reference to the Typeface. Instead pass the context into the helper method to create a new Typeface instance for each Activity. – Xaver Kapeller May 04 '16 at 02:47
  • See my answer for more information. – Xaver Kapeller May 04 '16 at 02:53

3 Answers3

1

You can use a static factory method to create your Typeface instance for each Activity like this:

public class FontHelper {

    private static final String FONT_PATH = "fonts/OpenSans-Bold.ttf";

    public static Typeface getCustomTypeFace(Context context) {
        return Typeface.createFromAsset(context.getAssets(), FONT_PATH);
    }
}

You can use it like this:

public class ExampleActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final Typeface typeface = FontHelper.getCustomTypeFace(this);
        ...
    }
}
Xaver Kapeller
  • 49,491
  • 11
  • 98
  • 86
  • thanks, this is exactly what I was looking for. In you opinion, is this better or creating a new Typeface instance in every Activity? – Rain Man May 04 '16 at 03:03
  • This does create a new Typeface in every Activity, it just does it in a factory as part of the FontHelper class. This is the optimal solution for your use case. – Xaver Kapeller May 04 '16 at 03:07
-1

First you must create a common activity called MasterActivity

public class MasterActivity extends AppCompatActivity {

    protected Typeface titleFont;

    @Override
    public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
        super.onCreate(savedInstanceState, persistentState);

        // path for the fonts
        String fontTitle = "fonts/OpenSans-Bold.ttf";

        titleFont = Typeface.createFromAsset(getAssets(), fontTitle);
    }
}

and then make your MainActivity extends from MasterActivity like this:

public class MainActivity extends MasterActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // set the custom font
        page_title.setTypeface(titleFont);
    }
}

and AboutActivity extends from MasterActivity too

public class AboutActivity extends MasterActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_about);

        // set the custom font
        page_title.setTypeface(titleFont);
    }
}
Vu Nguyen
  • 301
  • 1
  • 3
  • 10
-1

Use this custom font class

public class TextView extends android.widget.TextView {
    Context mContext;
    String str;
    //fonts
    public static Typeface Font_name;

    public TextView(Context context) {
        super(context);
        mContext=context;


        initialiseFont(null);
    }



    public TextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext=context;
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TextView, 0, 0);
        try {
            str = ta.getString(R.styleable.TextView_font_family);

        } finally {
            ta.recycle();
        }
        initialiseFont(str);
    }

    public TextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext=context;
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TextView, 0, 0);
        try {
            str = ta.getString(R.styleable.TextView_font_family);

        } finally {
            ta.recycle();
        }
        initialiseFont(str);
    }

    public TextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mContext=context;
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TextView, 0, 0);
        try {
            str = ta.getString(R.styleable.TextView_font_family);

        } finally {
            ta.recycle();
        }
        initialiseFont(str);
    }
    private void initialiseFont(String font) {
        if(font==null || font.equals("")){

        }
        else {
            Font_name = Typeface.createFromAsset(mContext.getAssets(), font);
            setTypeface(Font_name);
        }

    }
}

Add this tag in arrs.xml to read custom attribute font-family

<resources>
    <declare-styleable name="TextView">
        <attr name="font_family" format="string"/>
    </declare-styleable>
</resources>

Copy your font in assets folder(Use same file name) and Use this tag if you are using TextView anywhere

<Your_package_name_which_you_created_custom_font_class.TextView
        android:text="Hello World!"
        android:layout_width="wrap_content"
        app:font_family="OpenSans-Bold.ttf"
        android:layout_height="wrap_content" />