6

短版: 在 xml 中使用 android:hardwareAccelerated="false" 禁用硬件加速会将我的 Theme.Sherlock.Light.DarkActionBar 主题的背景颜色更改为更白的“白色”。 编辑:这曾经是主要问题。我更改了标题以强调第二个问题。

仅对 mapView 禁用硬件加速会导致不断重绘。

长版:

默认情况下,AFAIK 硬件加速在 API 级别 14 及更高级别上启用。(参考)

由于我正在构建和测试 API 级别 16,因此我的硬件加速通常是开启的,所以这就是我习惯看到的。主题是浅色但不是纯白色,它是浅灰色(默认)。

我在地图上绘制了一些圆形叠加层,当我放大关闭时,地图视图变得非常滞后,并且在 logcat 中出现“太大而无法渲染为纹理”的形状错误。我发现关闭硬件加速可以解决问题。

当我在 android 清单中为应用程序(或单个活动)关闭硬件加速时,我的布局的背景颜色会发生变化。它从浅灰色变为非常浅的灰色,几乎是纯白色。这是正常行为吗?

我尝试为地图视图关闭硬件加速:

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

这对于消除纹理过大的错误非常有效,因为地图视图没有硬件加速,并且它还使我的应用程序的其余部分硬件加速。这将是理想的解决方案。然而,这会导致另一个问题。它使我使用此代码的叠加层的 onDraw 方法不断被调用。即,onDraw 本身被一遍又一遍地调用,而不在 mapview 上调用 invalidate()。知道为什么会这样吗?

更新:

下面是一些简单的代码,当仅为mapView(我想要的)禁用硬件加速时,将重新创建常量重绘问题:

地图活动:

public class SettingsActivity extends MapActivity {

private MapView mapView;
private static List<Overlay> overlayList;
private static AccuracyCircleOverlay accuracyCircleOverlay;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_manage_maps);

    mapView = (MapView) findViewById(R.id.map);

    overlayList = mapView.getOverlays();
    accuracyCircleOverlay = new AccuracyCircleOverlay(this);
    overlayList.add(accuracyCircleOverlay);
}

@Override
protected boolean isRouteDisplayed() {
    return false;
}
}

覆盖:

public class AccuracyCircleOverlay extends Overlay {

private Context context;

public AccuracyCircleOverlay(Context context) {
    this.context = context;
}

@TargetApi(11)
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
    super.draw(canvas, mapView, shadow);

    if (android.os.Build.VERSION.SDK_INT >= 11) {
        mapView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }                 
            Log.d("accuracy OVERLAY", "being redrawn");
}
}
4

3 回答 3

4

我终于意识到问题所在了。将 mapView 的图层类型设置为软件不应该从覆盖的绘制方法内部完成!这样做似乎会触发另一次平局,从而导致循环。我将以下代码放在包含 mapView 的 Activity 的 onCreate 中,并且它可以正常工作。它告诉 mapView 在软件模式下渲染而不会导致不断的重绘!

活动中:

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

或者在 XML 中:

<com.google.android.maps.MapView
        ...
        android:layerType="software" />
于 2013-01-08T21:17:17.527 回答
2

我很欣赏这个答案并没有解决您问题的重点(我理解这是在质疑为什么MapView关闭硬件加速时相关的覆盖层会不断重绘 - 我承认,我真的不知道为什么)。但是,正如 ndw 建议的那样,我认为您应该打开加速,而是专注于限制您在叠加层中实际绘制的内容的大小。

这正是我现在正在处理的应用程序中必须做的事情。我在我Path的顶部画了一个MapView来说明来自 GPS 数据日志的路线。如果我放大得太远,Path突然消失,我在 LOGCAT 中收到警告说“形状路径太大而无法渲染成纹理”,就像你一样。我修复它的解决方案是Path在地图的每个缩放中重新生成 (考虑到这一点,无论如何都需要完成,因为在每个缩放级别上,您获得的实际像素位置Projection明显不同)。当Path由您所基于的任何数据(例如GeoPoints 集)生成时,请使用Projection类来确定是否有任何路径段等远离地图并且应该离开(这就是我对 GPS 路线所做的事情)。如果您有单个矢量对象本身可能会变得太大(例如圆圈),那么我建议您设计代码,以便如果圆圈的任何区域落在地图内,它将包括圆圈,但还包括一些逻辑如果在高缩放级别,只需在可见区域中绘制该圆表面的一小部分(例如通过绘制正方形)。

于 2012-12-10T22:15:57.780 回答
1

我不认为更改是颜色特定于您的代码,我经历过同样的事情。

在没有 GPU 仿真和 holo_light 主题的情况下运行模拟器,您将获得白色背景,使用 GPU 仿真运行,您将获得浅灰色背景。

也就是说,我不认为禁用硬件加速是解决 mapview 问题的正确方法。我会尝试找出您尝试渲染的形状太大的原因,以及是否可以采取任何措施使其变小。

于 2012-12-10T19:16:01.093 回答