ListView适配器的行为不符合预期

时间:2015-12-22 03:06:43

标签: android listview android-listview

我遇到的问题让我发疯了。我之前用相同代码制作的每个适配器都能很好地工作,但是这个适配器并不适用。调用.notifyDataSetChanged()不会工作,它只需要调用getView()一次,不管List有多少项。

总结:当我调用.notifyDataSetChanged()并且它只调用一次getView()时,适配器不会刷新列表视图。

适配器代码:

public class ObstacleListAdapter extends BaseAdapter {

private Activity activity;
private LayoutInflater inflater;
private List<Obstacle> feedItems;

public ObstacleListAdapter(Activity activity, List<Obstacle> feedItems) {
    this.activity = activity;
    this.feedItems = feedItems;
}

@Override
public int getCount() {
    return feedItems.size();
}

@Override
public Object getItem(int location) {
    return feedItems.get(location);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    if (inflater == null)
        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (convertView == null)
        convertView = inflater.inflate(R.layout.obstacle_list_row, null);


    TextView text = (TextView) convertView.findViewById(R.id.obstacle_text);

    Obstacle obstacle = feedItems.get(position);

    text.setText(obstacle.getName()+" à "+
            calculationByDistance(MapsActivity.MY_LOC,new LatLng(obstacle.getLatitude(),obstacle.getLongitude()))+" metros");


    return convertView;
}

public double calculationByDistance(LatLng StartP, LatLng EndP) {
    int Radius = 6371;// radius of earth in Km
    double lat1 = StartP.latitude;
    double lat2 = EndP.latitude;
    double lon1 = StartP.longitude;
    double lon2 = EndP.longitude;
    double dLat = Math.toRadians(lat2 - lat1);
    double dLon = Math.toRadians(lon2 - lon1);
    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
            + Math.cos(Math.toRadians(lat1))
            * Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2)
            * Math.sin(dLon / 2);
    double c = 2 * Math.asin(Math.sqrt(a));
    double valueResult = Radius * c;
    double km = valueResult / 1;
    DecimalFormat newFormat = new DecimalFormat("####");
    int kmInDec = Integer.valueOf(newFormat.format(km));
    double meter = valueResult % 1000;
    int meterInDec = Integer.valueOf(newFormat.format(meter));
    Log.i("Radius Value", "" + valueResult + "   KM  " + kmInDec
            + " Meter   " + meterInDec);

    return kmInDec*1000;
}

活动代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    ctx = this;
    dbOperations = new DatabaseOperations(ctx);

    listView = (ListView) findViewById(R.id.list_item);
    adapter = new ObstacleListAdapter(this, obstacleList);
    listView.setAdapter(adapter);
}


@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    mMap.setMyLocationEnabled(true);
    mMap.getUiSettings().setZoomControlsEnabled(true);

    obstacleList = dbOperations.listAllObstacles();
    for(int i=0;i<obstacleList.size();i++){
        LatLng marker = new LatLng(obstacleList.get(i).getLatitude(), obstacleList.get(i).getLongitude());
        mMap.addMarker(new MarkerOptions().position(marker).title(obstacleList.get(i).getName()));
    }

    mMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {

        @Override
        public void onMyLocationChange(Location location) {

            //mMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude())));
            //CameraUpdate center =
            //      CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 20);

            //mMap.moveCamera(center);
            MY_LOC = new LatLng(location.getLatitude(), location.getLongitude());
            obstacleList.clear();
            obstacleList = dbOperations.listAllObstacles();
            adapter.notifyDataSetChanged();

        }
    });

    setMapIfNeeded();

}

2 个答案:

答案 0 :(得分:1)

问题在于您的活动:

obstacleList.clear();
obstacleList = dbOperations.listAllObstacles();

你实际上是在将障碍列表更改为这个新列表(它不会传播到列表适配器。

相反,你应该做的是:

obstacleList.clear()
obstacleList.addAll(dbOperations.listAllObstacles());

答案 1 :(得分:-1)

将您的扩展类更改为ArrayAdapter<Obstacle>