ListView包含TabHost与其他ListViews

时间:2013-04-24 20:19:45

标签: android android-listview android-tabhost android-tabs

我想创建一个ListView,最后一行显示带有两个标签的TabHost。我想为每个标签加载另一个ListView。为此,我创建了三个XML文件。

main.xml是我加载初始列表的地方。 mainlistdata.xml是列表的每一行的呈现方式。最后一个xml是tabslayout.xml。此布局用于主列表视图的最后一行。它将加载tabhost。 Here is the code包含所有xml:

我的主要课程是:

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);
    }
}

这是加载listviews上的内容的类,以及我设置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;
    }
}

正如您在下一张图片中看到的那样,我正在加载数据,然后我正在加载标签。问题是每个选项卡只加载第一行数据。任何想法我该如何解决这个问题? enter image description here enter image description here

1 个答案:

答案 0 :(得分:2)

正如Sherif elKhatib在他的评论中已经说过,应该避免在另一个ListViewListView。针对您的问题的解决方案是使用单个ListView以及不同的行类型,以给出在ListView中包含其他ListViews的标签的错觉,所有标签都由自定义适配器处理。根据您的示例,您将有四种行类型:

  • 正常行(带字母的行)
  • 包含标签
  • 的一行
  • 每个伪ListViews的两种行类型(除非您的标签应具有相同的行外观,在这种情况下,您将有一个标签行类型)

要实现这些行类型,您需要使用适配器的getItemViewType()getViewTypeCount()方法:

// 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;
}

getView()中,您将根据这些行布局类型夸大正确的布局(布局),并设置数据。适配器还需要处理用户选择要使用notifyDataSetChanged()的选项卡,并使用正确的行类型(和数据)更新ListView

您可以看到whole sample here,同时查看xml layouts used,这应该很容易理解。