【问题标题】:update UI when a variable from other Classes is changed更改其他类的变量时更新 UI
【发布时间】:2016-04-22 12:06:10
【问题描述】:

我有一个使用 GPS-Tracker 的离线地图应用程序。我的主要目标是感知纬度和经度的变化并更新TextView
我的GPS-Tracker 类实现如下:

public class GPSTracker extends Service implements LocationListener {

    ...

    public GPSTracker(Context context) {
        ...
        getLocation();
    }

    public Location getLocation() {
        // returns Location
    }

    @Override
    public void onLocationChanged(Location location) {
        // Method 1: update UI elements (textview) directly 
        MainActivity.tvGPS.setText("lat: " + Double.toString(location.getLatitude()) + "lon: " + Double.toString(location.getLongitude());

        // Method 2: call a method from MainActivity which updates UI
        MainActivity.setNewPosition(location.getLatitude() , location.getLatitude());

        // Method 3: sense changes in Latitude and Longitude directly in MainActivity and update UI
    }
}

问题:
如何直接感知经纬度的变化(MainActivity)并修改 UI。
我到目前为止测试的内容:

  • 来自 GPSTracker/onLocationChanged 的​​ UI 更新(如代码中的方法 1 和 2):它有效,但不是来自 MainActivity
  • 使用LocalBroacastManager 提到here 但它需要不断检查位置以检测更改
  • 使用Observer Pattern 提到的here:更改仅在Observer 中有效@ 类不在MainActivity
  • 【问题讨论】:

    标签: android


    【解决方案1】:

    您可以将MainActivity 作为参数传递给GPSTracker 的构造函数。

    private TextView tvGPS;
    
    public GPSTracker(Activity a) {
          ...
          tvGPS = (TextView)a.findViewById(R.id.tvGPS); // whatever ID
    }
    

    然后你可以直接在onLocationChanged中更改文字。

    @Override
    public void onLocationChanged(Location location) {
        tvGPS.setText("lat: " + Double.toString(location.getLatitude()) + "lon: " + Double.toString(location.getLongitude());
    }
    

    【讨论】:

    • 它与定义可从其他类访问的公共 TextView 或多或少相同吗?这个概念会增加复杂性,尤其是当需要从多个类更新 UI 时。
    【解决方案2】:

    请不要将 Activity 实例传递给使用静态方法的跟踪器!这是非常糟糕的做法!

    您可以使用事件总线。 http://square.github.io/otto/

    创建一个总线供应商:

    public class BusProvider {
        private static final Bus BUS = new Bus(ThreadEnforcer.ANY);
    
        public static Bus getInstance() {
            return BUS;
        }
    
        private BusProvider() {
            // No instances.
        }
    }
    

    创建总线事件:

         public class LocationChangedEvent{
    
        private Location location;
    
          private Location location;
    
            public LocationChangedEvent(Location location) {
                this.location = location;
            }
    
            public Location getLocation() {
                return location;
            }
    
            public void setLocation(Location location) {
                this.location = location;
            }
     }
    
    
    
    public class GPSTracker extends Service implements LocationListener {
    
            ...
    
        public GPSTracker(Context context) {
            ...
            getLocation(); 
        }
    
        public Location getLocation() {
            // returns Location
        }
    
        @Override
        public void onLocationChanged(Location location) {
           new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        BusProvider.getInstance().post(new LocationChangedEvent(location));
                    }
                });
        }
    }   
    

    在您的活动中:

     @Subscribe
        public void onLocationUpdated(LocationChangedEvent locationChangedEvent){
            //TODO update ui as you need
    
        }
    

    别忘了注册/注销总线

    【讨论】:

      猜你喜欢
      • 2015-01-17
      • 1970-01-01
      • 1970-01-01
      • 2021-02-26
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多