I'm running an Android application and I want to load a font dynamically and use it during runtime. How can I do this?
And also how can I include a font in an SDK that I've written, reference the sdk in the app I've written, and use the font included in the SDK?
Edit: Thanks for putting a -1 Vote on this, whoever did this, I'll stop sharing knowledge, that's a good way to shut me down.
Here's how I would do it: (Using an AsyncTask, which is not perfect)
If you want something more stable than an AsyncTask RxAndroid offers other good variants, far more stable.
In this example I'm doing everything in the "doInBackground" section, but you can use it the same way, anywhere after the task is done.
This example also assumes we have persmissions to write and read from external storage.
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
public DownloadTask(Context context) {
this.context = context;
}
@Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// download the file
input = connection.getInputStream();
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/fonts");
dir.mkdirs();
File file = new File(dir, "font.ttf");
try {
OutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while((len=input.read(buf))>0){
out.write(buf,0,len);
}
out.close();
input.close();
} catch (Exception e) {
e.printStackTrace();
}
File sdcard = Environment.getExternalStorageDirectory();
File dirs = new File(sdcard.getAbsolutePath()+"/fonts");
if(dirs.exists()) {
File[] files = dirs.listFiles();
Log.d("s","files");
}
final Typeface typeface = Typeface.createFromFile(
new File(Environment.getExternalStorageDirectory()+"/fonts", "font.ttf"));
Log.d("a","created");
// Now I'm starting with an example that shows how to use
// this font on a textview of my choice.
// Assumptions: font has characters uF102 and uF104
final TextView tv = (TextView) findViewById(R.id.myTextView);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (tv != null && typeface != null) {
tv.setTypeface(typeface);
tv.setText("\uF102");
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (tv.getText().equals("\uF102")){
tv.setText("\uF104");
} else {
tv.setText("\uF102");
}
}
});
}
}
});
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
}
In case we want to load the font from an sdk we're using, of from a library we've written, we can include the font in the drawable raw section, and from the application using this sdk/lib we can reference the font like so:
(I've used the amaticobold font in this case just for example)
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/fonts");
dir.mkdirs();
File file = new File(dir, "font.ttf");
InputStream is = getResources().openRawResource(getResources().getIdentifier("amaticbold","raw", getPackageName()));
try {
OutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while((len=is.read(buf))>0){
out.write(buf,0,len);
}
out.close();
is.close();
} catch (Exception e) {
e.printStackTrace();
}
File sdcard = Environment.getExternalStorageDirectory();
File dirs = new File(sdcard.getAbsolutePath()+"/fonts");
if(dirs.exists()) {
File[] files = dirs.listFiles();
Log.d("s","files");
}
final Typeface typeface = Typeface.createFromFile(
new File(Environment.getExternalStorageDirectory()+"/fonts", "font.ttf"));
editText.setTypeface(typeface);