getLoaderManager().initLoader() не принимает 'this' в качестве аргумента, хотя класс (ListFragment) реализует LoaderManager.LoaderCallbacks<Cursor>

У меня проблемы с выполнением инструкции по использованию SQLite в Android. Я использую 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>,

Спасибо за любые идеи.

20 ответов

Решение

Вы не используете правильные реализации CursorLoader а также Loader, Удалите старый импорт и используйте следующие:

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(),

Есть идеи по этому поводу?

РЕДАКТИРОВАТЬ: следуйте этому руководству, если вы не знаете, как использовать фрагменты. Создайте новый класс с расширением SherlockFragment и переместите туда свою логику отображения. Сделайте ваше старое действие расширенным SherlockFragmentActivity и покажите вновь созданный SherlockFragment. Таким образом, я получил это работает. Спасибо @JakeWharton!

Несколько вещей, на которые стоит обратить внимание (из моего недавнего опыта борьбы с этим):

  1. Если для вашего minSDK установлено значение меньше 11 (т. Е. Уровень 10 для Gingerbread) и вы используете пакет поддержки для обратной совместимости, убедитесь, что вы используете

    getSupportLoaderManager().initLoader(LOADER_ID, null, this);
    
  2. Вы упомянули это, когда сказали, что используете ListFragment, но стоит повторить: не расширяйте Activity, иначе пакет поддержки не будет работать. Вместо этого расширьте класс FragmentActivity или класс ListFragment.

  3. При импорте убедитесь, что вы используете правильные версии, если ваш minSDK < 11:

     android.support.v4.app.FragmentActivity;
     android.support.v4.app.LoaderManager;
     android.support.v4.content.Loader;
    

Надеюсь, это поможет вам... или, по крайней мере, кому-то еще...

Приведение третьего аргумента решило проблему в моем случае:

от

 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. Этот код был внутри активности, а не фрагмент

Уже поздно, но, возможно, поможет кому-нибудь.
если вы используете загрузчик менеджер во фрагменте, и вы мин. API ниже HONEYCOMB
Вы должны использовать этот импорт

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*/);

надеюсь, это поможет кому-нибудь.

Вот что у вас есть:

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

Вот что у вас должно получиться:

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

Причина, по которой первый не работает:

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

Измените ваш импорт на

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

и использовать

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

В моем случае мне нужно было, чтобы моя активность расширяла ActionBarActivity из пакета android.support.v7.app. Я был тогда в состоянии использовать

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

Моя ошибка была из-за этого:

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

У меня была похожая проблема, когда мой AsyncTaskLoader не возвращал мой список, но я решил изменить вызов с.initLoader на.restartLoader.

Поэтому я никогда не вызывал.initLoader и сразу же вызывал.restartLoader.

У меня был прослушиватель onListItemClick в моем фрагменте, и каждый раз, когда он возвращался из фрагмента, перезагружал onListItemClick и просматривал приложение, в котором он продолжал падать.

Это может быть просто для моего приложения, но, надеюсь, это поможет другим, если у них возникнут проблемы с перезагрузкой фрагмента.

Это было частью файлового менеджера в моем приложении, так что это специфическое нажатие на несколько onListItemClicks во фрагменте, который вы загружаете.

Я использую ActionBarSherlock с моим приложением, и я также столкнулся с этой проблемой и прошел все шаги, которые обсуждали другие в этом вопросе. Однако у меня продолжала возникать та же проблема после пробования всех предложенных резолюций.

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

Проблема заключалась в том, что я ожидал, что "Затмение" расскажет мне, когда я что-то упустил, и это говорило мне об этом, но не так, как я привык. Обычно 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);
}

0

После долгой жертвы я получил это решение, если вы используете фрагменты, тогда просто используйте этот код.

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

я надеюсь, что это полезно для вас

Я пытался позвонить initLoader()внутри деятельности. Для меня это сработало

изменение

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

к

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

Если вы попробовали все вышеперечисленные методы и все еще сталкиваетесь с той же ошибкой с параметром "this", выполните следующие действия:

  1. Зайдите в настройки и включите импорт на лету (по умолчанию он будет включен, и вы можете сделать это с помощью клавиш Alt+Enter).

  2. Вырежьте весь код действия, которое было реализовано
    LoaderCallback... и вставьте его в текстовом редакторе.

  3. Затем, наконец, скопируйте весь код этого действия из текстового редактора, в который вы вставили, без каких-либо команд импорта (только код класса / действия).

  4. Вы получите много ошибок, поскольку вы еще ничего не импортировали. Просто нажмите Alt+Enter, где бы вы ни получали ошибки, и их библиотеки будут импортированы автоматически. Примечание: выберите android.app... библиотеку для CursorLoaders.

Попробуйте эти 2 строки, это будет работать

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

loaderManager.initLoader(LOADER_ID, null,  this);

Столкнулся с той же проблемой. Мой 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;

Если вы используете API 29, вместо getLoaderManager используйте:

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

Использовать

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

Если вы используете API 28 или новее, вместо getLoaderManager использование:

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

Я использую minSDK 27, и у меня была та же проблема, я пытался разыграть как @Dexter предложить, но это выдало ошибку, сказав cannot be cast to android.app.LoaderManager$LoaderCallbacksЯ попытался использовать различные операторы импорта, и это сработало. Я закомментировал 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 версии были импортированы.

Я справился с этим с помощью 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

Затем вы можете использовать: getSherlockActivity().getSupportLoaderManager().initLoader(...) в YourListFragment.java

Не уверен, что это правильный подход, но он сохраняет всю мою логику во фрагментах, что приятно.

Другие вопросы по тегам