在以下链接
写道:
图书馆项目不能包含原始资产 这些工具不支持在库项目中使用原始资产文件(保存在assets /目录中)。应用程序使用的任何资产资源都必须存储在应用程序项目本身的assets /目录中。但是,支持保存在res /目录中的资源文件。
因此,如果我想创建一个使用自定义字体的自定义视图组件,我该如何访问该资源?我不能用我最喜欢的字体重新分发我的组件!!!!
祝你好运
答案 0 :(得分:24)
这是从实际工作的资源加载字体的方法;-) 归功于第一版的mr32bit。
private Typeface getFontFromRes(int resource)
{
Typeface tf = null;
InputStream is = null;
try {
is = getResources().openRawResource(resource);
}
catch(NotFoundException e) {
Log.e(TAG, "Could not find font in resources!");
}
String outPath = getCacheDir() + "/tmp" + System.currentTimeMillis() ".raw";
try
{
byte[] buffer = new byte[is.available()];
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outPath));
int l = 0;
while((l = is.read(buffer)) > 0)
bos.write(buffer, 0, l);
bos.close();
tf = Typeface.createFromFile(outPath);
// clean up
new File(outPath).delete();
}
catch (IOException e)
{
Log.e(TAG, "Error reading in font!");
return null;
}
Log.d(TAG, "Successfully loaded font.");
return tf;
}
答案 1 :(得分:7)
好的,我找到了解决问题的方法。您需要将文件复制到外部目录,然后从Typeface.createFromFile
的文件加载字体,然后删除临时文件。我知道这不是一种干净的工作方式,而是在努力工作。
1 - 您需要将字体放在“/res/raw/font.ttf”
上2 - 在您的代码中使用以下方法
3 - 输入您的代码Typeface mFont = FileStreamTypeface(R.raw.font);
4 - 一切都已完成
Typeface FileStreamTypeface(int resource)
{
Typeface tf = null;
InputStream is = getResources().openRawResource(resource);
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/gmg_underground_tmp";
File f = new File(path);
if (!f.exists())
{
if (!f.mkdirs())
return null;
}
String outPath = path + "/tmp.raw";
try
{
byte[] buffer = new byte[is.available()];
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outPath));
int l = 0;
while((l = is.read(buffer)) > 0)
{
bos.write(buffer, 0, l);
}
bos.close();
tf = Typeface.createFromFile(outPath);
File f2 = new File(outPath);
f2.delete();
}
catch (IOException e)
{
return null;
}
return tf;
}
如果有人有替代方案,我很高兴看到它。 您是否必须记住此解决方法仅适用于Android库
祝你好运
答案 2 :(得分:2)
Intellij Idea(和android studio一样,它基于intellij)有一个功能,可以让你将库模块的资产文件包含到应用程序模块中,我不了解其他环境。
转到文件菜单中的项目结构,然后进入facet,选择应用程序模块,在编译器选项卡中选中“将资源从依赖项包含到进入APK”复选框。
由于intellij比Eclipse好得多,我认为迁移是合理的。
修改强>
android studio中完全支持资产和清单合并。
答案 3 :(得分:1)
如果扩展TextView并想要使用许多此视图,则此视图中只应有一个Typeface实例。将* .ttf文件复制到res / raw /并使用以下代码:
public class MyTextView extends TextView {
public static final String FONT = "font.ttf";
private static Typeface mFont;
private static Typeface getTypefaceFromFile(Context context) {
if(mFont == null) {
File font = new File(context.getFilesDir(), FONT);
if (!font.exists()) {
copyFontToInternalStorage(context, font);
}
mFont = Typeface.createFromFile(font);
}
return mFont;
}
private static void copyFontToInternalStorage(Context context, File font) {
try {
InputStream is = context.getResources().openRawResource(R.raw.font);
byte[] buffer = new byte[4096];
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(font));
int readByte;
while ((readByte = is.read(buffer)) > 0) {
bos.write(buffer, 0, readByte);
}
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setTypeface(getTypefaceFromFile(context));
}
}
mFont是一个静态变量,因此引用不会被销毁,可以在其他MyTextViews中重用。 这段代码与其他答案几乎相同,但我觉得如果你在ListView或其它东西中使用它,效率会提高并消耗更少的内存。
答案 4 :(得分:0)
因此,如果我想创建一个使用自定义字体的自定义视图组件,我该如何访问该资源?
您的代码将以不同的方式访问它。您只需告诉自定义视图的重用者将字体文件包含在其资产中。
我不能用我最喜欢的字体重新发布我的组件!!!!
当然可以。将字体与库项目的其余部分一起放在ZIP文件中,以及将其放在项目中的位置说明。但是请务必使用您有权以这种方式重新分发的字体。
答案 5 :(得分:0)
即使你将你的字体放在assets / fonts文件夹中,这个库也可以运行,而且非常容易使用:https://github.com/neopixl/PixlUI。我已经在Android 2.3上成功测试过了。 以及4.4
答案 6 :(得分:0)
只需使用@ bk138的响应,这对我有用的小改动
在清单
中添加此内容<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
并在创建Buffered
之前添加它 File f2 = new File(outPath);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outPath));
答案 7 :(得分:0)
下面的代码修改了@ bk138的解决方案,并包含了@Jason Robinson的建议,即不删除文件并首先检查先前缓存的文件。此外,它在字体后面命名临时文件而不是创建时间。
public static Typeface getFontFromRes(Context context, int resId, boolean deleteAfterwards){
String tag = "StorageUtils.getFontFromRes";
String resEntryName = context.getResources().getResourceEntryName(resId);
String outPath = context.getCacheDir() + "/tmp_" + resEntryName + ".raw";
//First see if the file already exists in the cachDir
FileInputStream fis = null;
try {
fis = new FileInputStream(new File(outPath));
} catch (FileNotFoundException e) {
Log.d(tag,"fileNotFoundException outPath:"+outPath+e.getMessage());
}
if(fis != null){
try {
Log.d(tag,"found cached fontName:"+resEntryName);
fis.close();
} catch (IOException e) {
Log.d(tag,"IOException outPath:"+outPath+e.getMessage());
}
//File is already cached so return it now
return Typeface.createFromFile(outPath);
}
InputStream is = null;
try {
is = context.getResources().openRawResource(resId);
}catch(NotFoundException e) {
Log.e(tag, "Could not find font in resources! " + outPath);
}
try{
byte[] buffer = new byte[is.available()];
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outPath));
int l = 0;
while((l = is.read(buffer)) > 0)
bos.write(buffer, 0, l);
bos.close();
}catch (IOException e){
Log.e(tag, "Error reading in font!");
return null;
}
Typeface tf = Typeface.createFromFile(outPath);
if(deleteAfterwards){
// clean up if desired
new File(outPath).delete();
}
Log.d(tag, "Successfully loaded font.");
return tf;
}
答案 8 :(得分:0)
这是我在@ Mr32Bit的答案中修改后的版本/改进。在第一次调用时,我将字体复制到app private dir / custom_fonts。将来读取检查是否存在,如果是,则读取现有副本(每次在复制文件上节省时间)。
注意:这假定只有一个自定义字体。
/**
* Helper method to load (and cache font in app private folder) typeface from raw dir this is needed because /assets from library projects are not merged in Eclipse
* @param c
* @param resource ID of the font.ttf in /raw
* @return
*/
public static Typeface loadTypefaceFromRaw(Context c, int resource)
{
Typeface tf = null;
InputStream is = c.getResources().openRawResource(resource);
String path = c.getFilesDir() + "/custom_fonts";
File f = new File(path);
if (!f.exists())
{
if (!f.mkdirs())
return null;
}
String outPath = path + "/myfont.ttf";
File fontFile = new File(outPath);
if (fontFile.exists()) {
tf = Typeface.createFromFile(fontFile);
}else{
try
{
byte[] buffer = new byte[is.available()];
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outPath));
int l = 0;
while((l = is.read(buffer)) > 0)
{
bos.write(buffer, 0, l);
}
bos.close();
tf = Typeface.createFromFile(outPath);
}
catch (IOException e)
{
return null;
}
}
return tf;
}