【问题标题】:Acquire Context in custom Drawable class在自定义 Drawable 类中获取 Context
【发布时间】:2018-05-04 19:35:07
【问题描述】:

我试图创建一个自定义类以将文本实现为可绘制但我无法将Typeface 设置为Paint。 下面是自定义类的代码实现(即TextDrawable)。

这里我想获取Application的上下文来调用方法getAssets(),但是这里我无法调用方法getContext()

public class TextDrawable extends Drawable {
    private final String text;
    private final Paint paint;

    public TextDrawable(String text) {
        this.text = text;
        this.paint = new Paint();
        paint.setColor(Color.GRAY);
        paint.setTextSize(35f);
        //paint.setTypeface(Typeface.createFromAsset(**getContext().getAssets()**, "fonts/Montserrat-Regular.otf"));
        paint.setAntiAlias(true);
        paint.setTextAlign(Paint.Align.RIGHT);
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.drawText(text, 0, 10, paint);
    }

    @Override
    public void setAlpha(int alpha) {
        paint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        paint.setColorFilter(cf);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
}

【问题讨论】:

  • 确保您取消注释代码行,如果这是故意的,您可以尝试使用在线工具将 otf 文件转换为 ttf。
  • 你到底有什么问题?
  • 嗨,@IsmailIqbal 评论是故意的,文件格式没有问题。我无法在此类中获取 getContext().getAssets()
  • 我无法在此类@MikeM 中获取getContext().getAssets()。
  • 请参考此question 并查看评分最高的答案。

标签: java android android-context android-typeface android-custom-drawable


【解决方案1】:

可绘制对象没有上下文。所以正如@azizbekian 和@Mike M 所建议的,你有两个选择。

在构造函数中传递上下文

public TextDrawable(Context context, String text) {
    paint.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/Montserrat-Regular.otf"));
    ...
}

请注意,这种方法会在您每次使用此 Drawable 时创建一个新的 Typeface 实例,这通常是一种不好的做法,也会直接影响性能。

在构造函数中传递字体

public TextDrawable(String text, Typeface typeface) {
    paint.setTypeface(typeface);
    ...
}

这种方法更好,因为您可以将单个字体实例用于与此 Drawable 相关或不相关的多个对象。

扩展后一种方法,您可以创建一个静态 TypefaceProvider,如下所示。这样可以确保您始终只有一个实例字体。

字体提供者

public class TypefaceProvider
{
    private static Map<String, Typeface> TYPEFACE_MAP = new HashMap<>();

    public static Typeface getTypeFaceForFont(Context context, String fontFile)
    {
        if (fontFile.length() <= 0) throw new InvalidParameterException("Font filename cannot be null or empty");
        if (!TYPEFACE_MAP.containsKey(fontFile))
        {
            try
            {
                Typeface typeface = Typeface.createFromAsset(context.getAssets(), "fonts/"+fontFile);
                TYPEFACE_MAP.put(fontFile, typeface);
            }
            catch (Exception e)
            {
                throw new RuntimeException(String.format("Font file not found.\nMake sure that %s exists under \"assets/fonts/\" folder", fontFile));
            }
        }

        return TYPEFACE_MAP.get(fontFile);
    }
}

【讨论】:

  • 好的,如果我在应用程序类级别创建一个静态上下文,然后在这里使用该上下文怎么样。如果有任何缺点。这样做。
  • 应用程序中的静态上下文是“非推荐,首选”方法。每个人都使用它,但没有人推荐它。所以,是的,你可以,只是不要告诉任何人是我建议的! >:)
【解决方案2】:

我无法在此类中获取 getContext().getAssets()。

您必须将Context 对象作为参数传递给您的类的构造函数:

public class TextDrawable extends Drawable { ... public TextDrawable(Context context, String text) { paint.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/Montserrat-Regular.otf")); ... } ... }

【讨论】:

  • 应该是Typeface#createFromAsset(AssetManager mgr, String path)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-15
  • 2011-02-18
  • 1970-01-01
  • 1970-01-01
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多