Monday, April 25, 2011

Better findViewById that doesn't require you to type-cast the result

If you started developing Android apps, you must have known the findViewById method. That is the method that glues UI and code.

However, findViewById returns the generic View, so you need to type-cast it to the specific view if you want to do widget-specific operations on it (e.g. setText).

TextView lAddress = (TextView) findViewById(R.id.lAddress);

or,

ImageButton bSubmit = (ImageButton) findViewById(R.id.bSubmit);

That's so annoying, even more if you change the type of the widget with similar but unrelated ones, like swapping a Button with an ImageButton.

Solution: use a generic method that returns you an object of the type that you request.

Paste the 2 methods below anywhere you like.

/**
 * Convenience method of findViewById
 */
@SuppressWarnings("unchecked")
public static <T extends View> T getView(View parent, int id) {
 return (T) parent.findViewById(id);
}

/**
 * Convenience method of findViewById
 */
@SuppressWarnings("unchecked")
public static <T extends View> T getView(Activity activity, int id) {
 return (T) activity.findViewById(id);
}

Now, you can just call them like:

TextView lAddress = getView(this, R.id.lAddress);

// or, if not inside an activity, let's say in an Adapter's getView:
View res = convertView != null? convertView: getLayoutInflater().inflate(R.layout.item_person, null);
TextView lAddress = getView(res, R.id.lAddress);

Friday, April 15, 2011

Call getItem instead of parent.getItemAtPosition

On your list item click listener, usually you will need to get the item clicked. You can do it with:

News news = (News) parent.getItemAtPosition(position);


However, I don't recommend that, mainly because of the cast. If you change the adapter to operate on items of different type, the compiler will not catch the error.

Instead, access the adapter directly.


News news = adapter.getItem(position);


This is possible only if you make the adapter return the correct item type instead of Object:

public News getItem(int position) {
return list == null || position >= list.items.size()? null: list.items.get(position);
}


(for long-time Java user, you may not have noticed that that was possible starting Java 5.)