问题
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