草庐IT

android - Canvas.drawVertices(...) 什么都不画

coder 2023-12-10 原文

下一个类是一个红色三角形的 View :

public class FreeStyleViewII extends View {

private final Paint paint = new Paint();
private final int[] colors = new int[] {
        Color.RED,
        Color.RED,
        Color.RED,
        0xFF000000, 0xFF000000, 0xFF000000
};
private final float[] verts = new float[] {
    1f/2f * 200f, 1f/4f * 200f,
    1f/4f * 200f, 3f/4f * 200f,
    3f/4f * 200f, 3f/4f * 200f
};
private final Path path = new Path();
{
    path.moveTo(1/2 * 200, 1/4 * 200);
    path.lineTo(1/4 * 200, 3/4 * 200);
    path.lineTo(3/4 * 200, 3/4 * 200);
    path.lineTo(1/2 * 200, 1/4 * 200);
}

private final RectF bounds = new RectF();

    public FreeStyleViewII(Context context) {
        super(context);
    }

    public FreeStyleViewII(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public FreeStyleViewII(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.clipRect(bounds);
        canvas.drawRGB(0, 0, 0);

        paint.setStyle(Style.FILL);
        paint.setColor(Color.RED);

        // HERE. WHY DRAWVERTICES DOESN'T WORK BUT DRAWPATH DOES?... 
        canvas.drawVertices(Canvas.VertexMode.TRIANGLES, verts.length, verts, 0, null, 0, colors, 0, null, 0, 0, paint);
        // canvas.drawPath(path, paint);

        paint.setStyle(Style.STROKE);
        paint.setColor(Color.LTGRAY);
        canvas.drawLine(0, bounds.bottom / 2, bounds.right, bounds.bottom / 2, paint);
        canvas.drawLine(bounds.right / 2, 0, bounds.right / 2, bounds.bottom, paint);

        // Delay
    try {  
        Thread.sleep(30);  
    } catch (InterruptedException e) { }

        invalidate();

    }

@Override
public void onSizeChanged(int w, int h, int oldW, int oldH) {
    bounds.set(1, 1, w - 1, h - 1);
    System.out.println(bounds.left + " " + bounds.top + " " + bounds.right + " " + bounds.bottom);

    verts[0] = bounds.left + ((bounds.right - bounds.left) * (1f / 2f));
    verts[1] = bounds.top + ((bounds.bottom - bounds.top)  * (1f / 4f));
    System.out.println(" Point: X ----> " + verts[0] + " | Y ----> " + verts[1]);

    verts[2] = bounds.left + ((bounds.right - bounds.left) * (1f / 4f));
    verts[3] = bounds.top + ((bounds.bottom - bounds.top)  * (3f / 4f));
    System.out.println(" Point: X ----> " + verts[2] + " | Y ----> " + verts[3]);

    verts[4] = bounds.left + ((bounds.right - bounds.left) * (3f / 4f));
    verts[5] = bounds.top + ((bounds.bottom - bounds.top)  * (3f / 4f));
    System.out.println(" Point: X ----> " + verts[4] + " | Y ----> " + verts[5]);

    path.reset();

    path.moveTo(verts[0], verts[1]);
    path.lineTo(verts[2], verts[3]);
    path.lineTo(verts[4], verts[5]);
    path.lineTo(verts[0], verts[1]);

}
}

当我使用 Canvas.drawPath 方法时,它工作正常。但是,如果我更改为 Canvas.drawVertices,它什么也不会绘制。我已经检查了 Bug in Canvas.drawVertices? (with repro code and logcat) 中所说的内容和 Method drawVertices() didn't drawing anything on Android Canvas ,但在我的情况下结果是一样的。

我正在使用 AndroVM(v 4.1.1)VirtualBox(v 4.1.22)用于检测。难道是模拟器?

有什么想法吗?

最佳答案

简答:

禁用硬件加速,你会没事的!

长答案:

我遇到了完全相同的问题。在我的自定义 View 代码中,我调用了 Canvas.drawVertices(),如下所示:

canvas.drawVertices(Canvas.VertexMode.TRIANGLES, mTriVerts.length, mTriVerts, 0, null, 0, mTriangleColors, 0, null, 0, 0, mTriPaint);

这在许多设备上的工作方式与预期完全一样,但在我的 4.x 测试设备上,我尝试绘制的三角形完全消失了,并且 logcat 中没有任何痕迹可以说明原因。

在 S.O. 找不到解决方案之后我开始四处挖掘,偶然发现了以下令人震惊的解决方案:如果启用了硬件加速,一堆标准的东西将无法工作,包括对 Canvas.drawVertices() 的任何调用,并且硬件加速已打开在所有支持 Android 4.x 及更高版本的设备上默认打开。

问题及解决方案概述in the official android docs .在这里总结一下,只需将其放在不受支持的调用之前的行中:

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

这是在 View 级别上,不幸的是,目前无法在已设置为软件模式的 View 上重新启用硬件加速,但阅读文档时感觉是这样将来可能是一个选择。如果您觉得您的代码需要硬件加速,只需避免使用调用,或将不兼容的代码单独收集在一个 View 中,然后对其进行概要分析,看看您是否确实通过这种方式获得了一些东西。

重要编辑:

setLayerType() 调用仅在 Android API 级别 11 及更高版本上受支持,这意味着您必须将对此函数的调用包装在版本检查中,以使其在早期版本上工作,如下所示:

if (android.os.Build.VERSION.SDK_INT >= 11) {
    setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

现在你应该准备好了!

PS:希望这个答案能及时送达您手中!

关于android - Canvas.drawVertices(...) 什么都不画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14679063/

有关android - Canvas.drawVertices(...) 什么都不画的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  6. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  7. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  8. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  9. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  10. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

随机推荐