1

我一直在尝试显示指南针以及我的位置与地图上另一个位置之间的距离。

几乎完全一样:

Android:列表视图中的指南针+距离

我理解了代码,设置了一个监听器来检测方向变化,还计算了距离。

此外,我在我的 ListView 中显示了正确的距离(我已经有一个自定义适配器)。那是关于我在哪里的一点澄清。

这是我的问题:我通过侦听器每秒更新 ListView,通过更改适配器正在查看和调用的实际列表的值:

    notifyDataSetChanged();

正如我所预料的那样,每秒调用一次会使 ListView 变得迟钝。我可以每 10 秒左右(或更多)更新一次距离。但是,我必须更频繁地更新列表才能拥有实时指南针。我一直在四处寻找,我真的找不到任何东西,我会很感激我能得到的所有帮助。谢谢!

旁注:如果您需要查看我编写的任何代码,我愿意将其粘贴在这里。它有很多部分,所以我会按需做。

4

1 回答 1

1

恕我直言,您应该省略整个列表视图和适配器。最好的方法是为应该经常更新的元素创建自己的视图。

例如,创建名为 HeadingView 的视图,该视图将具有 setAbsouluteheading。此设置器将由适配器使用。然后视图也将实现 SensorEventListener 来观察传感器并获取设备标题。当相对方向应该改变 HeadingView 会自行更新。这种情况下的问题是检测 HeadingView 何时应为传感器事件注册/注销自身。onWindowFocusChanged看起来很有希望,而onWindowSystemUiVisibilityChanged(API 级别 16)正是您所需要的。

请记住,存在可能存在某些极端情况的危险,并且您的视图不会在应该的时候从观察传感器中取消注册。这可能会导致睡眠模式下的严重功耗,因此请记住进行大量测试。

可能有其他方法可以在此 HeadingView 和传感器之间执行通信,但我认为总的来说我的概念是很好的解决方案。


更新:

我想出了更好的主意,如何与此 HeadingView 进行通信,而不会检测到何时禁用传感器并且不会导致内存泄漏。答案是周参考或更确切地说是WeakHashMap

HeadingView 视图与我之前解释的差不多,但在构造函数中它会通知 YourActivity 它的存在。所以它会是这样的:

public class HeadingView extends View {

    public HeadingView(Context context) {
        super(context);

        YourActivity activity = (YourActivity) context;
        activity.addWeekSensorObserver(this);
    }
}

你的活动:

public class YourActivity extends Activity implements SensorEventListener {
    // there is no WeekSet and WeakHashMap is more handy then List<WeakReference>
    private final  WeakHashMap<HeadingView, Object> sensorObservers = new WeakHashMap<HeadingView, Object>();
    public void addWeekSensorObserver(HeadingView headingView) {
        sensorObservers.put(headingView, null);
    }

    private updateHeadings(float[] deviceHeading) {
        Set<HeadingView> keySet = sensorObservers.keySet();
        for (HeadingView headingView : keySet) {
            headingView.setDeviceHeading(deviceHeading);
        }
    }
}

活动中的标准传感器处理现在适用,因此检测何时禁用传感器不是问题,您不必担心内存泄漏。我怀疑即使您也不必大量更改代码:)。为了使它更好,您可以定义接口。

于 2012-07-12T14:29:47.730 回答