如何按用户位置最多的顺序显示我的列表 (RecyclerView)?
How can I display my list (RecyclerView) in order of the most user's location?
如何通过计算每个项目与位置和用户的距离,以最多用户位置(一个点)的顺序显示列表(RecyclerView)?
正如您在我的代码中看到的那样,在浏览 json 时,我计算了距离,但每次用户更改位置时,列表都会增加相同的数据
注意:如果用户位置发生变化,更新列表必须做什么?
如图所示:
这是我的代码:
private List<MarkerObj> markerObjList;
private void getStation() {
progressBar.setVisibility(View.VISIBLE);
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, API_XOIL.STATIONS_LIST, null,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
markerObjList = new ArrayList<>();
for (int i=0; i<response.length(); i++) {
try {
JSONObject jsonObject = response.getJSONObject(i);
MarkerObj markerObj = new MarkerObj(
jsonObject.getInt("id"),
jsonObject.getString("libele"),
jsonObject.getString("reference"),
jsonObject.getString("latitude"),
jsonObject.getString("longitude"),
jsonObject.getString("images"),
jsonObject.getString("alimentation"),
jsonObject.getString("wifi"),
jsonObject.getString("fastfood"),
jsonObject.getString("lavage"),
jsonObject.getString("entretien"));
/*markerObjList.add(markerObj);
NosStations.AdapterListeStations adapterListeStations = new NosStations.AdapterListeStations(getApplicationContext(), markerObjList);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setAdapter(adapterListeStations);
recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), LinearLayoutManager.VERTICAL));
recyclerView.setHasFixedSize(true);
adapterListeStations.notifyDataSetChanged();*/
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
int finalI = i;
LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
double latView = location.getLatitude();
double lonView = location.getLongitude();
try {
Location loc1 = new Location(markerObj.getName());
loc1.setLatitude(Double.parseDouble(markerObj.getLat()));
loc1.setLongitude(Double.parseDouble(markerObj.getLon()));
Location loc2 = new Location("");
loc2.setLatitude(latView);
loc2.setLongitude(lonView);
float distanceInMeters = loc1.distanceTo(loc2);
String distanceView = String.valueOf(distanceInMeters);
MarkerObj markerObj1 = new MarkerObj(
markerObj.getId(),
markerObj.getName(),
markerObj.getRef(),
markerObj.getLat(),
markerObj.getLon(),
markerObj.getImages(),
markerObj.getAlimentation(),
markerObj.getWifi(),
markerObj.getFastfood(),
markerObj.getLavage(),
markerObj.getEntretien(),
distanceView);
markerObjList.add(markerObj1);
NosStations.AdapterListeStations adapterListeStations = new NosStations.AdapterListeStations(getApplicationContext(), markerObjList);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setAdapter(adapterListeStations);
recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), LinearLayoutManager.VERTICAL));
recyclerView.setHasFixedSize(true);
adapterListeStations.notifyDataSetChanged();
progressBar.setVisibility(View.GONE);
}
catch (Exception e){
e.printStackTrace();
Log.e("error", e.toString());
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
return;
}
assert locationManager != null;
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30000, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 30000, 0, locationListener);
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (error instanceof NetworkError) {
progressBar.setVisibility(View.GONE);
getOfflineMarker();
Toast.makeText(getApplicationContext(), getString(R.string.volley_network_error), Toast.LENGTH_LONG).show();
}
else if (error instanceof ServerError) {
progressBar.setVisibility(View.GONE);
getOfflineMarker();
Toast.makeText(getApplicationContext(), getString(R.string.volley_server_error), Toast.LENGTH_LONG).show();
}
else if (error instanceof AuthFailureError) {
progressBar.setVisibility(View.GONE);
getOfflineMarker();
Toast.makeText(getApplicationContext(), getString(R.string.volley_authfail), Toast.LENGTH_LONG).show();
}
else if (error instanceof ParseError) {
progressBar.setVisibility(View.GONE);
getOfflineMarker();
Toast.makeText(getApplicationContext(), getString(R.string.volley_parse_error), Toast.LENGTH_LONG).show();
}
else if (error instanceof TimeoutError) {
progressBar.setVisibility(View.GONE);
getOfflineMarker();
Toast.makeText(getApplicationContext(), getString(R.string.volley_time_out_error), Toast.LENGTH_LONG).show();
}
}
});
VolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonArrayRequest);
}
您需要将 markerObjList 和位置变化侦听器的填充分开。在 'onResponse' 方法中仅填充 markerObject 列表。
在单独的方法中创建位置更改侦听器,比如视图的 onCreate,当触发位置侦听器时,重新计算所有标记对象的距离,根据更新的距离对列表进行排序,并将排序后的列表设置为适配器。代码看起来像这样
onCreate()
{
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
int finalI = i;
LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
double latView = location.getLatitude();
double lonView = location.getLongitude();
try {
ArrayList<> newMarkerObjList = new ArrayList<>();
int i = 0;
// recalcualte distances of all marker and add them in new list
for( i =0; i < markerObjList.size()){
MarkerObj markerObj = markerObjList[i]
Location loc1 = new Location(markerObj.getName());
loc1.setLatitude(Double.parseDouble(markerObj.getLat()));
loc1.setLongitude(Double.parseDouble(markerObj.getLon()));
Location loc2 = new Location("");
loc2.setLatitude(latView);
loc2.setLongitude(lonView);
float distanceInMeters = loc1.distanceTo(loc2);
String distanceView = String.valueOf(distanceInMeters);
MarkerObj markerObj1 = new MarkerObj(
markerObj.getId(),
markerObj.getName(),
markerObj.getRef(),
markerObj.getLat(),
markerObj.getLon(),
markerObj.getImages(),
markerObj.getAlimentation(),
markerObj.getWifi(),
markerObj.getFastfood(),
markerObj.getLavage(),
markerObj.getEntretien(),
distanceInMeters,
distanceView);
newMarkerObjList.add(markerObj1);
}
// create a predicate for sorting based on 'distanceInMeters';
Collections.sort( newMarkerObjList);
markerObjList = newMarkerObjList;
// and set this new list to the adapter;
NosStations.AdapterListeStations adapterListeStations = new NosStations.AdapterListeStations(getApplicationContext(), markerObjList);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setAdapter(adapterListeStations);
recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), LinearLayoutManager.VERTICAL));
recyclerView.setHasFixedSize(true);
adapterListeStations.notifyDataSetChanged();
progressBar.setVisibility(View.GONE);
}
catch (Exception e){
e.printStackTrace();
Log.e("error", e.toString());
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
}
为数组中的每个元素添加当前位置侦听器,并在同一列表中添加更新的标记对象,从而导致列表中出现重复标记并增加标记列表的大小
如何通过计算每个项目与位置和用户的距离,以最多用户位置(一个点)的顺序显示列表(RecyclerView)? 正如您在我的代码中看到的那样,在浏览 json 时,我计算了距离,但每次用户更改位置时,列表都会增加相同的数据
注意:如果用户位置发生变化,更新列表必须做什么?
如图所示:
这是我的代码:
private List<MarkerObj> markerObjList;
private void getStation() {
progressBar.setVisibility(View.VISIBLE);
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, API_XOIL.STATIONS_LIST, null,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
markerObjList = new ArrayList<>();
for (int i=0; i<response.length(); i++) {
try {
JSONObject jsonObject = response.getJSONObject(i);
MarkerObj markerObj = new MarkerObj(
jsonObject.getInt("id"),
jsonObject.getString("libele"),
jsonObject.getString("reference"),
jsonObject.getString("latitude"),
jsonObject.getString("longitude"),
jsonObject.getString("images"),
jsonObject.getString("alimentation"),
jsonObject.getString("wifi"),
jsonObject.getString("fastfood"),
jsonObject.getString("lavage"),
jsonObject.getString("entretien"));
/*markerObjList.add(markerObj);
NosStations.AdapterListeStations adapterListeStations = new NosStations.AdapterListeStations(getApplicationContext(), markerObjList);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setAdapter(adapterListeStations);
recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), LinearLayoutManager.VERTICAL));
recyclerView.setHasFixedSize(true);
adapterListeStations.notifyDataSetChanged();*/
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
int finalI = i;
LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
double latView = location.getLatitude();
double lonView = location.getLongitude();
try {
Location loc1 = new Location(markerObj.getName());
loc1.setLatitude(Double.parseDouble(markerObj.getLat()));
loc1.setLongitude(Double.parseDouble(markerObj.getLon()));
Location loc2 = new Location("");
loc2.setLatitude(latView);
loc2.setLongitude(lonView);
float distanceInMeters = loc1.distanceTo(loc2);
String distanceView = String.valueOf(distanceInMeters);
MarkerObj markerObj1 = new MarkerObj(
markerObj.getId(),
markerObj.getName(),
markerObj.getRef(),
markerObj.getLat(),
markerObj.getLon(),
markerObj.getImages(),
markerObj.getAlimentation(),
markerObj.getWifi(),
markerObj.getFastfood(),
markerObj.getLavage(),
markerObj.getEntretien(),
distanceView);
markerObjList.add(markerObj1);
NosStations.AdapterListeStations adapterListeStations = new NosStations.AdapterListeStations(getApplicationContext(), markerObjList);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setAdapter(adapterListeStations);
recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), LinearLayoutManager.VERTICAL));
recyclerView.setHasFixedSize(true);
adapterListeStations.notifyDataSetChanged();
progressBar.setVisibility(View.GONE);
}
catch (Exception e){
e.printStackTrace();
Log.e("error", e.toString());
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
return;
}
assert locationManager != null;
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30000, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 30000, 0, locationListener);
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (error instanceof NetworkError) {
progressBar.setVisibility(View.GONE);
getOfflineMarker();
Toast.makeText(getApplicationContext(), getString(R.string.volley_network_error), Toast.LENGTH_LONG).show();
}
else if (error instanceof ServerError) {
progressBar.setVisibility(View.GONE);
getOfflineMarker();
Toast.makeText(getApplicationContext(), getString(R.string.volley_server_error), Toast.LENGTH_LONG).show();
}
else if (error instanceof AuthFailureError) {
progressBar.setVisibility(View.GONE);
getOfflineMarker();
Toast.makeText(getApplicationContext(), getString(R.string.volley_authfail), Toast.LENGTH_LONG).show();
}
else if (error instanceof ParseError) {
progressBar.setVisibility(View.GONE);
getOfflineMarker();
Toast.makeText(getApplicationContext(), getString(R.string.volley_parse_error), Toast.LENGTH_LONG).show();
}
else if (error instanceof TimeoutError) {
progressBar.setVisibility(View.GONE);
getOfflineMarker();
Toast.makeText(getApplicationContext(), getString(R.string.volley_time_out_error), Toast.LENGTH_LONG).show();
}
}
});
VolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonArrayRequest);
}
您需要将 markerObjList 和位置变化侦听器的填充分开。在 'onResponse' 方法中仅填充 markerObject 列表。
在单独的方法中创建位置更改侦听器,比如视图的 onCreate,当触发位置侦听器时,重新计算所有标记对象的距离,根据更新的距离对列表进行排序,并将排序后的列表设置为适配器。代码看起来像这样
onCreate()
{
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
int finalI = i;
LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
double latView = location.getLatitude();
double lonView = location.getLongitude();
try {
ArrayList<> newMarkerObjList = new ArrayList<>();
int i = 0;
// recalcualte distances of all marker and add them in new list
for( i =0; i < markerObjList.size()){
MarkerObj markerObj = markerObjList[i]
Location loc1 = new Location(markerObj.getName());
loc1.setLatitude(Double.parseDouble(markerObj.getLat()));
loc1.setLongitude(Double.parseDouble(markerObj.getLon()));
Location loc2 = new Location("");
loc2.setLatitude(latView);
loc2.setLongitude(lonView);
float distanceInMeters = loc1.distanceTo(loc2);
String distanceView = String.valueOf(distanceInMeters);
MarkerObj markerObj1 = new MarkerObj(
markerObj.getId(),
markerObj.getName(),
markerObj.getRef(),
markerObj.getLat(),
markerObj.getLon(),
markerObj.getImages(),
markerObj.getAlimentation(),
markerObj.getWifi(),
markerObj.getFastfood(),
markerObj.getLavage(),
markerObj.getEntretien(),
distanceInMeters,
distanceView);
newMarkerObjList.add(markerObj1);
}
// create a predicate for sorting based on 'distanceInMeters';
Collections.sort( newMarkerObjList);
markerObjList = newMarkerObjList;
// and set this new list to the adapter;
NosStations.AdapterListeStations adapterListeStations = new NosStations.AdapterListeStations(getApplicationContext(), markerObjList);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setAdapter(adapterListeStations);
recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), LinearLayoutManager.VERTICAL));
recyclerView.setHasFixedSize(true);
adapterListeStations.notifyDataSetChanged();
progressBar.setVisibility(View.GONE);
}
catch (Exception e){
e.printStackTrace();
Log.e("error", e.toString());
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
}
为数组中的每个元素添加当前位置侦听器,并在同一列表中添加更新的标记对象,从而导致列表中出现重复标记并增加标记列表的大小