画布不在自定义视图中显示所有绘制的部分?

时间:2012-07-12 21:27:59

标签: android android-emulator android-canvas android-view

我正在为Android应用程序开发自定义视图,类似于Mind the Robot提供的Analog Gauge示例代码。

从列出的网站运行代码,我会在屏幕上看到这个:

(摩托罗拉Droid,2.2.3),(仿真器,4.0.3)

has an arrow

(Xoom,4.0.3)(其他电话,4.0.3)

does not have an arrow

手不见了!

正在进行绘图调用(我可以在logcat中看到它们),但调用绘制的画布元素是不可见的。

不依赖于API级别;如果我以正确的方式将其导入到项目中,当我在Xoom上运行它时它会显示出来。

但是,当我将文件移动到不同的项目文件夹(相同的源代码,相同的布局)时,它会回到丢失拨号盘。

发生了什么事?相同的代码如何在不同的设备上产生不同的结果呢?

7 个答案:

答案 0 :(得分:13)

因此,我神秘的关键线索似乎是它在模拟器上运行,但在硬件设备上却没有。

硬件渲染

我确实仔细阅读了Android Developer网站上的硬件渲染页面,但显然还不够。

http://developer.android.com/guide/topics/graphics/hardware-accel.html

虽然它确实提到API从版本11开始可用,但它没有说默认情况下为所有应用程序打开了硬件渲染,从API Level 14(ICS)开始。

这对我们意味着什么?

几乎所有东西都更快;除了少数不起作用的东西。

我设法违反其中两项,却没有意识到:

  • Canvas.DrawTextOnPath()
  • Paint.setShadowLayer()

在API参考中没有提及(或者我可以找到的任何其他地方,当然也没有被Lint检查过),但使用任何列出的操作都可以做到奇怪的事情。

就我而言,Canvas.DrawTextOnPath()似乎工作正常。

但是当Android注意到我手上使用的颜料设置了阴影层时,它会默默地忽略它。

我如何知道我的View是否是硬件加速的?

从上面的文档链接:

  

有两种不同的方法可以检查应用程序是否是硬件加速的:

     
      
  • 如果视图附加到硬件加速窗口,View.isHardwareAccelerated()将返回true。
  •   
  • 如果Canvas是硬件加速的,Canvas.isHardwareAccelerated()会返回true
  •   
     

如果您必须检查绘图代码,请尽可能使用Canvas.isHardwareAccelerated()代替> View.isHardwareAccelerated()。当视图附加到硬件>加速窗口时,仍然可以使用非硬件加速Canvas绘制它。例如,当将视图绘制到位图中以用于缓存时,会发生这种情况。

在我的情况下,似乎发生了相反的情况。 自定义视图记录它不是硬件加速的;然而,画布报告它是硬件加速的。

解决方法和工作

最简单的解决方法是强制自定义视图进行软件渲染。根据文档,这可以通过以下方式完成:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

或者,您可以删除有问题的操作,并保持硬件渲染开启。

从我的不幸中学习。祝你好运。

答案 1 :(得分:3)

我将它放入init()并在此之后正常工作。

    private void init() {
    setLayerType(myView.LAYER_TYPE_SOFTWARE, null);
    ....
}

答案 2 :(得分:2)

鹰,你究竟在哪里称这条线?我在初始化后称之为:

    tachometer = (CustomRoundInstrument) theFragment.findViewById(R.id.tachometer);
    tachometer.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

虽然这不起作用,我是否必须将其称为其他地方?

非常感谢帮助!

答案 3 :(得分:2)

使用myView.setLayerType(View.LAYER_TYPE_SOFTWARE,null);建议我可以看到手。但我还有一个问题:我看到只有0写的比例!如同在图片和模式中的两个存储零:( GALAXY NEXUS 4.2.1)

enter image description here

我的drawScale()方法如下例所示:

 private void drawScale(Canvas canvas) {
        canvas.drawOval(scaleRect, scalePaint);

        canvas.save(Canvas.MATRIX_SAVE_FLAG);
        for (int i = 0; i < totalNicks; ++i) {
            float y1 = scaleRect.top;
            float y2 = y1 - 0.020f;

            canvas.drawLine(0.5f, y1, 0.5f, y2, scalePaint);


            if ((i % 5) == 0) {
                int value = nickToDegree(i);

                if ((value >= minDegrees) && (value <= maxDegrees)) {
                    String valueString = Integer.toString(value);
                    canvas.drawText(valueString, 0.5f, y2 - 0.015f, scalePaint);

                }
            }

            canvas.rotate(degreesPerNick, 0.5f, 0.5f);


        }
        canvas.restore();

    }

答案 4 :(得分:0)

在我的情况下,我做了这个:

 AnalogView bar = (AnalogView) findViewById(R.id.AnalogBar);
    bar.setLayerType(bar.LAYER_TYPE_SOFTWARE, null);
if (value_list.size()>0)   bar.SetData(Double.parseDouble(value_list.get(value_list.size()-1)));

其中AnalogView中的SetData为

public  void SetData(double data) {
    setHandTarget((float)data);
  invalidate();
}

答案 5 :(得分:0)

关于Galaxy S4 Android 4.4.2

TYPE_TEMPERATURE已弃用

使用

TYPE_AMBIENT_TEMPERATURE

答案 6 :(得分:-1)

对于在初始化中按比例绘制文本问题的任何人,请执行以下操作:

scalePaint.setLinearText(真);