按最近的位置对Listview排序

时间:2015-04-12 10:45:48

标签: android sorting listview gps distance

我从网上获取我的JSON数据。对于许多物体,其中之一是纬度和经度。我可以计算确切的距离但是..

如何对列表视图进行排序以首先显示最近的位置。

MainActivity

public class MainActivity extends ActionBarActivity {

    private ListView lv_nearestShops;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        GPSTracker gps;

        this.lv_nearestShops = (ListView) this.findViewById(R.id.lv_nearestShops);

        gps = new GPSTracker(MainActivity.this);

        if(gps.canGetLocation()) {
            double latitude = gps.getLatitude();
            double longitude = gps.getLongtitude();

            Log.d("Location = ", "Latitude: " + latitude + " - Longitude : " + longitude);
        }

        new GetAllShopsTask().execute(new ApiConnector());


    }

    public void setListAdapter(JSONArray jsonArray){

        this.lv_nearestShops.setAdapter(new lv_nearestShops_adapter(jsonArray, this));
    }

    private class GetAllShopsTask extends AsyncTask<ApiConnector,Long,JSONArray>
    {
        @Override
        protected JSONArray doInBackground(ApiConnector... params) {
            return params[0].GetAllShops();
        }

        @Override
        protected void onPostExecute(JSONArray jsonArray) {
            setListAdapter(jsonArray);

        }
    }


}

ApiConnector

public class ApiConnector {

    public JSONArray GetAllShops() {
        String url = ""; //php script

        HttpEntity httpEntity = null;

        try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);

            HttpResponse httpResponse = httpClient.execute(httpGet);

            httpEntity = httpResponse.getEntity();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        JSONArray jsonArray = null;
        if (httpEntity != null) {
            try {
                String entityResponse = EntityUtils.toString(httpEntity);

                Log.e("Entity Response : ", entityResponse);

                jsonArray = new JSONArray(entityResponse);

            } catch (JSONException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return jsonArray;
    }
}

listview适配器

public class lv_nearestShops_adapter extends BaseAdapter {

    private JSONArray dataArray;
    private Activity activity;

    double latA;
    double lngA;
    double latB;
    double lngB;

    private static LayoutInflater inflater = null;

    public lv_nearestShops_adapter(JSONArray jsonArray, Activity a)
    {
        this.dataArray = jsonArray;
        this.activity = a;

        inflater = (LayoutInflater) this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return this.dataArray.length();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

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

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

        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.lv_nearestshop_layout, null);
            viewHolder = new ViewHolder();

            viewHolder.name = (TextView) convertView.findViewById(R.id.itemName);
            viewHolder.street = (TextView) convertView.findViewById(R.id.itemStreet);
            viewHolder.distance = (TextView) convertView.findViewById(R.id.itemDistance);

            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        try {
            JSONObject jsonObject = this.dataArray.getJSONObject(position);

            // naam
            viewHolder.name.setText(jsonObject.getString("name"));
            // street
            viewHolder.street.setText(jsonObject.getString("street"));

            // distance

            latB = jsonObject.getDouble("latitude");
            lngB = jsonObject.getDouble("longitude");

            float distance;

            GPSTracker gps;

            Context context = parent.getContext();
            gps = new GPSTracker(context);

            if(gps.canGetLocation()) {
                latA = gps.getLatitude();
                lngA = gps.getLongtitude();

                Log.e("Location = ", "Latitude: " + latA + " - Longitude : " + lngA);
            }

            Location locationA = new Location("point A");
            locationA.setLatitude(latA);
            locationA.setLongitude(lngA);
            Location locationB = new Location("point B");
            locationB.setLatitude(latB);
            locationB.setLongitude(lngB);
            distance = locationA.distanceTo(locationB);

            int iDistance= (int) distance;

            if(iDistance > 1000) {
                int result = iDistance / 1000;
                viewHolder.distance.setText(String.valueOf(result) + " km");
            } else {
                viewHolder.distance.setText(String.valueOf(iDistance) + " m");
            }

            jsonObject.put("distance", iDistance);


        }
        catch (JSONException e) {
            e.printStackTrace();
        }


        return convertView;
    }

    private class ViewHolder{
        private TextView name;
        private TextView street;
        private TextView distance;
    }

}

2 个答案:

答案 0 :(得分:1)

一种方法是将JSON数组转换为包含JSON对象内容的包装类的标准ArrayList。 e.g

class Location
{
    JSONObject jsonObject;

    public Location(JSONObject jsonObj)
    {
        this.jsonObject = jsonObj
    }

    long getLongitude()
    {
        // get longitude value from json object
    }

    long getLatitude()
    {
        // get latitude value from json object
    }


    // .. any other info
}


List<Location> locationList = new ArrayList<Location>(); 

创建一个Comparator类,使用存储在Location类中的经度和纬度,按距离到当前位置对此列表进行排序。然后Collection.sort(list,yourComparator)将为您排序列表。

将列表视图更改为使用locationList对象。

答案 1 :(得分:0)

您可以计算用户位置和传入的lat-long json数据之间的距离,如:

function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
 var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2-lat1);  // deg2rad below
  var dLon = deg2rad(lon2-lon1); 
  var a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * 
    Math.sin(dLon/2) * Math.sin(dLon/2)
    ; 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  var d = R * c; // Distance in km
  return d;
}

然后,您可以将距离存储在数组中并对数组进行排序。在listview中显示已排序的数据。

Courtesy