我一直试图在地图上显示指南针和我的位置与另一个位置之间的距离。
几乎完全像:
Android: compass + distance in a listview
我理解了代码,设置了一个用于检测方向变化的监听器,并且还计算了距离。
此外,我在ListView中显示正确的距离(我已经有一个自定义适配器)。这有点澄清我在哪里。
这是我的问题:我每秒通过监听器更新ListView,通过更改适配器正在查看的实际列表的值并调用:
notifyDataSetChanged();
每隔一秒调用就会使ListView变得迟钝,就像我预期的那样。我可以每10秒左右更新一次距离(或者更多一点)。但是,我必须更频繁地更新列表以获得实时指南针。我一直在四处寻找,我真的找不到任何东西,我会感激所有的帮助。谢谢!
旁注:如果您需要查看我编写的任何代码,我愿意将其粘贴到此处。它有很多部分,所以我会按需提供。
答案 0 :(得分:1)
恕我直言,你应该省略整个列表视图和适配器。最好的方法是为应该经常更新的元素创建自己的视图。
例如创建名为HeadingView的视图,它将具有setAbsouluteheading。适配器将使用此setter。然后视图还将实现SensorEventListener以观察传感器并获取设备标题。 当相对方向改变时,HeadingView会自行更新它。在这种情况下的问题是当HeadingView应该为传感器事件注册/取消注册时检测。 onWindowFocusChanged看起来很有前途,onWindowSystemUiVisibilityChanged(API级别16)就是您所需要的。
请记住,存在一些危险,即可能存在一些极端情况,并且您的视图不会在应该观察传感器时取消注册。这可能会导致睡眠模式下的功耗非常大,所以请记住进行大量测试。
可能有其他方法可以在此HeadingView和传感器之间进行通信,但我认为通常我的概念是很好的解决方案。
我已经想出了如何与此HeadingView进行通信而没有问题,可以检测何时禁用传感器并且不会导致内存泄漏。答案是week reference或更准确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);
}
}
}
活动中的标准传感器处理现在适用,因此检测何时禁用传感器不是问题,您不必担心内存泄漏。我怀疑即使你不必更改代码:)。 为了使它更好,你可以定义接口。