Android marker custom infowindow

孤街醉人 提交于 2020-01-13 18:38:30

问题


I am using Google Map V2.

I need to show the ListView (custom ListView with Image) in custom InfoWindow. I tried it and got success only in View, the problem is I can't get the listItemClick event.

googleMap.setInfoWindowAdapter(new InfoWindowAdapter() {

@Override
public View getInfoWindow(Marker arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public View getInfoContents(Marker arg0) {
    View v = getLayoutInflater().inflate(R.layout.infowindow, null);
    try{
        String[] names = {"The Mayfair (D22) Condominium, For Rent","The Mayfair (D22) Condominium, For Rent","The Mayfair (D22) Condominium, For Rent","The Mayfair (D22) Condominium, For Rent"};
        Log.d("f", names.toString());
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(PropertyMapList.this, R.layout.info_row_view, R.id.textView1, names);
        Log.d("d", adapter.getCount()+"");
        ListView list = (ListView) v.findViewById(R.id.listView1);
        list.setAdapter(adapter);
        list.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(
                    AdapterView<?> arg0,
                    View arg1, int arg2,
                    long arg3) {
                Log.d("position:", arg2+"");
            }
        });
    }catch (Exception e) {
        e.printStackTrace();
    }
    return v;
}
});

回答1:


Finally i got successful answer myself with these code integration

And you can find the app in play-store

https://play.google.com/store/apps/details?id=com.stp.stproperty&hl=en

Marker XML file

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="300dp"
    android:layout_height="wrap_content"
    android:orientation="vertical" android:background="@drawable/marker_bg" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="7dp"
        android:layout_marginLeft="5dp"
        android:layout_marginBottom="20dp"
        android:layout_marginRight="5dp" >

    </ListView>

</RelativeLayout>

And the listview custom layout (Text with Arrow image)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="90dp"
    android:orientation="vertical"
    android:gravity="center_vertical"
    android:background="@drawable/marker_selecter" >

    <RelativeLayout android:layout_width="fill_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/ProeprtyName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_centerHorizontal="true"
            android:layout_marginLeft="5dp"
            android:layout_toLeftOf="@+id/RightArrow"
            android:textColor="@color/list_textcolor"
            android:textSize="16sp" />

        <ImageView
            android:id="@+id/RightArrow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="3dp"
            android:layout_centerInParent="true"
            android:src="@drawable/detaildisclosure" />
    </RelativeLayout>
</RelativeLayout>

Adding marker to map

// Set title for marker here, with the help of this title we can customize easily and change lat and long values, icon as weel to your code
googleMap.addMarker(new MarkerOptions()
    .title(infoTitle.get(index))
    .position(new LatLng(Double.parseDouble(lanAndLat.get(index).split("\\$")[0]), Double.parseDouble(lanAndLat.get(index).split("\\$")[1])))
    .icon(BitmapDescriptorFactory.fromBitmap(icon)));

Set marker onclicklistener as :

googleMap.setOnMarkerClickListener(new OnMarkerClickListener() {

    @Override
    public boolean onMarkerClick(Marker arg0) {

        drawCustomMarker(arg0.getPosition().latitude, arg0.getPosition().longitude, arg0.getTitle(),0);
        return true;
    }
});

Declare the custom marker as global variable (To clear this from view and recreate it will help)

CustomMarker = getLayoutInflater().inflate(R.layout.infowindow, null);

Custom marker drawing function. I made it for my use case. Please customize it according to your requirement

private void drawCustomMarker(Double latitude, Double longitude, String title, int propertyId){
    try{
        int selectedMarkerIndex = -1; // On-select from list-view this needs to be highlighted in marker as selected
        mapinnerLayout.removeView(CustomMarker);
        googleMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(latitude, longitude)));

        // I am passing title as string with # separated values to access

        String[] names = title.split("\\#");
        ArrayList<MarkerAdapterClass> markerClass = new ArrayList<MarkerAdapterClass>();
        for(int i=0;i<names.length;i++){
            // this is custom class for my own use if you want you can change this class 
            MarkerAdapterClass classObj = new MarkerAdapterClass();
            String[] data = names[i].split("\\|");
            int pId = Integer.parseInt(data[1]);
            if(pId==propertyId){
                selectedMarkerIndex = i;
            }
            classObj.setpropertyTitle(data[0]);
            classObj.setid(pId);
            classObj.setitemIndex(Integer.parseInt(data[2]));
            markerClass.add(classObj);
        }
        CustomMarker.setVisibility(View.VISIBLE);
        MarkerInfoAdapter adapter = new MarkerInfoAdapter(PropertyMapList.this, markerClass, districtView);
        final ListView list = (ListView) CustomMarker.findViewById(R.id.listView1);
        list.setAdapter(adapter);
        if(selectedMarkerIndex>=0){
            adapter.setSelected(selectedMarkerIndex);
            list.setSelection(selectedMarkerIndex);
        }
        int height = getMarkerInfoHeight(markerClass.size(), list);
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(450,height);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
        layoutParams.setMargins(0, mapinnerLayout.getHeight()/2 - (height+30), 0, 0);
        mapinnerLayout.addView(CustomMarker, layoutParams);

    }catch(Exception e){
        //e.printStackTrace();
    }
}

mapinnerLayout is an relative layout (container of map)

I am using this to support 10 and 7 inches tablet. The height and width will vary for devices and portrait to landscape. I am calculating this here:

public int getMarkerInfoHeight(int size, ListView view){
    int height = 90;
    int Orientation = PropertyMapList.this.getResources().getConfiguration().orientation;
    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    int deviceheight = displaymetrics.heightPixels;
    RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    lp.setMargins(5, 3, 5, 12);
    if(Orientation == Configuration.ORIENTATION_LANDSCAPE && deviceheight <= 700){
        if(size > 1){
            height = 190;
            lp.setMargins(5, 3, 5, 25);
        }
    }else{
        if(size == 2){
            height = 190;
            lp.setMargins(5, 3, 5, 25);
        }else if(size > 2){
            height = 285;
            lp.setMargins(5, 3, 5, 35);
        }
    }
    view.setLayoutParams(lp);
    return height;
}

Marker adapter:

public class MarkerInfoAdapter extends BaseAdapter {
    private static ArrayList<MarkerAdapterClass> propertyNames;
    private LayoutInflater mInflater;
    int selectedPosition = -1;
    private ListView parentAdapter;
    Context context;
    public MarkerInfoAdapter(Context context, ArrayList<MarkerAdapterClass> results, ListView parentAdapter) {
        propertyNames = results;
        this.parentAdapter = parentAdapter;
        mInflater = LayoutInflater.from(context);
        this.context = context;
    }
    @Override
    public int getCount() {
        return propertyNames.size();
    }

    @Override
    public Object getItem(int position) {
        return propertyNames.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
    static class ViewHolder {
        TextView Name;
        ImageView image;
    }
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        try{
            if(convertView==null)
            {
                convertView=mInflater.inflate(R.layout.marker_row_view, null);
                holder=new ViewHolder();
                holder.Name=(TextView)convertView.findViewById(R.id.ProeprtyName);
                holder.image=(ImageView)convertView.findViewById(R.id.RightArrow);
                convertView.setTag(holder);
            }
            else
            {
                holder=(ViewHolder)convertView.getTag();
            }
            holder.Name.setText(propertyNames.get(position).getpropertyTitle());
            if(selectedPosition == position){
                convertView.setBackgroundResource(R.drawable.blue_marker_bg);
                ((TextView)convertView.findViewById(R.id.ProeprtyName)).setTextColor(Color.WHITE);
                convertView.setMinimumHeight(80);
            }else{
                convertView.setBackgroundResource(R.drawable.directories_list_bg);
                ((TextView)convertView.findViewById(R.id.ProeprtyName)).setTextColor(Color.BLACK);
                convertView.setMinimumHeight(80);
            }
            ((TextView)convertView.findViewById(R.id.ProeprtyName)).setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    setSelected(position);
                    if(context.getClass().getSimpleName().equals("PropertyMapList")){
                        ((PropertyListAdaptor)parentAdapter.getAdapter()).setSelected(propertyNames.get(position).getitemIndex());
                    }else{
                        ((FavoriteListAdapter)parentAdapter.getAdapter()).setSelected(propertyNames.get(position).getitemIndex());
                    }
                    parentAdapter.setSelection(propertyNames.get(position).getitemIndex());
                }
            });
        }catch (Exception e) {
            e.printStackTrace();
        }

        return convertView;
    }
    public void setSelected(int position) {
        selectedPosition = position;
        notifyDataSetChanged();
    }
}

Marker adapter class

public class MarkerAdapterClass {
    private int id;
    private String propertyTitle;
    private int itemIndex=0;

    public String getpropertyTitle() {
        return propertyTitle;
    }
    public void setpropertyTitle(String title) {
        this.propertyTitle = title;
    }
    public int getitemIndex() {
        return itemIndex;
    }
    public void setitemIndex(int itemIndex) {
        this.itemIndex = itemIndex;
    }
    public int getid() {
        return this.id;
    }
    public void setid(int id) {
        this.id = id;
    }
}



回答2:


The info window that is drawn is not a live view. The view is rendered as an image (using View.draw(Canvas)) at the time it is returned

check documentation



来源:https://stackoverflow.com/questions/16185254/android-marker-custom-infowindow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!