【问题标题】:Fetch data using volley and display in Google Maps使用 volley 获取数据并在 Google Maps 中显示
【发布时间】:2017-12-28 07:05:45
【问题描述】:

这是我第一次在 Android 中使用 Google Maps。我能够创建显示one marker 的地图。这对我来说是一个好的开始。但是,我想显示multiple markers。为此,我使用volley 从数据库中获取位置。但是,我遇到了一个问题,一个我以前遇到过的问题,但是我设法解决了这个问题,现在它在我当前的项目中再次浮出水面,即我喜欢在我的应用程序中使用Singletons 来存储数据,只要应用程序在内存中。例如,我的singleton 可以保存array list of objects,我可以在任何活动/片段中随时随地获取数组列表。但是,我需要在activity/fragment 变为活动状态之前在我的singleton 中填充arraylist 并访问onCreate/onCreateView 中的对象的arraylist,但似乎activity/fragment 加载速度非常快并且对@987654334 的引用来自singleton 的@ 始终是null。在我目前的项目中:

这是处理所有位置的singleton class

public class PointOfInterestLab {
    private ArrayList<PointOfInterest> mPointOfInterests;
    private static PointOfInterestLab sPointOfInterestLab;
    private Context mAppContext;

    private PointOfInterestLab(Context appContext){
        mAppContext = appContext;
        mPointOfInterests = new ArrayList<PointOfInterest>();

    }

    public static PointOfInterestLab get(Context c){
        if(sPointOfInterestLab == null){
            sPointOfInterestLab = new PointOfInterestLab(c.getApplicationContext());
        }

        return sPointOfInterestLab;

    }

    public ArrayList<PointOfInterest> getPointOfInterests(){
        return mPointOfInterests;

    }

    public PointOfInterest getPointOfInterest(int id){
        for(PointOfInterest pointOfInterest: mPointOfInterests){
            if(pointOfInterest.getID() == id){
                return pointOfInterest;
            }
        }

        return null;

    }

    public void addPointOfInterest(PointOfInterest pointOfInterest){
        mPointOfInterests.add(pointOfInterest);
    }

    public void clearPointOfInterests(){
        mPointOfInterests.clear();
    }

    public void deletePointOfInterest(PointOfInterest pointOfInterest){
        mPointOfInterests.remove(pointOfInterest);

    }
}

在我要显示位置的片段中:

public class PointOfInterestMapFragment extends Fragment implements OnMapReadyCallback {
    private static final String TAG = PointOfInterestMapFragment.class.getSimpleName();
    private GoogleMap mGoogleMap;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        //get locations from server
        getPOISFromDB();
    }//end method onCreate

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle saveInstanceState){

        View v = inflater.inflate(R.layout.fragment_poi_map, parent, false);

        //obtain the support fragment and get notified when the map is ready
        SupportMapFragment mapFragment = (SupportMapFragment)getChildFragmentManager()
                .findFragmentById(R.id.map);
        //pass fragment in getMapAsync handler
        mapFragment.getMapAsync(this);

        return v;
    }//end method onCreateView

    @Override
    public void onMapReady(GoogleMap googleMap){
        mGoogleMap = googleMap;

        ArrayList<PointOfInterest> pointOfInterests;
        pointOfInterests = PointOfInterestLab.get(getActivity())
                .getPointOfInterests();
        for(PointOfInterest pointOfInterest : pointOfInterests){
            //add marker and move camera
            /*LatLng location = new LatLng(pointOfInterest.getLocation().getLatitude()
                    , pointOfInterest.getLocation().getLongitude());
            mGoogleMap.addMarker(new MarkerOptions()
                    .position(location)
                    .title(pointOfInterest.getName()));
            mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(location));*/
           Log.d(TAG, pointOfInterest.getName());
        }
        /*This is just for debugging, it is returning a null object
        Meaning by the time the array list of the singleton class
       is being populated this has been called I guess*/
        PointOfInterest pointOfInterest = PointOfInterestLab.get(getActivity()).getPointOfInterest(3);

        LatLng location = new LatLng(pointOfInterest.getLocation().getLatitude(),pointOfInterest.getLocation().getLongitude());
        mGoogleMap.addMarker(new MarkerOptions()
                .position(location)
                .title("location"));
        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(location));

    }
    //Get locations from db
    private  void getPOISFromDB(){
        // Tag used to cancel the request
        String tag_string_req = "req_poi_list";

        StringRequest strReq = new StringRequest(Request.Method.POST,
                AppConfig.URL_POI_LIST, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Response: " + response);

                try {
                    JSONObject jObj = new JSONObject(response);
                    JSONArray jsonArray = jObj.getJSONArray("pois");
                    PointOfInterestLab.get(getActivity()).clearPointOfInterests();

                    for(int i=0; i < jsonArray.length(); i++){
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        int id = jsonObject.getInt("poi_id");
                        String name = jsonObject.getString("name");
                        String summary = jsonObject.getString("summary");
                        double latitude =  jsonObject.getDouble("latitude");
                        double longitude = jsonObject.getDouble("longitude");
                        Location location = new Location("dummyProvider");
                        location.setLatitude(latitude);
                        location.setLongitude(longitude);

                        PointOfInterest pointOfInterest = new PointOfInterest(id, name, summary
                                , location);
                        PointOfInterestLab.get(getActivity()).addPointOfInterest(pointOfInterest);

                    }

                } catch (JSONException e) {
                    Log.e(TAG, e.getMessage());
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Server error: " + error.getMessage());

            }
        }) {

            @Override
            protected Map<String, String> getParams() {

                Map<String, String> params = new HashMap<String, String>();

                SQLiteHandler sqLiteHandler = new SQLiteHandler(getActivity());
                User user = sqLiteHandler.getUserDetails();
                params.put("user_id", user.getUserID());
                return params;
            }

        };

        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);

    }//end method getPOISFromDB

}//end class

这是我现在用来测试的部分代码。我在LatLng location = new LatLng(pointOfInterest.getLocation().getLatitude(),pointOfInterest.getLocation().getLongitude()); 在线收到错误PointOfInterest.getLocation()' on a null object reference

 /*This is just for debugging, it is returning a null object
   Meaning by the time the array list of the singleton class
   is being populated this has been called I guess*/

            PointOfInterest pointOfInterest = PointOfInterestLab.get(getActivity()).getPointOfInterest(3);

            LatLng location = new LatLng(pointOfInterest.getLocation().getLatitude(),pointOfInterest.getLocation().getLongitude());
            mGoogleMap.addMarker(new MarkerOptions()
                    .position(location)
                    .title("location"));
            mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(location));

我也尝试在托管活动的onCreate 方法中调用数据库api,但似乎不起作用

public class MainActivity extends AppCompatActivity {
    ......

    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, "onCreate");
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_pedometer);

        Toolbar toolbar  = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        User user = new User();
        user.checkLogin(MainActivity.this);

        tabLayout = (TabLayout)findViewById(R.id.tabs);
        viewPager = (ViewPager)findViewById(R.id.viewpager);
        viewPager.setAdapter(new MyAdapter(getSupportFragmentManager()));
        viewPager.setOffscreenPageLimit(2);

        //runnable to get rid of bug
        tabLayout.post(new Runnable() {
            @Override
            public void run() {
                tabLayout.setupWithViewPager(viewPager);
            }
        });

        setTitle("Updates");
        //get locations from db
        getPOISFromDB();
    }//end method onCreate

    private class MyAdapter extends FragmentStatePagerAdapter {

        private MyAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position)
        {
            switch (position){
                case 0 :
                    return new FirstFragment();
                case 1 :
                   eturn new SecondFragment();

                case 2 :
                    return new PointOfInterestMapFragment();

            }
            return null;
        }

        @Override
        public int getCount() {

            return 3;

        }

        /**
         * This method returns the title of the tab according to the position.
         */

        @Override
        public CharSequence getPageTitle(int position) {

            switch (position){
                case 0 :
                    return getResources().getString(R.string.fragment_1);
                case 1 :
                    return getResources().getString(R.string.fragment_2);
                case 2 :
                    return getResources().getString(R.string.fragment_3);

            }
            return null;
        }

    }//end class MyAdapter  

    private  void getPOISFromDB(){
        // Tag used to cancel the request
        String tag_string_req = "req_poi_list";

        StringRequest strReq = new StringRequest(Request.Method.POST,
                AppConfig.URL_POI_LIST, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Response: " + response);

                try {
                    JSONObject jObj = new JSONObject(response);
                    JSONArray jsonArray = jObj.getJSONArray("pois");
                    PointOfInterestLab.get(AppController.getInstance()).clearPointOfInterests();

                    for(int i=0; i < jsonArray.length(); i++){
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        int id = jsonObject.getInt("poi_id");
                        String name = jsonObject.getString("name");
                        String summary = jsonObject.getString("summary");
                        double latitude =  jsonObject.getDouble("latitude");
                        double longitude = jsonObject.getDouble("longitude");
                        Location location = new Location("dummyProvider");
                        location.setLatitude(latitude);
                        location.setLongitude(longitude);

                        PointOfInterest pointOfInterest = new PointOfInterest(id, name, summary
                                , location);
                        PointOfInterestLab.get(AppController.getInstance()).addPointOfInterest(pointOfInterest);

                    }

                } catch (JSONException e) {
                    Log.e(TAG, e.getMessage());
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Server error: " + error.getMessage());

            }
        }) {

            @Override
            protected Map<String, String> getParams() {

                Map<String, String> params = new HashMap<String, String>();

                SQLiteHandler sqLiteHandler = new SQLiteHandler(AppController.getInstance());
                User user = sqLiteHandler.getUserDetails();
                params.put("user_id", user.getUserID());
                return params;
            }

        };

        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);

    }//end method getPOISFromDB
}

如何在 onMapReady 方法中显示标记,即在 onMapReady 方法执行之前填充单例?

【问题讨论】:

  • 你可以在activity中调用数据库api调用并存储在我们的singleton类中。之后你就可以启动fragment了。否则在片段中调用 api,然后在获取数据时初始化地图。
  • 创建一个在 googleMap 对象上创建标记的函数。因此,在获得成功响应后,您可以创建此功能编号。您的对象具有 LatLong 的时间
  • @Soham 在活动的 onCreate 方法中还是?
  • 是的,onCreate。 @促进者。
  • 在得到 api 的响应后设置你的适配器viewPager.setAdapter(new MyAdapter(getSupportFragmentManager()));。您正在初始化适配器,这就是您收到空指针异常的原因。

标签: android google-maps android-fragments android-volley


【解决方案1】:

感谢@soham,我更改为在 api 响应后初始化我的适配器。在onCreate中删除了MainActivity中的这行代码

@Override
    public void onCreate(Bundle savedInstanceState) {
        ......

        viewPager.setAdapter(new MyAdapter(getSupportFragmentManager()));

        .......
}

把它放在方法getPOISFromDB()

......

@Override
            public void onResponse(String response) {
                Log.d(TAG, "Response: " + response);

                try {
                    JSONObject jObj = new JSONObject(response);
                    JSONArray jsonArray = jObj.getJSONArray("pois");
                    PointOfInterestLab.get(AppController.getInstance()).clearPointOfInterests();

                    for(int i=0; i < jsonArray.length(); i++){
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        int id = jsonObject.getInt("poi_id");
                        String name = jsonObject.getString("name");
                        String summary = jsonObject.getString("summary");
                        double latitude =  jsonObject.getDouble("latitude");
                        double longitude = jsonObject.getDouble("longitude");
                        Location location = new Location("dummyProvider");
                        location.setLatitude(latitude);
                        location.setLongitude(longitude);

                        PointOfInterest pointOfInterest = new PointOfInterest(id, name, summary
                                , location);
                        PointOfInterestLab.get(AppController.getInstance()).addPointOfInterest(pointOfInterest);

                    }

                } catch (JSONException e) {
                    Log.e(TAG, e.getMessage());
                }

                viewPager.setAdapter(new MyAdapter(getSupportFragmentManager()));

            }

 .....

【讨论】:

    猜你喜欢
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多