尽管在恢复应用程序时某些项目已添加到适配器,但ListView为空

时间:2012-05-23 01:06:17

标签: android android-listview android-adapter android-listfragment

我在市场上有一个应用程序,我似乎无法解决这个问题。今天我跟踪了以下方法。

public void updateDealList(ArrayList<Deal> deals) {
    // first call or showing bookmakrs (also gets called other times when adapter is null)
    if (dealListAdapter == null || showingBookmarks || !dealListAdapter.moreDealsToDownload()) { 
        dealListAdapter = new EndlessDealListAdapter(getActivity(),
                R.layout.deal_list_item, deals);
        setListAdapter(dealListAdapter);
        listView = getListView();
        if (getActivity().findViewById(R.id.right_fragment_container)!=null){ // if tablet
            listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            listView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT);
        }
        showingBookmarks=false;
        Log.d("UPDATE_DEAL_LIST", "Notified list  created new" + dealListAdapter.getCount());
        return; //PROBLEM OCCURS WHEN APP COMES IN HERE AFTER RESUMING
    }
    dealListAdapter.getDealListAdapter().clear();
    for (Deal d: deals){
        dealListAdapter.getDealListAdapter().add(d);
        Log.d("UPDATE_DEAL_LIST", "added " + d.title);
    }
    dealListAdapter.notifyDataSetChanged();
    Log.d("UPDATE_DEAL_LIST", "Notified list " + dealListAdapter.getCount());
}

这个方法传递了一个交易对象的arraylist,这些交易对象是从互联网上下载的。首次打开应用程序时,将从Internet中提取数据并调用上述方法,从而创建为ListFragment设置的新适配器。当用户请求更多交易时,也会调用此方法。

我遇到的问题是列表有时会认为它是空的,它包含了包含交易的适配器。当一个用户在他们的设备内存不足时恢复应用程序(我假设部分应用程序已从ram中删除)时,似乎会发生这种情况。调用此方法并且dealListAdapter为null,因此创建了一个新方法并添加了交易。尽管发生了这种情况,但列表仍然是空的,用户必须强制关闭应用程序以使其再次运行。

以下行显示调用方法时输入if和21个交易添加到适配器。不幸的是,该列表对用户来说是空的。

05-23 01:52:32.879: D/UPDATE_DEAL_LIST(3478): Notified list  created new21

3 个答案:

答案 0 :(得分:0)

我真的不知道这是否会有所帮助,但是以下方法应该根据其子项调整列表大小。我不明白为什么有时notifyDataSetChanged()不起作用,列表根本不会改变,但使用它代替了我的问题。

    public static class Utility {
    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            return;
        }


        int totalHeight = 0;
        int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        int newHeight = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        if (newHeight >= 100)
            params.height = newHeight;  
        else 
            params.height = 100;
        listView.setLayoutParams(params);
        listView.requestLayout();
    }
}

希望它有所帮助!

答案 1 :(得分:0)

您可以尝试以下一个或多个选项

  • 在设置列表适配器之前尝试调用setListShown(false)

  • 否则,请执行 setListShown(false);
    setListAdapter(null);

  • 否则,请执行requestLayout()

答案 2 :(得分:0)

一个想法(相当长的镜头:)

如果应用程序本身没有被杀死,只是活动,系统会尝试重新创建活动的最后一个状态,调用onRestoreInstanceState()。 如果应用程序被杀死,则不会调用此方法 - 因此这是两者之间的重大差异之一。

ListActivity会覆盖onRestoreInstanceState()。在它继续之前,它确保列表存在。如果列表不存在,则会将其从默认位置膨胀。

如果您在onResume()中设置contentView,请尝试将其移至onCreate(),这可能会解决问题。

如果我看到了Activty的代码,我可以提供更多帮助。