【问题标题】:Can I add a marker to an ArrayList and a HashMap at the same time?我可以同时向 ArrayList 和 HashMap 添加标记吗?
【发布时间】:2016-09-04 00:29:35
【问题描述】:

我的代码完全按照我的意愿工作。我的意思是我有一个显示 5 个标记类别的地图片段,我可以按类别过滤它们,一切正常。您可能会观察到标记 1 和标记 8 将出现在多个类别中。这是代码,之后我将继续我的问题:

        Boolean mSetCameraPosition;
        Boolean checkBox1Checked, checkBox2Checked, checkBox3Checked,     checkBox4Checked, checkBox5Checked;
        private int mapTypeSelected;
        CheckBox cbAllDay, cbBefore12, cbBetween1216, cbBetween1620, ccbAfter20;
        AlertDialog dialog;
        List<Marker> firstCategoryList = new ArrayList<>();
        List<Marker> secondCategoryList = new ArrayList<>();
        List<Marker> thirdCategoryList = new ArrayList<>();
        List<Marker> fourthCategoryList = new ArrayList<>();
        List<Marker> fifthCategoryList = new ArrayList<>();


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


        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            checkLocationPermission();
        }


        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);


        if (savedInstanceState == null) {
            mapTypeSelected = GoogleMap.MAP_TYPE_NORMAL;
            mSetCameraPosition = true;

        } else {
            mapTypeSelected = savedInstanceState.getInt("the_map_type", GoogleMap.MAP_TYPE_NORMAL);
            mSetCameraPosition = false;



  @Override
    public void onMapReady(GoogleMap googleMap) {

        mMap = googleMap;
        if (mSetCameraPosition) {
            initialLocation(TOULOUSE_LAT, TOULOUSE_LNG, 12);

        }
        mMap.setMapType(mapTypeSelected);

 if (initialMarkers) {
            addMarkers2Map();
        }

  public void addMarkers2Map() {

        // Markers location

        LatLng marker1 = new LatLng(43.607044, 1.450307);
        LatLng marker2= new LatLng(43.571505, 1.417759);
        LatLng marker3= new LatLng(43.607469, 1.447162);
        LatLng marker4= new LatLng(43.600723, 1.455917);
        LatLng marker5= new LatLng(43.604892, 1.476562);
        LatLng marker6= new LatLng(43.604496, 1.474924);
        LatLng marker7= new LatLng(43.604781, 1.474502);

        // Markers All day long
        firstCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker1).title("First Place ").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 8.30 - 22.30")));

        // Markers Before 12 PM
        secondCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker2).title("Second Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 10.30 - 11.30")));

        // Markers Between 12-16
        thirdCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker3).title("Third Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 15.30 - 16.30")));
        thirdCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker4).title("Fourth Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 15.00 - 16.00")));

        // Markers Between 16-20
        fourthCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker5).title("Fifth Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 15.30 - 16.30")));
        fourthCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker6).title("Sixth Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 16.30 - 17.30")));
        fourthCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker7).title("Seventh Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 18.30 - 19.30")));
        fourthCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker8).title("Eighth Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 17.30 - 18.30\nHH:21.30 - 22.30")));


        // Markers After 20
        fifthCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker8).title("Eighth Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 17.30 - 18.30\nHH:21.30 - 22.30")));
        fifthCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker1).title("First Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 8.30 - 22.30")));


  public void filterTheMarkers(View view) {


        if (dialog == null){
        AlertDialog.Builder builder;
        builder = new AlertDialog.Builder(this);
        LayoutInflater inflater = this.getLayoutInflater();
        @SuppressLint("InflateParams") View checkBoxView = inflater.inflate(R.layout.markers_filtering, null);
        builder.setView(checkBoxView);
        cbAllDay = (CheckBox) checkBoxView.findViewById(R.id.checkBox1);
        if (checkBox1Checked != null) {
            cbAllDay.setChecked(checkBox1Checked);

        }
        cbBefore12 = (CheckBox) checkBoxView.findViewById(R.id.checkBox2);
        if (checkBox2Checked != null) {
            cbBefore12.setChecked(checkBox2Checked);

        }
        cbBetween1216 = (CheckBox) checkBoxView.findViewById(R.id.checkBox3);
        if (checkBox3Checked != null) {
            cbBetween1216.setChecked(checkBox3Checked);

        }
        cbBetween1620 = (CheckBox) checkBoxView.findViewById(R.id.checkBox4);
        if (checkBox4Checked != null) {
            cbBetween1620.setChecked(checkBox4Checked);

        }
        ccbAfter20 = (CheckBox) checkBoxView.findViewById(R.id.checkBox5);
        if (checkBox5Checked != null) {
            ccbAfter20.setChecked(checkBox5Checked);

        }

        dialog = builder.create();


    }

        dialog.show();
    }

  public void displaySelectedMarkers(View view) {

        dialog.dismiss();
        Log.i("TAG", "All Day " + cbAllDay.isChecked() + " Before 12 " + cbBefore12.isChecked() + " Between 12-16 " + cbBetween1216.isChecked() + " Between 16-20" + cbBetween1620.isChecked() + " After 20 " + ccbAfter20.isChecked());
        //according these check boxes status execute your code to show/hide markers


        if (cbAllDay.isChecked() && cbBefore12.isChecked() && cbBetween1216.isChecked() && cbBetween1620.isChecked() && ccbAfter20.isChecked()) {
            // show all markers
            for (Marker marker : firstCategoryList) {
                marker.setVisible(true);
            }
            for (Marker marker : secondCategoryList) {
                marker.setVisible(true);
            }
            for (Marker marker : thirdCategoryList) {
                marker.setVisible(true);
            }
            for (Marker marker : fourthCategoryList) {
                marker.setVisible(true);
            }
            for (Marker marker : fifthCategoryList) {
                marker.setVisible(true);
            }
        } else if (cbAllDay.isChecked() && !cbBefore12.isChecked() && !cbBetween1216.isChecked() && !cbBetween1620.isChecked() && !ccbAfter20.isChecked()) {
            // show only All Day Markers
            for (Marker marker : firstCategoryList) {
                marker.setVisible(true);
            }
            for (Marker marker : secondCategoryList) {
                marker.setVisible(false);
            }
            for (Marker marker : thirdCategoryList) {
                marker.setVisible(false);
            }
            for (Marker marker : fourthCategoryList) {
                marker.setVisible(false);
            }
            for (Marker marker : fifthCategoryList) {
                marker.setVisible(false);
            }
        }
//....and it goes like this for a while until I finish all the possibilities

现在我要做的是为单击的每个标记信息窗口打开一个新活动,因此我找到的解决方案是将所有标记添加到 HashMap 并为每个标记命名,以便我可以将其添加到HashMap 和 ArrayList,像这样:

private Map<Marker, Class> allMarkersMap = new HashMap<>();
Marker markerMarker1 = mMap.addMarker(new MarkerOptions().position(marker1).title("BAR ACASA").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 8.30 - 22.30"));

firstCategoryList.add(markerMarker1);
allMarkersMap.put(markerMarker1, Marker1.class);

现在在 onMapReady 上,我正在添加此代码,并为每个标记 Marker1.java、Marker2.java 创建一个类.....:

mMap.setOnInfoWindowClickListener(MyOnInfoWindowClickListener);
GoogleMap.OnInfoWindowClickListener MyOnInfoWindowClickListener = new GoogleMap.OnInfoWindowClickListener() {
    @Override
    public void onInfoWindowClick(Marker marker) {
        Class cls = allMarkersMap.get(marker);
        Intent intent = new Intent(MainActivity.this, cls );
        startActivity(intent);
    }
};

对于仅出现在一个类别中的标记,一切正常,但对于多个类别中的标记,过滤器不再起作用,仅显示最后添加到 HashMap 的标记(希望您了解我在这里说)。

那么,我可以这样做并且我的过滤器仍然可以正常工作吗?正如我想象的那样,正在发生的事情是,一旦我定义了一个标记并将其放在 Arraylist 中,它就会将标记移动到那里,然后当我将它放在 HashMap 中时,它会再次将它移动到 HashMap 所以当我过滤arraylists 标记不再在列表中...
对于我的信息窗口为显示的每个标记打开不同的活动,最佳解决方案是什么?

【问题讨论】:

  • 只需在标记单击时传递参数(每次根据标记单击不同)并保持活动相同。希望对您有所帮助。

标签: android google-maps google-maps-markers infowindow


【解决方案1】:

我不会为我的解决方案编写太多代码,因为我认为您编写它会更好,而且我认为它背后的想法比代码本身更重要。

首先给你一个小建议,每当你开始开发显示信息的 UI 东西时,试着找到一个通用的描述或描述将要显示的信息的规则。当您找到该规则/描述时,这意味着您找到了 model 类。 我强烈建议使用您创建的包含 UI 所需信息的自定义类。

现在回到您的示例,据我了解,您可以将标记添加到类别中,并根据该类别在地图上显示它们。 我会做什么我会创建一个自定义类,称为MyAwesomeMarker,它有一个Marker 成员和一个ArrayList&lt;String&gt; category

类似这样的:

public class MyAwesomeMarker {
   private Marker mMarker;
   private List<String> mMarkerCategories; // here you can mark if a marker is in more than one categories.
   // constructors
   public MyAwesomeMarker(Marker marker, String category) {
     mMarker = marker;
     mMarkerCategories = new ArrayList<String>();
     mMarkerCategories.add(category);            
   }

   public void addNewCategory(String category) {
      if(category != null && !mMarkerCategorie.contains(category)) {
         mMarkerCategories.add(category);
      }
   }

   public void toggleMarkerIfHasCategory(String theCategory) {
       for(String category : mMarkerCategories) {
           if(category.equals(theCategory) {
                   marker.setVisible(true);
           }
           else {
                 marker.setVisible(false);
           }

       }
   }

   // setters getters 
}

那么在你的主课中我会有一个MyAwesomeMarker的列表,我们称之为myMarkers

现在您要显示名为awesomness 的类别中的所有标记。

for(MyAwesomeMarker marker : myMarkers) {
       marker.toggleMarkerIfHasCategory("awesomness");
}

现在您唯一需要做的就是生成您的自定义标记灯,然后您就完成了。

【讨论】:

  • 明天我一定会试试你的建议。我同意这样一个事实,即如果我编写代码会更好,因为这样我会更好地理解我在做什么。我不明白您在这里试图告诉我什么“每当您开始开发显示信息的 UI 事物时,请尝试找到一个通用描述或描述将显示的信息的规则。当您找到该规则/描述时意味着你找到了一个模型类。” (尝试在哪里找到通用描述或规则?我对这一切都很陌生,我真的很感激更详细的解释)
  • 我也不知道如何“private List mMarkerCategories; // 这里你可以标记一个标记是否在多个类别中。”这将是一个名为 mMarkerCategories 的字符串列表,因此在这种情况下,它可以包含类别或标记?抱歉,我不明白你在解释什么
  • 只是为了澄清我想要做的事情:我在地图上添加了一些标记。这个标记将永远存在。我将标记分为 5 类。一些标记将属于多个类别。标记将按类别过滤并相应显示,但其他标记,不属于该类别的标记不会被删除,只是设置为不可见。这样,我只想将标记添加到地图一次,然后通过过滤过程对其进行操作。
  • @First comment:我想说的是创建包含您要显示的数据的对象,为此您必须找到一个规则(例如,您有一个带有 category = 的标记> 具有标记变量和类别变量的自定义类)。其次,mMarkers 将包含类别,因为您的类别是字符串。第三条评论,在toggle方法中处理。
  • 好的,理论上我明白你在说什么,不幸的是我需要阅读更多的文档才能实际做到这一点。几个月前我开始这样做,我相信我仍然错过了很多重要的概念。如果你能提供一个准确的代码解决方案,我会从它开始,以便更好地理解这个概念。提前致谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-02
  • 2015-02-13
相关资源
最近更新 更多