All we have to do is extending ListActivity, implement the methods and we are good to go.
But there are times when it is not an option, because we need to extend another class.
Let say....MapActivity? So we need to create a two tabbed view for user to be able to change from map view to list view. Our intended application may look like this.
When user click on an entry in list view, user will be redirected to the entry location in map view.
In this tutorial, we will create only a ListView then, we will add Tabs and MapView Tab.
We will need to create our implementation of ArrayAdapter and override its getView() method to accomodate our own view. We will create a title, a description and an icon for each row.
Dont forget to add uses library and internet permission in AndroidManifest.xml
First, we need to create a model class. Let say Restaurant.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.tukangandroid.tutorial; | |
public class Restaurant { | |
private String name; | |
private String specialMenu; | |
private int latitude; | |
private int longitude; | |
public Restaurant(String name, String specialMenu, int latitude, int longitude) { | |
this.name = name; | |
this.specialMenu = specialMenu; | |
this.latitude = latitude; | |
this.longitude = longitude; | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public String getSpecialMenu() { | |
return specialMenu; | |
} | |
public void setSpecialMenu(String specialMenu) { | |
this.specialMenu = specialMenu; | |
} | |
public int getLatitude() { | |
return latitude; | |
} | |
public void setLatitude(int latitude) { | |
this.latitude = latitude; | |
} | |
public int getLongitude() { | |
return longitude; | |
} | |
public void setLongitude(int longitude) { | |
this.longitude = longitude; | |
} | |
} |
After that, we will create our view: main.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:orientation="vertical" | |
android:layout_width="fill_parent" | |
android:layout_height="fill_parent"> | |
<ListView android:id="@+id/list" | |
android:layout_width="fill_parent" | |
android:layout_height="fill_parent" | |
/> | |
</LinearLayout> |
Next, create our layout for each row in our list view: row.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="fill_parent" | |
android:layout_height="?android:attr/listPreferredItemHeight" | |
android:padding="6dip"> | |
<ImageView | |
android:id="@+id/icon" | |
android:layout_width="wrap_content" | |
android:layout_height="fill_parent" | |
android:layout_marginRight="6dip" | |
android:src="@drawable/icon" /> | |
<LinearLayout | |
android:orientation="vertical" | |
android:layout_width="0dip" | |
android:layout_weight="1" | |
android:layout_height="fill_parent"> | |
<TextView | |
android:id="@+id/toptext" | |
android:layout_width="fill_parent" | |
android:layout_height="0dip" | |
android:layout_weight="1" | |
android:gravity="center_vertical" | |
/> | |
<TextView | |
android:layout_width="fill_parent" | |
android:layout_height="0dip" | |
android:layout_weight="1" | |
android:id="@+id/bottomtext" | |
android:singleLine="true" | |
android:ellipsize="marquee" | |
/> | |
</LinearLayout> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.tukangandroid.tutorial; | |
import java.util.ArrayList; | |
import java.util.List; | |
import android.app.Activity; | |
import android.content.Context; | |
import android.os.Bundle; | |
import android.view.LayoutInflater; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.ArrayAdapter; | |
import android.widget.ListView; | |
import android.widget.TextView; | |
public class DoubleTabView extends Activity { | |
private ListView lv; | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.main); | |
lv = (ListView)findViewById(R.id.list); | |
// Adding dummy data | |
List<Restaurant> restaurants = new ArrayList<Restaurant>(); | |
restaurants.add(new Restaurant("Indonesian Restaurant", "babi guling", 35100000, 129100000)); | |
restaurants.add(new Restaurant("Chinese Restaurant", "cap cay", 35110000, 129110000)); | |
restaurants.add(new Restaurant("Korean Restaurant", "kimchi jige", 35120000, 129120000)); | |
lv.setAdapter(new RestaurantAdapter(this,android.R.layout.simple_list_item_1, restaurants)); | |
} | |
// Our array adapter, in our view, we will create a title, a description and an icon for each row | |
private class RestaurantAdapter extends ArrayAdapter<Restaurant> { | |
private List<Restaurant> items; | |
public RestaurantAdapter(Context context, int textViewResourceId, List<Restaurant> items) { | |
super(context, textViewResourceId, items); | |
this.items = items; | |
} | |
// Create a title and detail, icon is created in the xml file | |
@Override | |
public View getView(int position, View convertView, ViewGroup parent) { | |
View v = convertView; | |
if (v == null) { | |
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); | |
v = vi.inflate(R.layout.row, null); | |
} | |
Restaurant o = items.get(position); | |
if (o != null) { | |
TextView tt = (TextView) v.findViewById(R.id.toptext); | |
TextView bt = (TextView) v.findViewById(R.id.bottomtext); | |
if (tt != null) { | |
tt.setText("Name : "+o.getName()); | |
} | |
if(bt != null){ | |
bt.setText("Special menu: "+ o.getSpecialMenu()); | |
} | |
} | |
return v; | |
} | |
} | |
} |
Execute the application and we will see our generic list view application

Next, we will create a tab bar for user to choose List View or Map View and we will add the feature to navigate user to the map view whenever he/she click on a row in the List View
First, we should change our main.xml. We add TabHost, TabWidget and MapView
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="fill_parent" | |
android:layout_height="fill_parent"> | |
<TabHost android:id="@+id/tabhost" | |
android:layout_width="fill_parent" | |
android:layout_height="wrap_content"> | |
<TabWidget android:id="@android:id/tabs" | |
android:layout_width="fill_parent" | |
android:layout_height="wrap_content" | |
/> | |
<FrameLayout android:id="@android:id/tabcontent" | |
android:layout_width="fill_parent" | |
android:layout_height="fill_parent" | |
android:paddingTop="62px"> | |
<ListView android:id="@+id/list" | |
android:layout_width="fill_parent" | |
android:layout_height="fill_parent" | |
/> | |
<com.google.android.maps.MapView | |
android:id="@+id/mapview" | |
android:layout_width="fill_parent" | |
android:layout_height="fill_parent" | |
android:clickable="true" | |
android:apiKey="0Tmz2clOfrJGA0_c_d17-gSC4We41u7Onmx9W_Q" | |
/> | |
</FrameLayout> | |
</TabHost> | |
</LinearLayout> |
Next, we add the tab name programatically, then we add navigateToLocation method to navigate and zoom to the restaurant location
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.tukangandroid.tutorial; | |
import java.util.ArrayList; | |
import java.util.List; | |
import com.google.android.maps.GeoPoint; | |
import com.google.android.maps.MapActivity; | |
import com.google.android.maps.MapController; | |
import com.google.android.maps.MapView; | |
import com.google.android.maps.Overlay; | |
import com.google.android.maps.OverlayItem; | |
import android.content.Context; | |
import android.graphics.drawable.Drawable; | |
import android.os.Bundle; | |
import android.view.LayoutInflater; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.AdapterView; | |
import android.widget.ArrayAdapter; | |
import android.widget.ListView; | |
import android.widget.TabHost; | |
import android.widget.TextView; | |
import android.widget.AdapterView.OnItemClickListener; | |
public class DoubleTabView extends MapActivity { | |
private ListView lv; | |
private TabHost tabs; | |
private MapView mapView; | |
private List<Overlay> mapOverlays; | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.main); | |
tabs=(TabHost)findViewById(R.id.tabhost); | |
tabs.setup(); | |
TabHost.TabSpec spec=tabs.newTabSpec("list"); | |
spec.setContent(R.id.list); | |
spec.setIndicator("List View"); | |
tabs.addTab(spec); | |
spec=tabs.newTabSpec("mapview"); | |
spec.setContent(R.id.mapview); | |
spec.setIndicator("Map View"); | |
tabs.addTab(spec); | |
tabs.setCurrentTab(0); | |
mapView = (MapView) findViewById(R.id.mapview); | |
mapView.setBuiltInZoomControls(true); | |
mapOverlays = mapView.getOverlays(); | |
lv = (ListView)findViewById(R.id.list); | |
// Adding dummy data | |
final List<Restaurant> restaurants = new ArrayList<Restaurant>(); | |
restaurants.add(new Restaurant("Indonesian Restaurant", "babi guling", 35100000, 129100000)); | |
restaurants.add(new Restaurant("Chinese Restaurant", "cap cay", 35110000, 129110000)); | |
restaurants.add(new Restaurant("Korean Restaurant", "kimchi jige", 35120000, 129120000)); | |
lv.setAdapter(new RestaurantAdapter(this,android.R.layout.simple_list_item_1, restaurants)); | |
lv.setOnItemClickListener(new OnItemClickListener() { | |
public void onItemClick(AdapterView<?> arg0, View arg1, int position, | |
long arg3) { | |
// When user click a row, we get the row coordinate and navigate to that location | |
navigateToLocation(restaurants.get(position), mapView, false); | |
tabs.setCurrentTab(1); | |
} | |
}); | |
} | |
public void navigateToLocation(Restaurant restaurant, MapView mv, boolean isDefault) { | |
mapOverlays.clear(); | |
Drawable drawable = this.getResources().getDrawable(R.drawable.icon); | |
HelloItemizedOverlay itemizedOverlay = new HelloItemizedOverlay(drawable); | |
GeoPoint point = new GeoPoint(restaurant.getLatitude(), restaurant.getLongitude()); | |
OverlayItem overlayitem = new OverlayItem(point, "", ""); | |
itemizedOverlay.addOverlay(overlayitem); | |
mapOverlays.add(itemizedOverlay); | |
mv.displayZoomControls(true); | |
MapController mc = mv.getController(); | |
mc.animateTo(point); // move map to the given point | |
int zoomlevel = mv.getMaxZoomLevel() - 1; | |
mc.setZoom(zoomlevel); // zoom | |
mv.setSatellite(false); // display only "normal" mapview | |
} | |
// Our array adapter, in our view, we will create a title, a description and an icon for each row | |
private class RestaurantAdapter extends ArrayAdapter<Restaurant> { | |
private List<Restaurant> items; | |
public RestaurantAdapter(Context context, int textViewResourceId, List<Restaurant> items) { | |
super(context, textViewResourceId, items); | |
this.items = items; | |
} | |
// Create a title and detail, icon is created in the xml file | |
@Override | |
public View getView(int position, View convertView, ViewGroup parent) { | |
View v = convertView; | |
if (v == null) { | |
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); | |
v = vi.inflate(R.layout.row, null); | |
} | |
Restaurant o = items.get(position); | |
if (o != null) { | |
TextView tt = (TextView) v.findViewById(R.id.toptext); | |
TextView bt = (TextView) v.findViewById(R.id.bottomtext); | |
if (tt != null) { | |
tt.setText("Name : "+o.getName()); | |
} | |
if(bt != null){ | |
bt.setText("Special menu: "+ o.getSpecialMenu()); | |
} | |
} | |
return v; | |
} | |
} | |
@Override | |
protected boolean isRouteDisplayed() { | |
// TODO Auto-generated method stub | |
return false; | |
} | |
} |
Build and run.
Our final application should look like this
Click one restaurant, and the application will navigate and zoom to the location
That's it! Have fun!
This comment has been removed by the author.
ReplyDeleteSorry, do you have a complete source code for this?
ReplyDeleteThanks a lot !! Worked Perfectly .
ReplyDeleteGreat Article
ReplyDeleteJava Web Services Online Training
Web Services Course
Web Services Training Courses
Java Web Services Training in Chennai