Loading typeface dynamically from url or statically from lib

家住魔仙堡 提交于 2020-01-06 02:40:28

问题


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.


回答1:


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);


来源:https://stackoverflow.com/questions/38167537/loading-typeface-dynamically-from-url-or-statically-from-lib

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!