Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make my ArrayAdapter follow the ViewHolder pattern?

Here is my ArrayAdapter. I would like to make this more efficient by following the ViewHolder pattern:

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/List14.html

but am not sure how to accomplish this.

UPDATE: ViewHolder Pattern

private class QuoteAdapter extends ArrayAdapter<Quote> {      private ArrayList<Quote> items;     // used to keep selected position in ListView     private int selectedPos = -1; // init value for not-selected      public QuoteAdapter(Context context, int textViewResourceId, ArrayList<Quote> items) {         super(context, textViewResourceId, items);         this.items = items;     }      public void setSelectedPosition(int pos) {         selectedPos = pos;         // inform the view of this change         notifyDataSetChanged();     }      @Override     public View getView(int position, View convertView, ViewGroup parent) {         View v = convertView;         ViewHolder holder; // to reference the child views for later actions          if (v == null) {             LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);             v = vi.inflate(R.layout.mainrow, null);              // cache view fields into the holder             holder = new ViewHolder();             holder.nameText = (TextView) v.findViewById(R.id.nameText);             holder.priceText = (TextView) v.findViewById(R.id.priceText);             holder.changeText = (TextView) v.findViewById(R.id.changeText);              // associate the holder with the view for later lookup             v.setTag(holder);         }         else {             // view already exists, get the holder instance from the view             holder = (ViewHolder)v.getTag();         }          // change the row color based on selected state         if (selectedPos == position) {             v.setBackgroundResource(R.drawable.stocks_selected_gradient);             holder.nameText.setTextColor(Color.WHITE);             holder.priceText.setTextColor(Color.WHITE);             holder.changeText.setTextColor(Color.WHITE);         } else {             v.setBackgroundResource(R.drawable.stocks_gradient);             holder.nameText.setTextAppearance(getApplicationContext(), R.style.BlueText);             holder.priceText.setTextAppearance(getApplicationContext(), R.style.BlueText);             holder.changeText.setTextAppearance(getApplicationContext(), R.style.BlueText);         }          Quote q = items.get(position);         if (q != null) {             if (holder.nameText != null) {                 holder.nameText.setText(q.getSymbol());             }             if (holder.priceText != null) {                 holder.priceText.setText(q.getLastTradePriceOnly());             }             if (holder.changeText != null) {                 try {                     float floatedChange = Float.valueOf(q.getChange());                     if (floatedChange < 0) {                         if (selectedPos != position)                             holder.changeText.setTextAppearance(getApplicationContext(), R.style.RedText); // red                     } else {                         if (selectedPos != position)                             holder.changeText.setTextAppearance(getApplicationContext(), R.style.GreenText); // green                     }                 } catch (NumberFormatException e) {                     System.out.println("not a number");                 } catch (NullPointerException e) {                     System.out.println("null number");                 }                 holder.changeText.setText(q.getChange() + " (" + q.getPercentChange() + ")");             }         }         return v;     } } 
like image 634
Sheehan Alam Avatar asked Sep 30 '10 15:09

Sheehan Alam


People also ask

What is the benefit of ViewHolder pattern in Android?

The ViewHolder design pattern enables you to access each list item view without the need for the look up, saving valuable processor cycles. Specifically, it avoids frequent call of findViewById() during ListView scrolling, and that will make it smooth.

How do you use a ViewHolder?

A ViewHolder describes an item view and metadata about its place within the RecyclerView. RecyclerView. Adapter implementations should subclass ViewHolder and add fields for caching potentially expensive View. findViewById(int) results.

What is the purpose of the ViewHolder Design practice?

When you are developing an Android program; and you want to have a ArrayAdapter you can Simply have a Class (most of times with ViewHolder suffix) or directly inflate your convertView and find your view by id.

How do I use ArrayAdapter?

Go to app > res > layout > right-click > New > Layout Resource File and create a new layout file and name this file as item_view. xml and make the root element as a LinearLayout. This will contain a TextView that is used to display the array objects as output.


1 Answers

The ViewHolder is basically a static class instance that you associate with a view when it's created, caching the child views you're looking up at runtime. If the view already exists, retrieve the holder instance and use its fields instead of calling findViewById.

In your case:

@Override public View getView(int position, View convertView, ViewGroup parent) {     View v = convertView;     ViewHolder holder; // to reference the child views for later actions      if (v == null) {         LayoutInflater vi =              (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);         v = vi.inflate(R.layout.mainrow, null);         // cache view fields into the holder         holder = new ViewHolder();         holder.nameText = (TextView) v.findViewById(R.id.nameText);         holder.priceText = (TextView) v.findViewById(R.id.priceText);         holder.changeText = (TextView) v.findViewById(R.id.changeText);         // associate the holder with the view for later lookup         v.setTag(holder);     }     else {         // view already exists, get the holder instance from the view         holder = (ViewHolder) v.getTag();     }     // no local variables with findViewById here      // use holder.nameText where you were      // using the local variable nameText before      return v; }  // somewhere else in your class definition static class ViewHolder {     TextView nameText;     TextView priceText;     TextView changeText; } 

caveat: I didn't try to compile this, so take with a grain of salt.

like image 93
codelark Avatar answered Sep 25 '22 03:09

codelark