getLoaderManager()。initLoader()不接受'this'作为参数,尽管类(ListFragment)实现了LoaderManager.LoaderCallbacks <cursor> </cursor>

时间:2012-06-22 12:00:35

标签: android sqlite android-loadermanager android-listfragment

我在Android中使用SQLite guide时遇到问题。我使用ListFragment而不是ListActivity(如示例中所示),因此我使用了ListFragment工具LoaderManager.LoaderCallbacks<Cursor>。然后,在fillData()中的ListFragment方法:

private void fillData() {
    // Fields from the database (projection)
    // Must include the _id column for the adapter to work
    String[] from = new String[] { NotesSQLiteHelper.COLUMN_TITLE };
    // Fields on the UI to which we map
    int[] to = new int[] { R.id.label };

    getLoaderManager().initLoader(0, null, this); //error
    adapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.notes_row, null, from, to, 0);
    setListAdapter(adapter);
}

我收到错误:

The method initLoader(int, Bundle, LoaderManager.LoaderCallbacks<D>) in the type LoaderManager is not applicable for the arguments (int, null, NotesActivity.ArrayListFragment)
即使this实现了LoaderManager.LoaderCallbacks<Cursor>

也会在标记的行上显示。

感谢您的任何想法。

18 个答案:

答案 0 :(得分:82)

您没有使用CursorLoaderLoader的正确实现。 删除旧的导入并使用这些导入:

import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;

但是使用SherlockActionBar我有同样的问题: 由于我必须扩展SherlockListActivity,因此没有方法getSupportLoadManager()

有关于此的任何想法吗?

编辑:如果您不知道如何使用片段,请关注this tutorial。使用扩展SherlockFragment创建一个新类,并在那里移动您的显示逻辑。让您的旧活动扩展SherlockFragmentActivity并显示新创建的SherlockFragment。这样我就搞定了。感谢@JakeWharton!

答案 1 :(得分:59)

需要注意的一些事项(根据我最近与此斗争的经历):

  1. 如果您的minSDK设置为小于11(即Gingerbread的10级)并且您使用支持包以实现向后兼容性,请确保使用

    getSupportLoaderManager().initLoader(LOADER_ID, null, this);
    
  2. 当你说你正在使用ListFragment时,你提到了这一点,但它需要重复:不要扩展Activity,否则支持包将不起作用。而是扩展FragmentActivity类或ListFragment类。

  3. 对于您的导入,如果您的minSDK

     android.support.v4.app.FragmentActivity;
     android.support.v4.app.LoaderManager;
     android.support.v4.content.Loader;
    
  4. 希望这可以帮助你...或者至少是其他人...

答案 2 :(得分:9)

在我的案例中,转换第三个参数解决了问题:

来自

 getLoaderManager().initLoader(0, null, this);

 getLoaderManager().initLoader(0, null, (android.app.LoaderManager.LoaderCallbacks<Cursor>) this);

注意:

  1. minSdk是8,我正在使用支持库v4。
  2. (android.support.v4.app.LoaderManager.LoaderCallbacks<Cursor>) this) 没用。
  3. getSupportLoaderManager() or getSupportLoadManager() 没用。
  4. 此代码内部活动不是片段

答案 3 :(得分:3)

现在已经很晚了但也许可以帮助一些人 如果你在片段中使用装载器maneger,你最小api低于HONEYCOMB
你shuld使用这个导入

import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;      
import android.support.v4.app.Fragment;

并且对于启动加载器使用此代码

getActivity().getSupportLoaderManager().initLoader(/loader stuff*/);

希望这对某人有所帮助。

答案 4 :(得分:3)

将导入更改为

import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;

并使用

getSupportLoaderManager().initLoader(0, null, this);

答案 5 :(得分:2)

我的错误是因为:

//import android.app.ListFragment; Error when doesnt import from support.v4
import android.support.v4.app.ListFragment;

答案 6 :(得分:2)

在我的情况下,我必须让我的Activity扩展来自android.support.v7.app包的ActionBarActivity。然后我就可以使用

getSupportLoaderManager()。initLoader(0,null,this);

答案 7 :(得分:1)

我正在使用ActionBarSherlock和我的应用程序,我也遇到了这个问题并完成了其他人在这个问题中讨论的所有步骤。但是,在尝试所有建议的解决方案后,我仍然遇到同样的问题。

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

问题是我已经陷入期待Eclipse告诉我什么时候我错过了什么并告诉我,但不是我习惯的方式。通常情况下,Eclipse在其他情况下会告诉我,我错过了使某些工作成功的覆盖,但这并不是直接说到这里。我终于选择了“LoaderManager.LoaderCallbacks”作为问题,并意识到我没有回调,因此这个错误实际上是一个非常有效的错误。添加基本​​覆盖解决了我的问题并允许我继续前进。

// Creates a new loader after the initLoader () call
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
  // do work
  return null;
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
  adapter.swapCursor(data);
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
  // data is not available anymore, delete reference
  adapter.swapCursor(null);
}

答案 8 :(得分:1)

我有一个类似的问题,我的AsyncTaskLoader没有返回我的List,但我的解决方法是将.initLoader的调用更改为.restartLoader。

所以我实际上从不调用.initLoader并立即调用.restartLoader。

我的片段中有一个onListItemClick侦听器,每次从片段中退出并重新加载onListItemClick并在应用程序中导航它一直崩溃。

它可能只是特定于我的应用程序,但希望它有助于其他人,如果他们有片段堆栈重新加载问题。

这是我的应用程序中文件管理器部分的一部分,因此它特定于单击要加载的片段中的多个onListItemClicks。

答案 9 :(得分:1)

这是您拥有的:

getLoaderManager().initLoader(0, null, this); 

这是您应该拥有的:

LoaderManager.getInstance(this).initLoader(0, null, this);

第一个失败的原因:

/**
 * @deprecated Use
 * {@link LoaderManager#getInstance(LifecycleOwner) LoaderManager.getInstance(this)}.
 */

答案 10 :(得分:0)

遇到同样的问题。我的minSdkVersion是14,所以不能使用android.support.v4包。

我通过扩展LoaderCallbacks而不是LoaderManager.LoaderCallbacks来计算它并使用这些包

import android.app.LoaderManager.LoaderCallbacks;  
import android.content.CursorLoader;  
import android.database.Cursor;  
import android.widget.SimpleCursorAdapter;

答案 11 :(得分:0)

我通过使用SherlockListFragment来解决这个问题(或者我可以使用ListFragment),但是它包含在一个Activity中。我首先创建了一个通用的FragmentHolderActivity类,如下所示:

FragmentHolderActivity.java

public class FragmentHolderActivity extends SherlockFragmentActivity {

    public static final String FRAGMENT_LAYOUT_RESOURCE_ID = "fragment_layout_resource_id";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Integer fragmentLayoutResourceId = getIntent().getIntExtra(FRAGMENT_LAYOUT_RESOURCE_ID, Integer.MAX_VALUE);
        Assert.assertNotSame(fragmentLayoutResourceId, Integer.MAX_VALUE);

        setContentView(fragmentLayoutResourceId);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                return false;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

}

然后,您需要为片段创建XML文件。

your_list_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<fragment
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:name="com.example.YourListFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragment" />

这是用于启动片段的代码:

    Intent intent = new Intent();
    intent.setClass(this, FragmentHolderActivity.class);
    intent.putExtra(FragmentHolderActivity.FRAGMENT_LAYOUT_RESOURCE_ID, R.layout.your_list_fragment);
    startActivity(intent);

您只需告诉FragmentHolderActivity使用your_list_fragment布局,该布局又会加载YourListFragment.java

然后,您可以在YourListFragment.java中使用:getSherlockActivity().getSupportLoaderManager().initLoader(...)

不确定这是否是正确的方法,但它将我的所有逻辑保留在Fragments中,这很不错。

答案 12 :(得分:0)

如果你已经尝试了上述所有方法,并且仍然面临同样的错误,那么&#34;这个&#34;参数,然后按照以下步骤操作:

  1. 转到设置并启用导入选项。(默认为&#39; ll 启用,您可以使用Alt + Enter键执行此操作。

  2. 剪切已实施的活动的整个代码 LoaderCallback ...并将其粘贴到文本编辑器中。

  3. 然后最后从文本编辑器中复制该活动的整个代码 粘贴的地方,没有任何导入命令。(只有代码 课程/活动)。

  4. 由于您尚未导入任何内容,因此会收到很多错误。 只需按下Alt + Enter,即可获得错误及其错误 库将自动导入。 注意:为CursorLoaders选择android.app ...库。

答案 13 :(得分:0)

尝试这两行即可

android.support.v4.app.LoaderManager loaderManager = getSupportLoaderManager();

loaderManager.initLoader(LOADER_ID, null,  this);

答案 14 :(得分:0)

我使用的是minSDK 27,并且遇到了同样的问题,我尝试像@Dexter建议一样进行强制转换,但这给出了一个错误,提示cannot be cast to android.app.LoaderManager$LoaderCallbacks,因此我尝试使用不同的import语句,并且此方法可行。我注释了v4个版本,这就是我现在拥有的,并且该应用程序正在运行:

//import android.support.v4.app.LoaderManager;
import android.app.LoaderManager;
import android.support.v4.app.NavUtils;
//import android.support.v4.content.CursorLoader;
import android.content.CursorLoader;
//import android.support.v4.content.Loader;
//import android.content.Loader;

不确定何时导入v4版本。

答案 15 :(得分:0)

0

经过长时间的牺牲,如果您使用的是片段,我得到了此解决方案,然后只需使用此代码即可。

getActivity().getSupportLoaderManager().initLoader(1, null, YourActivity.this);

我希望这对您有帮助

答案 16 :(得分:0)

如果使用API​​ 28或更高版本,请使用{p> 1代替getLoaderManager

getSupportLoaderManager().initLoader(id, null, this);

答案 17 :(得分:0)

如果您使用API​​ 29,请使用:

getSupportLoaderManager().initLoader(id, null, this);