Jerome P. commented on my earlier post denouncing the ViewHolder pattern. He suggested an improvement to the ViewGroup approach that inverts the direction of dependency between the ContactView and its layout XML file. Instead of referencing the custom class from XML, the Java code now references the layout file using a standard resource reference. This adds further type safety and it means your view class can be completely ProGuarded.

The list adapter implementation becomes more convenient. It no longer needs to use a layout inflater, it can simply new up an instance of the view class:

    public View getView(int position, View convertView, ViewGroup parent) {
        ContactView view;
        if (convertView == null) {
            view = new ContactView(context);
            // Was: view = (ContactView) inflater.inflate(R.layout.list_item, null);
        }
        // continued...
    }

To do this, change the root element of the XML layout to <merge/> and modify the constructors of the custom view group:

public class ContactView extends LinearLayout {

    // private field declarations

    /** Inherited constructor. */
    public ContactView(Context context) {
        super(context);
        init(context);
    }

    /** All three constructors invoke this method. */
    private void init(Context context) {
        setOrientation(VERTICAL);
        LayoutInflater.from(context).inflate(R.layout.contact_view, this, true);
        nameView = (TextView) findViewById(R.id.contact_name);
        emailView = (TextView) findViewById(R.id.contact_email);
        addressView = (TextView) findViewById(R.id.contact_address);
    }

    // continued

The complete code for this example has been added to the 4-_better_custom_ViewGroup branch of the android-cciaa repository on GitHub.