3

我正在尝试实现两级 DrawerLayout。作为基线,我使用来自http://developer.android.com/training/implementing-navigation/nav-drawer.html的 Google 星球示例。所以我想扩展这个例子,从行星列表中选择一个行星,用该行星上的城市列表替换行星列表(除了地球之外大部分是空白的 - 我仍在充实我的数据:- ))。

我想我可以采取三种方法:-

  1. 替换列表视图
  2. 保留 ListView,但替换它的 ArrayAdapter
  3. 保留 ListView 和 ArrayAdapter,但替换适配器的数据

所以尝试选项 3(这是最好的方法吗?),在我的 DrawerItemClickListener 中,我执行以下操作......

arrayAdapter.clear(); 
arrayAdapter.addAll(arrayListOfCities);
arrayAdapter.notifyDataSetChanged(); 
mDrawerList.invalidateViews();
mDrawerList.forceLayout();
mDrawerList.refreshDrawableState();

但它似乎不起作用,即行星列表不会被城市列表取代。

我的方法正确吗?如果是,我如何让列表刷新?

4

1 回答 1

5

替换列表视图

真的没有这个必要。


保留 ListView,但替换它的 ArrayAdapter

这将是最容易实现的。首先,将以下字符串数组(城市名称)添加到 res/values/strings.xml:

<string-array name="mercury_array">
    <item>Undiscovered City 1 (Mercury)</item>
    <item>Undiscovered City 2 (Mercury)</item>
    <item>Undiscovered City 3 (Mercury)</item>
    <item>Undiscovered City 4 (Mercury)</item>
</string-array>
<string-array name="venus_array">
    <item>Undiscovered City 1 (Venus)</item>
    <item>Undiscovered City 2 (Venus)</item>
    <item>Undiscovered City 3 (Venus)</item>
    <item>Undiscovered City 4 (Venus)</item>
</string-array>
<string-array name="earth_array">
    <item>New York</item>
    <item>Hong Kong</item>
    <item>New Delhi</item>
    <item>London</item>
</string-array>
<string-array name="mars_array">
    <item>Undiscovered City 1 (Mars)</item>
    <item>Undiscovered City 2 (Mars)</item>
    <item>Undiscovered City 3 (Mars)</item>
    <item>Undiscovered City 4 (Mars)</item>
</string-array>
<string-array name="jupiter_array">
    <item>Undiscovered City 1 (Jupiter)</item>
    <item>Undiscovered City 2 (Jupiter)</item>
    <item>Undiscovered City 3 (Jupiter)</item>
    <item>Undiscovered City 4 (Jupiter)</item>
</string-array>
<string-array name="saturn_array">
    <item>Undiscovered City 1 (Saturn)</item>
    <item>Undiscovered City 2 (Saturn)</item>
    <item>Undiscovered City 3 (Saturn)</item>
    <item>Undiscovered City 4 (Saturn)</item>
</string-array>
<string-array name="uranus_array">
    <item>Undiscovered City 1 (Uranus)</item>
    <item>Undiscovered City 2 (Uranus)</item>
    <item>Undiscovered City 3 (Uranus)</item>
    <item>Undiscovered City 4 (Uranus)</item>
</string-array>
<string-array name="neptune_array">
    <item>Undiscovered City 1 (Neptune)</item>
    <item>Undiscovered City 2 (Neptune)</item>
    <item>Undiscovered City 3 (Neptune)</item>
    <item>Undiscovered City 4 (Neptune)</item>
</string-array>

loadContentList(int)MainActivity. _ 这是在主列表的项目单击时调用的方法:

private void loadContentList(int position) {

    setTitle(mPlanetTitles[position]);

    String[] content;

    switch(position) {
    case 0:
            content = getResources().getStringArray(R.array.mercury_array);
            break;
    case 1:
            content = getResources().getStringArray(R.array.venus_array);
            break;
    case 2:
            content = getResources().getStringArray(R.array.earth_array);
            break;
    case 3:
            content = getResources().getStringArray(R.array.mars_array);
            break;
    case 4:
            content = getResources().getStringArray(R.array.jupiter_array);
            break;
    case 5:
            content = getResources().getStringArray(R.array.saturn_array);
            break;
    case 6:
            content = getResources().getStringArray(R.array.uranus_array);
            break;
    case 7:
            content = getResources().getStringArray(R.array.neptune_array);
            break;
    default:
            content = getResources().getStringArray(R.array.neptune_array);     
}

    // Change ListView's adapter    
    mDrawerList.setAdapter(new ArrayAdapter<String>(this,
            R.layout.drawer_list_item, content));

    // Change OnItemClickListener // CityItemClickListener is defined below
    mDrawerList.setOnItemClickListener(new CityItemClickListener());
}

由于我们想在单击行星项时更新 ListView,我们将更改 DrawerItemClickListener 的方法体并调用新添加的loadContentList(int)

/* The click listner for ListView in the navigation drawer */
private class DrawerItemClickListener implements ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        //selectItem(position);
        loadContentList(position);
    }
}

单击城市时,我们将需要另一个 OnItemClickListener 来更改片段。:

private class CityItemClickListener implements ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        // This is the method that was being called on planet click 
        // in the original example. Implementation of it is up to you
        selectItem(position);
    }
}

保留 ListView 和 ArrayAdapter,但替换适配器的数据

定义 ArrayAdapter:

private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;    
---------> private ArrayAdapter<String> mAdapter;     

在 MainActivity 的 onCreate(Bundle) 中:

ArrayList<String> planetList = new ArrayList<String>();

planetList.addAll(Arrays.asList(mPlanetTitles));

mAdapter = new ArrayAdapter<String>(this,
            R.layout.drawer_list_item, planetList);

// set up the drawer's list view with items
mDrawerList.setAdapter(mAdapter);      

UnsupportedOperationException调用时我们必须传递一个 ArrayList 来避免mAdapter.clear()

更改loadContentList(int)为以下内容:

private void loadContentList2(int position) {

    setTitle(mPlanetTitles[position]);

    String[] content;

    switch(position) {

        ....
        ....
    }

    ArrayList<String> cityList = new ArrayList<String>();

    cityList.addAll(Arrays.asList(content));

    mAdapter.clear();

    mAdapter.addAll(cityList);

    // update
    mAdapter.notifyDataSetChanged();        

    // Change on item click listener
    mDrawerList.setOnItemClickListener(new CityItemClickListener());

}

CityItemClickListener 和 DrawerItemClickListener 将保持与以前相同。唯一的变化是:我们没有在行星列表项单击时创建新的 ArrayAdapter。

您需要找到一种方法(也许是一个按钮)让用户从城市视图返回到行星列表。

我还建议您查看 ExpandableListView。它可能会更优雅地解决您的问题。

于 2013-09-13T23:12:25.260 回答