Reputation: 7243
I want to create a ListView
with the last row showing a TabHost
with two tabs. I would like to load another ListView
for each tab. For this, I've created three XML files.
The main.xml is where I'm loading the initial list. The mainlistdata.xml is how each row of the list is presented. And the last xml is tabslayout.xml. This layout is used for the last row on the main listview. It will load the tabhost. Here is the code with all the xml:
My main class is this:
public class MainActivity extends Activity {
ArrayList<testData> myData = new ArrayList<testData>();
ListView listContent;
TestAdapter dataAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String[] aString = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
for (int i = 0; i < aString.length; i++) {
myData.add(new testData(i, aString[i]));
}
listContent = (ListView) findViewById(R.id.mainlist);
dataAdapter = new TestAdapter(this, myData,1);
listContent.setAdapter(dataAdapter);
}
}
And this is the class that loads the content on the listviews and where I set the tabhost:
public class TestAdapter extends ArrayAdapter<testData> {
private Context context;
private ArrayList<testData> data;
private ListView listContent,listContent2;
public TabHost tabs;
TestAdapter dataAdapter;
private int choice;
public TestAdapter(Context context, ArrayList<testData> data, int choice) {
super(context, R.layout.mainlistdata, data);
this.context = context;
this.data = data;
this.choice = choice;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView;
if (choice == 1) {
if (position == data.size()-1) {
rowView = inflater.inflate(R.layout.tabslayout, parent, false);
TextView first = (TextView) rowView.findViewById(R.id.dataTitle);
TextView second = (TextView) rowView.findViewById(R.id.dataValue);
TextView third = (TextView) rowView.findViewById(R.id.dataValueString);
first.setText("Item " + data.get(position).getIntValue());
second.setText(String.valueOf(data.get(position).getIntValue()));
third.setText(data.get(position).getStringValue());
tabs = (TabHost) rowView.findViewById(android.R.id.tabhost);
tabs.setup();
TabSpec tab1 = tabs.newTabSpec("Tab 1");
TabSpec tab2 = tabs.newTabSpec("Tab 2");
tab1.setContent(R.id.tabOne);
tab2.setContent(R.id.tabTwo);
tab1.setIndicator("One");
tab2.setIndicator("two");
tabs.addTab(tab1);
tabs.addTab(tab2);
tabs.setup();
listContent = (ListView) rowView.findViewById(R.id.listOne);
dataAdapter = new TestAdapter(context, data,2);
listContent.setAdapter(dataAdapter);
listContent2 = (ListView) rowView.findViewById(R.id.listTwo);
dataAdapter = new TestAdapter(context, data,3);
listContent2.setAdapter(dataAdapter);
} else {
rowView = inflater.inflate(R.layout.mainlistdata, parent, false);
TextView first = (TextView) rowView.findViewById(R.id.dataTitle);
TextView second = (TextView) rowView.findViewById(R.id.dataValue);
TextView third = (TextView) rowView.findViewById(R.id.dataValueString);
first.setText("Item " + data.get(position).getIntValue());
second.setText(String.valueOf(data.get(position).getIntValue()));
third.setText(data.get(position).getStringValue());
}
} else if (choice == 2) {
rowView = inflater.inflate(R.layout.mainlistdata, parent, false);
TextView first = (TextView) rowView.findViewById(R.id.dataTitle);
TextView second = (TextView) rowView.findViewById(R.id.dataValue);
TextView third = (TextView) rowView.findViewById(R.id.dataValueString);
first.setText("Item tab1 " + data.get(position).getIntValue());
second.setText(String.valueOf(data.get(position).getIntValue()));
third.setText(data.get(position).getStringValue());
} else {
rowView = inflater.inflate(R.layout.mainlistdata, parent, false);
TextView first = (TextView) rowView.findViewById(R.id.dataTitle);
TextView second = (TextView) rowView.findViewById(R.id.dataValue);
TextView third = (TextView) rowView.findViewById(R.id.dataValueString);
first.setText("Item tab2 " + data.get(position).getIntValue());
second.setText(String.valueOf(data.get(position).getIntValue()));
third.setText(data.get(position).getStringValue());
}
return rowView;
}
}
As you can see on the next image, I'm loading the data and then I'm loading the tabs. The problem is that each tab is only loading the first row of the data. Any idea How can I solve this?
Upvotes: 2
Views: 1741
Reputation: 87064
As Sherif elKhatib already said in his comment having a ListView
in another ListView
should be avoided. The solution for your problems is using a single ListView
along with different row types to give the illusion of having tabs in the ListView
containing other ListViews
, all handled by a custom adapter. Based on your example, you would have four row types:
ListViews
(unless your tabs should have the same row appearance in which case you would have a single tab row type)To implement these row types you would need to use the getItemViewType()
and getViewTypeCount()
method of an adapter:
// different row types
private static final int NORMAL_ROW = 0;
private static final int TAB_ROW = 1;
private static final int TAB1_TYPE = 2;
private static final int TAB2_TYPE = 3;
@Override
public int getItemViewType(int position) {
if (position < mData.size()) {
// we are in the initial list's range so it's a normal row
return NORMAL_ROW;
} else if (position == mData.size()) {
// we are at the tab level, so it's a tab row
return TAB_ROW;
} else {
// based on the current selected tab(0 by default) we have
// either a tab 1 row type or tab 2 row type
return mCurrentSelectedTab == 0 ? TAB1_TYPE : TAB2_TYPE;
}
}
@Override
public int getViewTypeCount() {
// if your list-tabs need different row types then you'll need to
// make the calculations here and update appropriately
return 4;
}
In the getView()
you would inflate the proper layout(your layouts) based on those row layout types and also set the data. The adapter will also need to handle the user selecting a tab to use notifyDataSetChanged()
and update the ListView
with the proper row type(and data) for the tab part of it.
You can see the whole sample here, also have a look at the xml layouts used, it should be quite easy to understand.
Upvotes: 2