如何按用户位置最多的顺序显示我的列表 (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) {

           }
       };
   }

为数组中的每个元素添加当前位置侦听器,并在同一列表中添加更新的标记对象,从而导致列表中出现重复标记并增加标记列表的大小