带有SQLiteCursorLoader的ExpandableListView和SimpleCursorTreeAdapter,未调用getChildrenCursor

时间:2012-12-24 05:58:19

标签: java android expandablelistview android-cursorloader

我首先要说的是我已经研究过这个特定的死亡解决方案,并且我知道解决方案"this has been solved HERE"HERE,但我无法让这些解决方案工作。其他信息:我正在使用兼容性库以及actionbarsherlock,它们都运行良好,没有任何问题,我不这么认为。

我有一个SQLite数据库,我希望将我的条目填入按日期分组的可扩展列表中。我知道我的数据库已正确填充,这里是我已经验证包含正确数据的列:

ID  (1, 2, 3, 4, etc)

TITLE (some text)

URL  (url as string)

DATE (ddMMyyyy)

其中日期列数据如下:22Dec2012或23Dec2012等。

每个日期有很多条目,我想将这些条目分组为日期作为组的子项。我看到数据库中填充了正确的信息。我有一些问题,主要是我的getChildrenCursor永远不会被调用,只有构造函数被调用。其次是根据链接的示例,我无法将getSherlockActivity上下文放入我的适配器中(getActivity()也不能正常工作,仅用于测试目的)。我将在下面用logcat解释错误。

我的片段

public class MyFragment extends SherlockFragment implements LoaderManager.LoaderCallbacks, OnItemClickListener {    

public static MyFragment newInstance(String symbol) {
    MyFragment f = new MyFragment();

    Bundle args = new Bundle();
    args.putString(Consts.INFO, info);
    f.setArguments(args);

    return f;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View myView = inflater.inflate(R.layout.fragment_layout3, container, false);
    mListView = (ExpandableListView)myView.findViewById(R.id.expandableListView);
    mListView.setOnItemClickListener(this);
    return myView;
}    

@Override
public void onPause() {
    super.onPause();

}    

@Override
public void onResume() {
    super.onResume();

    refresh();
}

public void refresh() {
    Log.v(TAG, "refresh");

    populateExpandableList();

    loader = getLoaderManager().getLoader(-1);
    if (loader != null && !loader.isReset()) {
      getLoaderManager().restartLoader(-1, null, this);
    } else {
      getLoaderManager().initLoader(-1, null, this);
    }

    if (getLoaderManager().getLoader(0x9999) == null) {
        getLoaderManager().initLoader(0x9999, null, this);
        //getLoaderManager().initLoader(-1, null, this);
    }
    else {
        getLoaderManager().restartLoader(0x9999, null, this);
        //getLoaderManager().restartLoader(-1, null, this);
    }
    getLoaderManager().getLoader(0x9999).forceLoad();
    //getLoaderManager().getLoader(1).forceLoad();
}

private void populateExpandableList() {
    // Set up our adapter
    Log.v(TAG, "Endtering setup adapter");
    mDbHelper = new DBHelper(getSherlockActivity(), DBConstants.DATABASE_NAME, null, DBConstants.DATABASE_VERSION);
    mAdapter = new MyExpandableAdapter(getSherlockActivity(), this, 
      R.layout.news_list_group,
      R.layout.news_list_child,
      new String[] { DBConstants.DATE_GROUP_NAME }, // Name for group layouts
      new int[] { R.id.group_title },
      new String[] { DBConstants.TITLE_NAME, DBConstants.URL_NAME }, // Name for child layouts
      new int[] { R.id.item_title, R.id.item_value });

    mListView.setAdapter(mAdapter);
  }    

@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
    // TODO Auto-generated method stub      
}   

@Override
public Loader onCreateLoader(int loaderId, Bundle args) {
    topics = new ArrayList<String>();

    if (loaderId == 0x9999) {
        return new MyLoader(getSherlockActivity(), mHandler, topics.toArray(new String[topics.size()]));
    }
    if (loaderId != -1 && loaderId != 0x9999) {
        Log.v(TAG, "CreateLoader child cursor: loader ID: "+loaderId);
        // child cursor
        mCursorLoader = new SQLiteCursorLoader(getSherlockActivity(), mDbHelper, "SELECT _ID, "+DBConstants.TITLE+", " +DBConstants.URL + ", " + DBConstants.TIME + ", " + DBConstants.STATUS + " FROM "+DBConstants.TABLE+" WHERE "+  DBConstants.KEY_ID+"="+String.valueOf(loaderId)+" ORDER BY "+DBConstants.TIME+" DESC", null);
        return mCursorLoader;
    }       
    else if (loaderId != 0x9999) {
        Log.v(TAG, "CreateLoader group cursor: loader ID: "+loaderId);
        // group cursor
        mCursorLoader = new SQLiteCursorLoader(getSherlockActivity(), mDbHelper, "SELECT date, "+DBConstants.TITLE+", "+DBConstants.URL+" FROM "+DBConstants.TABLE, null);
        return mCursorLoader;
    }

    return null;
}

@Override
public void onLoadFinished(Loader loader, Object result) {
    Log.v(TAG, "onLoadFinished");
    if(result != null /*&& result.length > 0*/) {
        if (loader.getId() == 0x9999) {
            getLoaderManager().restartLoader(-1, null, this);
            getLoaderManager().getLoader(-1).forceLoad();

        }
        if (loader.getId() != -1 && loader.getId() != 0x9999) {
            Log.v(TAG, "LoadFinished second loader: loaderID: "+loader.getId());
            if (!((Cursor) result).isClosed()) {
                Log.v(TAG, "data.getCount() " + ((Cursor) result).getCount());

                HashMap<Integer,Integer> groupMap = mAdapter.getGroupMap();
                try {
                    int groupPos = groupMap.get(loader.getId());
                    Log.v(TAG, "onLoadFinished() for groupPos " + groupPos);
                    mAdapter.setChildrenCursor(groupPos, (Cursor) result);
                } catch (NullPointerException e) {
                    Log.w("DEBUG","Adapter expired, try again on the next query: "
                    + e.getMessage());
                }
            }
            else {
                mAdapter.setGroupCursor((Cursor) result);
            }
        }
        else {

        }
    }
}

@Override
public void onLoaderReset(Loader loader) {
    int id = loader.getId();
    Log.v(TAG, "onLoaderReset() for loader_id " + id);
    if (id != -1) {
        // child cursor
        try {
            mAdapter.setChildrenCursor(id, null);
        } catch (NullPointerException e) {
            Log.w("TAG", "Adapter expired, try again on the next query: "
                    + e.getMessage());
        }
    } else {
      mAdapter.setGroupCursor(null);
    }
}



public class MyExpandableAdapter extends SimpleCursorTreeAdapter  {
    private final String TAG = getClass().getSimpleName().toString();
    private MyFragment mFragment;
    protected HashMap<Integer, Integer> mGroupMap = null;

    public NewsFeedExpandableAdapter(Context context, MyFragment mf, int groupLayout, int childLayout, String[] groupFrom,
            int[] groupTo, String[] childrenFrom, int[] childrenTo) {
        super(context, null, groupLayout, groupFrom, groupTo, childLayout, childrenFrom, childrenTo);       
        mFragment = mf;
        mGroupMap = new HashMap<Integer, Integer>();
        Log.v(TAG, "Adapter constructor");
    }

    @Override
    protected Cursor getChildrenCursor(Cursor groupCursor) {        
        // Given the group, we return a cursor for all the children within that group
        Log.v(TAG, "getChildrenCursor");
        int groupPos = groupCursor.getPosition();
        int groupId = groupCursor.getInt(groupCursor.getColumnIndex(DBConstants.TIME_GROUP_NAME));
        Log.v(TAG, "getChildrenCursor() for groupPos " + groupPos);
        Log.v(TAG, "getChildrenCursor() for groupId " + groupId);

        mGroupMap.put(groupId, groupPos);

        Loader loader = mFragment.getLoaderManager().getLoader(groupId); 
        if ( loader != null && !loader.isReset() ) { 
            mFragment.getLoaderManager().restartLoader(groupId, null, mFragment); 
        } else { 
            mFragment.getLoaderManager().initLoader(groupId, null, mFragment); 
        } 

        return null;    
    }

    //Accessor method
    public HashMap<Integer, Integer> getGroupMap() {
        return mGroupMap;
    }
}

}

现在在上面的适配器中,你看到我正在使用:

Loader loader = mFragment.getLoaderManager().getLoader(groupId); 
        if ( loader != null && !loader.isReset() ) { 
            mFragment.getLoaderManager().restartLoader(groupId, null, mFragment); 
        } else { 
            mFragment.getLoaderManager().initLoader(groupId, null, mFragment); 
        } 

而不是:

Loader loader = getSherlockActivity().getLoaderManager().getLoader(groupId); 
        if ( loader != null && !loader.isReset() ) { 
            getSherlockActivity().getLoaderManager().restartLoader(groupId, null, mFragment); 
        } else { 
            getSherlockActivity().getLoaderManager().initLoader(groupId, null, mFragment); 
        } 

因为当我使用getActivity或getSherlockActivity时,代码在上面的第一行给出错误说:

"Type mismatch, cannot convert from Loader<Object> to Loader"

以及第三和第五行错误:

"The method restartLoader(int, Bundle, LoaderManager.LoaderCallbacks<D>) in the type LoaderManager is not applicable for the arguments (int, null, MyFragment)"

有谁可能知道为什么我不能在这里使用getActivity?这让我完全疯狂。所以我尝试使用mFragment.getLoaderManager而不是使用传入适配器的片段,但我不知道这是否正确。

我在代码中放置了断点,它表明调用了适配器构造函数,就是这样,getChildrenCursor永远不会被调用。在片段断点中,它达到“Create Group Loader id = -1”就可以了。在onLoadFinished中,只有第一个“onLoadFinished”标记在日志中显示。它永远不会进入onLoadFinished中的IF语句。当我在logcat中检查loadFinished结果是否为空时,它显示为传入onLoadFinished的游标对象,但是某些东西不能正常工作。

在尝试可扩展列表之前,我正在使用这些相同的SQLiteCursorLoader设置,只检索所有列,并且它们工作正常。我绝对承认,也许我的SELECT语句都不正确。但我已经尝试了大量不同的选择查询,每次我得到相同的结果,什么也没有。任何人都可以帮助我,我绝望和疯狂。感谢。

0 个答案:

没有答案