为什么我的适配器变为空?

时间:2014-04-05 10:50:17

标签: android android-fragments android-listview android-cursoradapter fragmentpageradapter

我试图制作一个会定期更新的ListFragment(此处未显示更新的调用,但更新功能是)。这是我见过的日志猫:

04-05 11:05:44.252: V/QslLogFrag(2690): onCreate()
04-05 11:05:44.256: V/QslLogFrag(2690): onCreateView()
04-05 11:05:44.304: V/QslLogFrag(2690): onActivityCreate()
04-05 11:05:44.612: V/QslLogFrag(2690): null
04-05 11:05:44.736: V/QslLogFrag(2690): com.kd7uiy.qslmapper.QslLogAdapter@5282f55c
04-05 11:05:47.948: V/QslLogFrag(2690): null

最后3行行都在updateView类中提供,当需要检查新数据时,会在外部调用。前两个基本上是自动调用的,第三个是由用户输入调用的。

代码:

public class QslLogFragment extends ListFragment {

    private CursorAdapter mAdapter;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        getListView().setFastScrollEnabled(true);
        Cursor cursor = QslDatabase.getInstance(getActivity()).getTableQuery(
                mFilters);
        mAdapter= new QslLogAdapter(getActivity(), cursor, 0);
        setListAdapter(mAdapter);
        Log.v(TAG,"onActivityCreate()");
    }

    public void updateView() {
        Cursor cursor = QslDatabase.getInstance(getActivity()).getTableQuery(
                mFilters);
        Log.v(TAG,""+getListAdapter());
        if (getListAdapter() != null) {
            ((CursorAdapter) getListAdapter()).changeCursor(cursor);
        }
    }

在某种程度上,在我看来好像适配器被设置为null。注意我仍然可以毫无问题地滚动ListView,但我无法使用一组新的过滤器更新它。任何想法发生了什么?

注意,QslAdapter扩展了CursorAdapter,我使用了支持库CursorAdapter。

以下是我尝试的一系列事项:

  1. 我尝试过使用setListAdaptergetListAdapter
  2. 我尝试过不使用getListAdapter,只是保留对mAdapter的引用。
  3. 我已经确认此片段只有一个实例。
  4. 我没有在任何地方致电setListAdapter
  5. 我已验证getListAdaptermAdapter始终报告相同的指针,或为空。

2 个答案:

答案 0 :(得分:3)

如果@commonsware不介意,我会把它放到繁荣的答案中。虽然我确定他是否有任何进一步的见解,但他会创造一个更好的答案。


我觉得你可以处理QslLogFragment的多个副本。我以前遇到过类似的问题。

在这种情况下,记录您的方法调用是个好主意,就像您所做的那样。如果适配器“不可能”不同,那就是有2个片段的暗示,因此也建议记录片段。

将额外的日志放入所有活动&片段生命周期方法,以追踪拼图的最后一块。这看起来有点矫枉过正,但你可能会发现一些惊喜。


在我提醒过的情况下,我的代码基于Android SDK示例,每次我尝试访问它时都会创建一个新的片段。我没有缓存以前创建的任何片段。因此,请检查检索(或创建)片段的代码。

以下是我FragmentPagerAdapter的代码,每次都会创建一个新的代码片段。这是错误的代码,我不推荐它,但是现在它在它来自的演示中起到了它的作用。

public Fragment getItem(int position)
{
    // TODO don't create a new fragment each time this is called
    switch (position)
    {
        case 0:
        {
            return new WindFragment();
        }
        // more cases... etc...
        default:
        {
            return new TemperatureFragment();
        }
    }
}

每次用户翻到新页面时都会调用此方法,以显示不同的片段。此代码导致的问题与您的问题非常相似。

答案 1 :(得分:1)

我的问题非常接近理查德的答案,但我会发布更好的代码版本。

我一直在使用名为TabsAdapter的函数来管理我的FragementPager。默认代码是:

    @Override
    public Fragment getItem(int position) {
        TabInfo info = mTabs.get(position);
        return Fragment.instantiate(mContext, info.clss.getName(), info.args);
    }

我使用getItem函数(我的私有侦听器)设置了代码的监听器,因此实际上是在创建一个新的片段!

解决方案是使用WeakHashMap来存储片段的先前实例,因此如果我不必,我就不会重新创建它们!

WeakHashMap<Integer,Fragment> mFragmentMap;

@Override
public Fragment getItem(int position) {
    TabInfo info = mTabs.get(position);
    if (mFragmentMap.get(position)==null){
        mFragmentMap.put(position,Fragment.instantiate(mContext, info.clss.getName(), info.args));
    }
    return mFragmentMap.get(position);
}