如何按用户位置最多的顺序显示列表RecyclerView?

问题描述

如何通过计算每个项目与位置和用户间的距离,来按用户位置最多(一个点)的顺序显示列表(RecyclerView)? 如您在代码中所见,浏览json时,我会计算距离,但是每次用户更改位置时,列表都会使用相同的数据递增

请注意:如果用户的位置发生变化,必须怎么做才能更新列表?

如图所示:

The image illustrates what I want to achieve

这是我的代码

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,locationListener);
                                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,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) {

           }
       };
   }

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...