8

I have a ListAdapter with a lot of different layouts for the rows. To have a clean code I want to outsource the layouts for the rows from the getView() of the adapter in View classes. Is it possible to inflate a XML layout into a custom view? I've only found the LayoutInflater but it returns a View and that does not help. I want to have something like the setLayout() of an Activity. Is this possible?

Thanks!

2
  • Could not get you. Can you explain in a more better way...? Commented Apr 4, 2011 at 7:05
  • If you like at the answer of Matthew Willis you may understand my question. Commented Apr 4, 2011 at 7:14

2 Answers 2

28

You can have a custom row view and inflate your xml in its constructor:

public MyRow extends LinearLayout { public MyRow(Context context) { super(context); LayoutInflater.from(context).inflate(R.layout.my_row, this, true); ... other initialization ... } } 

and then use merge in my_row.xml:

<?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android"> ... your row layout ... </merge> 

The merge element causes its children to be added as children of your custom view. Check out Merging Layouts for more info.

Sign up to request clarification or add additional context in comments.

2 Comments

I tried this and got error merge can be used only with a valid view group root and attachtoroot=true. Why? I'm using exatcly the same call, I'm using an xml with merge as a root, with no attributes.
that link is a 404 now. the closest I could find was developer.android.com/training/improving-layouts/… but I'd also suggest reading android-developers.blogspot.ca/2009/03/…
0

I alwas use a custom Adapter with a viewholder like:

public class CalendarAdapter extends BaseAdapter { protected static CalViewHolder holder; private LayoutInflater mInflater; public HashMap<Integer,String[]> appointments = new HashMap<Integer,String[]>(); public CalendarAdapter(Context context,HashMap<Integer,String[]> set_appointments) { // Cache the LayoutInf mInflater = LayoutInflater.from(context); appointments = set_appointments; } @Override public int getCount() { // TODO Auto-generated method stub return appointments == null ? 0:appointments.size(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = mInflater.inflate(R.xml.appointment, null); holder = new CalViewHolder(); holder.app_lay = (LinearLayout) convertView.findViewById(R.id.appointment_layout); holder.app_head = (TextView) convertView.findViewById(R.id.appointment_head); holder.app_body = (TextView) convertView.findViewById(R.id.appointment_body); convertView.setTag(holder); }else{ holder = (CalViewHolder) convertView.getTag(); } holder.app_head.setText(appointments.get(position)[0]); holder.app_body.setText(appointments.get(position)[1]); return convertView; } static class CalViewHolder { LinearLayout app_lay; TextView app_head; TextView app_body; } 

}

2 Comments

I use this method too, but I have a lot of different layouts for the row, so there is a really big "if else".
with many different layouts, the performance will slow down, I realised a similar Listview with up to six different holders, this is acceptable, but keep in mind, that you have to reload every single item, if you add or remove controls. Perhaps a listview is not really what you need, think about adding your views simply to a LinearLayout.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.