Home > Uncategorized > Android Lists: ListActivity and ListView II – Custom Adapter and List Item View

Android Lists: ListActivity and ListView II – Custom Adapter and List Item View

You’ve got a functioning list of stock ticker symbols now; however, it’s just a list of symbols and nothing more. Let’s explore how to add a static stock quote to each of the ticker symbols.

First, you can design the layout of how the stock ticker and quote should appear in the list. This is accomplished by creating a new layout file under res\layout. The following shows a simple row layout with two TextViews placed side-by-side horizontally:


res/layout/stock_quote_list_item.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
android:orientation=”horizontal”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”fill_parent”
android:id=”@+id/ticker_symbol” />
<TextView
android:layout_width=”wrap_content”
android:layout_height=”fill_parent”
android:id=”@+id/ticker_price” />
</LinearLayout>

While you used the ArrayAdapter in the previous part, you can’t use that adapter here since it only accepts a layout that contains a single TextView. One of the easiest and most flexible ways to use the layout that was just created is to create your own adapter by making a new class that extends from ArrayAdapter.

To do this, you can start by making a data class that will hold the stock quote information. This class will be used as the type parameter to ArrayAdapter when you create your new adapter class. I’ve provided a basic class below that holds the stock ticker and quote, along with getters and setters.

src/com/austinrasmussen/stockviewer/StockQuote.java


package com.austinrasmussen.stockviewer;

public class StockQuote {
private String tickerSymbol;
private double quote;

public StockQuote(String tickerSymbol, double quote) {
this.tickerSymbol = tickerSymbol;
this.quote = quote;
}
public void setTickerSymbol(String tickerSymbol) {
this.tickerSymbol = tickerSymbol;
}
public String getTickerSymbol() {
return tickerSymbol;
}
public void setQuote(double quote) {
this.quote = quote;
}
public double getQuote() {
return quote;
}
}

Now that you have a class to hold the stock quote data, you can create the custom adapter that will use that class. The key behind extending ArrayAdapter is to override the ArrayAdapter.getView(…) method. If this isn’t done, you will run into the limitation of the ArrayAdapter class that requires you to provide it with a layout that only contains a single TextView (i.e. java.lang.IllegalStateException: ArrayAdapter requires the resource ID to be a TextView). I’ve put together an adapter class that will fulfill the requirements for this part of the series.

src/com/austinrasmussen/stockviewer/StockQuoteAdapter.java


package com.austinrasmussen.stockviewer;

import java.util.List;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class StockQuoteAdapter extends ArrayAdapter {
private final Activity activity;
private final List stocks;

public StockQuoteAdapter(Activity activity, List objects) {
super(activity, R.layout.stock_quote_list_item , objects);
this.activity = activity;
this.stocks = objects;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
StockQuoteView sqView = null;

if(rowView == null)
{
// Get a new instance of the row layout view
LayoutInflater inflater = activity.getLayoutInflater();
rowView = inflater.inflate(R.layout.stock_quote_list_item, null);

// Hold the view objects in an object,
// so they don't need to be re-fetched
sqView = new StockQuoteView();
sqView.ticker = (TextView) rowView.findViewById(R.id.ticker_symbol);
sqView.quote = (TextView) rowView.findViewById(R.id.ticker_price);

// Cache the view objects in the tag,
// so they can be re-accessed later
rowView.setTag(sqView);
} else {
sqView = (StockQuoteView) rowView.getTag();
}

// Transfer the stock data from the data object
// to the view objects
StockQuote currentStock = stocks.get(position);
sqView.ticker.setText(currentStock.getTickerSymbol());
sqView.quote.setText(currentStock.getQuote().toString());

return rowView;
}

protected static class StockQuoteView {
protected TextView ticker;
protected TextView quote;
}
}

The only step left to do is combine the stock quote data with the newly created StockQuoteAdapter class. This will be done in the main StockList activity class that we started in the previous part of this series. All that needs to be done here is to create an ArrayList of StockQuote objects, which will be used in constructing the StockQuoteAdapter. The String array creation and list adapter code is now replaced with the following:


List stocks = new ArrayList();
stocks.add(new StockQuote("MSFT", 24.78));
stocks.add(new StockQuote("ORCL", 34.02));
stocks.add(new StockQuote("AMZN", 180.13));
stocks.add(new StockQuote("ERTS", 19.73));

Well, that looks… quite ugly. You’ll also notice that we’ve lost the font formatting when using the simple_list_item_1 layout. This is because the simple_list_item_1 had some simple formatting applied to the single TextView in the layout.

In the next part I’ll go over layout and formatting in some more detail. This will assist in readability and help clean up the view.
Final Code
src/com/austinrasmussen/stockviewer/StockList.java

package com.austinrasmussen.stockviewer;

import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.os.Bundle;

public class StockList extends ListActivity {

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

List stocks = new ArrayList();
stocks.add(new StockQuote("MSFT", 24.78));
stocks.add(new StockQuote("ORCL", 34.02));
stocks.add(new StockQuote("AMZN", 180.13));
stocks.add(new StockQuote("ERTS", 19.73));

setListAdapter(new StockQuoteAdapter(this, stocks));
}
}

src/com/austinrasmussen/stockviewer/StockQuote.java


package com.austinrasmussen.stockviewer;

public class StockQuote {
private String tickerSymbol;
private Double quote;

public StockQuote(String tickerSymbol, Double quote) {
this.tickerSymbol = tickerSymbol;
this.quote = quote;
}
public void setTickerSymbol(String tickerSymbol) {
this.tickerSymbol = tickerSymbol;
}
public String getTickerSymbol() {
return tickerSymbol;
}
public void setQuote(double quote) {
this.quote = quote;
}
public Double getQuote() {
return quote;
}
}

src/com/austinrasmussen/stockviewer/StockQuoteAdapter.java


package com.austinrasmussen.stockviewer;

import java.util.List;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class StockQuoteAdapter extends ArrayAdapter {
private final Activity activity;
private final List stocks;

public StockQuoteAdapter(Activity activity, List objects) {
super(activity, R.layout.stock_quote_list_item , objects);
this.activity = activity;
this.stocks = objects;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
StockQuoteView sqView = null;

if(rowView == null)
{
// Get a new instance of the row layout view
LayoutInflater inflater = activity.getLayoutInflater();
rowView = inflater.inflate(R.layout.stock_quote_list_item, null);

// Hold the view objects in an object,
// so they don't need to be re-fetched
sqView = new StockQuoteView();
sqView.ticker = (TextView) rowView.findViewById(R.id.ticker_symbol);
sqView.quote = (TextView) rowView.findViewById(R.id.ticker_price);

// Cache the view objects in the tag,
// so they can be re-accessed later
rowView.setTag(sqView);
} else {
sqView = (StockQuoteView) rowView.getTag();
}

// Transfer the stock data from the data object
// to the view objects
StockQuote currentStock = stocks.get(position);
sqView.ticker.setText(currentStock.getTickerSymbol());
sqView.quote.setText(currentStock.getQuote().toString());

return rowView;
}

protected static class StockQuoteView {
protected TextView ticker;
protected TextView quote;
}
}

main.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
android:orientation=”vertical”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”>
<ListView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:id=”@android:id/list” />
</LinearLayout>

source – vexedlogic

Advertisements
Categories: Uncategorized
  1. November 14, 2011 at 10:40 pm

    Extremely Excellent Post.

    Helped me completely, easy to follow, NOT one problem, it’s the most complete guide for editing a listview, Thank you sincerely.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: