我一直试图显示一个指南针以及我的位置与地图上另一个位置之间的距离。
几乎完全一样:
Android: compass + distance in a listview
我了解了代码,设置了一个侦听器来检测方向变化,还计算了距离。
此外,我在ListView中显示了正确的距离(我已经有一个自定义适配器)。那是关于我在哪里的一点澄清。
这是我的问题:我通过更改适配器正在查看的实际列表的值并调用来通过侦听器每秒更新ListView:
notifyDataSetChanged();
就像我所期望的那样,每秒调用一次会使ListView变慢。我可以每10秒钟左右(或更短的时间)更新一次距离。但是,我必须更频繁地更新列表,才能同时使用实时指南针。我一直在环顾四周,却找不到任何东西,我将不胜感激。谢谢!
旁注:如果您需要查看我编写的任何代码,我愿意将其粘贴在此处。它有很多部分,因此我将按需进行。
最佳答案
恕我直言,您应该忽略整个列表视图和适配器。最好的方法是为应该经常更新的元素创建自己的视图。
例如,创建名为HeadingView的视图,该视图将具有setAbsouluteheading。该设置器将由适配器使用。然后,视图还将实现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);
}
}
}
现在适用于活动中的标准传感器处理,因此检测何时禁用传感器不是问题,并且您不必担心内存泄漏。我怀疑即使您也不必大量修改代码:)。
为了使它更好,您可以定义接口。