web-dev-qa-db-fra.com

getLoaderManager (). initLoader () n'accepte pas 'this' comme argument bien que la classe (ListFragment) implémente LoaderManager.LoaderCallbacks <Cursor>

J'ai du mal à suivre un guide sur l'utilisation de SQLite dans Android. J'utilise un ListFragment au lieu d'un ListActivity (comme dans l'exemple), j'ai donc à la place ListFragment implémente LoaderManager.LoaderCallbacks<Cursor>. Ensuite, dans la méthode fillData() dans le 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);
}

Je reçois l'erreur:

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

sur la ligne marquée même si this implémente LoaderManager.LoaderCallbacks<Cursor>.

Merci pour vos idées.

63
vurp0

Vous n'utilisez pas les implémentations appropriées de CursorLoader et Loader. Supprimez vos anciennes importations et utilisez-les:

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

Mais j'ai le même problème en utilisant SherlockActionBar: Comme je dois étendre SherlockListActivity il n'y a PAS de méthode getSupportLoadManager().

Des idées à ce sujet?

EDIT: suivez ce tutoriel si vous ne savez pas comment utiliser des fragments. Créez une nouvelle classe avec SherlockFragment étendu et déplacez-y votre logique d'affichage. Faites étendre votre ancienne activité SherlockFragmentActivity et affichez le SherlockFragment nouvellement créé. De cette façon, je l'ai fait fonctionner. Merci à @JakeWharton!

82
Matthias B

Quelques points à surveiller (d'après ma récente expérience dans ce domaine):

  1. Si votre minSDK est défini sur moins de 11 (c'est-à-dire le niveau 10 pour Gingerbread) et que vous utilisez le Support Pack pour une compatibilité descendante, assurez-vous d'utiliser

    getSupportLoaderManager().initLoader(LOADER_ID, null, this);
    
  2. Vous l'avez mentionné lorsque vous avez dit que vous utilisiez ListFragment, mais cela mérite d'être répété: ne prolongez pas l'activité, sinon le package de support ne fonctionnera pas. Au lieu de cela, étendez la classe FragmentActivity ou la classe ListFragment.

  3. Pour vos importations, assurez-vous d'utiliser les versions correctes si votre minSDK <11:

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

J'espère que cela vous aide ... ou au moins quelqu'un d'autre ...

59
wileyCoyote

La diffusion du troisième argument a résolu le problème dans mon cas:

de

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

à

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

Remarque:

  1. minSdk avait 8 ans et j'utilisais la bibliothèque de support v4.
  2. (Android.support.v4.app.LoaderManager.LoaderCallbacks<Cursor>) this) N'a pas fonctionné.
  3. getSupportLoaderManager() or getSupportLoadManager() n'a pas fonctionné.
  4. Ce code était à l'intérieur de l'activité non fragmentée
9
Dexter

Modifiez vos importations en

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

et utilise

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

Il est tard mais peut-être aider quelqu'un.
si vous utilisez Loader Maneger en fragment et que votre api min est inférieure à HONEYCOMB
vous devez utiliser ces importations

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;

et pour lancer le chargeur, utilisez ce code

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

espérons que cela aide quelqu'un.

3
max

Dans mon cas, je devais avoir mon activité étendre ActionBarActivity à partir du package Android.support.v7.app. J'ai pu ensuite utiliser

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

2
Oladipo Olasemo

Mon erreur était due à ceci:

//import Android.app.ListFragment; Error when doesnt import from support.v4
import Android.support.v4.app.ListFragment;
2
Renan Franca

J'utilise ActionBarSherlock avec mon application et j'ai également rencontré ce problème et j'ai suivi toutes les étapes discutées par d'autres dans cette question. Cependant, je continuais à avoir le même problème après avoir essayé toutes les résolutions suggérées.

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

Le problème était que je m'attendais à ce qu'Eclipse me dise quand je manquais quelque chose et cela me le disait mais pas de la façon dont j'étais habitué. Dans d'autres cas, Eclipse me disait généralement qu'il me manquait les remplacements pour que quelque chose fonctionne, mais ce n'est pas directement le cas ici. J'ai finalement détecté que le "LoaderManager.LoaderCallbacks" était le problème et j'ai réalisé que je n'avais aucun rappel pour cela, donc cette erreur était en fait une erreur très valide. L'ajout des remplacements de base a résolu mon problème et m'a permis d'avancer.

// 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);
}
1
brentil

J'avais un problème similaire où mon AsyncTaskLoader ne renvoyait pas ma liste, mais ma résolution était de changer l'appel de .initLoader en .restartLoader.

J'ai donc jamais appelé .initLoader et immédiatement appelé .restartLoader.

J'avais un écouteur onListItemClick dans mon fragment et à chaque fois retiré du fragment et rechargé onListItemClick et parcouru l'application, il n'arrêtait pas de planter.

Cela pourrait être spécifique à mon application, mais j'espère que cela aidera les autres s'ils ont des problèmes de rechargement de backstack de fragments.

Cela faisait partie d'une partie du gestionnaire de fichiers dans mon application, il est donc spécifique de cliquer sur plusieurs onListItemClicks dans le fragment que vous chargez.

1
Zachariah Rabatah

Après un long sacrifice, j'ai obtenu cette solution si vous utilisez des fragments, utilisez simplement ce code.

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

j'espère que cela vous est utile

0
Bilal Qasim

J'utilise minSDK 27 et j'ai eu le même problème, j'ai essayé de caster comme le suggère @Dexter, mais cela a donné une erreur disant cannot be cast to Android.app.LoaderManager$LoaderCallbacks, j'ai donc essayé d'utiliser différentes instructions d'importation et cela a fonctionné. J'ai commenté le v4 versions et voici ce que j'ai maintenant et l'application fonctionne:

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

Je ne sais pas trop quand/comment le v4 les versions ont été importées.

0
thehme

Ran dans le même problème. Mon minSdkVersion est 14, donc je ne peux pas utiliser le package Android.support.v4.

Je l'ai compris en étendant LoaderCallbacks, au lieu de LoaderManager.LoaderCallbacks et en utilisant ces packages

import Android.app.LoaderManager.LoaderCallbacks;  
import Android.content.CursorLoader;  
import Android.database.Cursor;  
import Android.widget.SimpleCursorAdapter;
0
Dino Tw

Essayez ces 2 lignes cela fonctionnera

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

loaderManager.initLoader(LOADER_ID, null,  this);
0
tarun mittal

J'ai contourné cela en utilisant un SherlockListFragment (ou vous pouvez utiliser ListFragment, je suppose), mais le contenir dans une activité. J'ai d'abord créé une classe générique FragmentHolderActivity qui ressemble à ceci:

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);
        }
    }

}

Ensuite, vous devez créer un fichier XML pour votre fragment.

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" />

Et voici le code que vous utilisez pour démarrer le fragment:

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

Vous dites simplement à FragmentHolderActivity d'utiliser la disposition your_list_fragment, qui à son tour charge YourListFragment.Java

Vous pouvez ensuite utiliser: getSherlockActivity().getSupportLoaderManager().initLoader(...) dans YourListFragment.Java

Je ne sais pas si c'est l'approche correcte, mais elle conserve toute ma logique dans Fragments, ce qui est bien.

0
Joony

Si vous avez essayé toutes les méthodes ci-dessus et que vous rencontrez toujours la même erreur avec le paramètre "this", procédez comme suit:

  1. Accédez aux paramètres et activez l'option d'importation à la volée (par défaut, elle sera activée et vous pouvez le faire en utilisant les touches Alt + Entrée).

  2. Couper tout le code de l'activité qui avait mis en place
    LoaderCallback ... et collez-le dans un éditeur de texte.

  3. Enfin, copiez tout le code de cette activité depuis l'éditeur de texte où vous avez collé, sans aucune commande d'importation (uniquement le code de la classe/activité).

  4. Vous obtiendrez de nombreuses erreurs car vous n'avez encore rien importé. Appuyez simplement sur Alt + Entrée partout où vous obtenez les erreurs et ses bibliothèques seront importées automatiquement. Remarque: Choisissez la bibliothèque Android.app ... pour CursorLoaders.

0
Saurabh Singh