2016-11-09 11 views
0

Das ist Code von meinem Fragment, zur Zeit lädt es nichts aus der Datenbank, die definitiv existiert. Ich habe es nach Edmunds Anleitung überarbeitet, indem ich mCursor mit der gesamten Datenbanktabelle an mCursorAdapter übergab, in der Hoffnung, dass onLoadFinished den Adapter das Drucken der Datenbank auf dem Bildschirm aktualisieren würde. Aber onLoadFinished() passiert nichts. Hilfe!Wie bekomme ich eine Datenbank in einem PagerAdapter Fragment angezeigt?

import android.content.ContentValues; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.net.Uri; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.LoaderManager; 
import android.support.v4.content.CursorLoader; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ListView; 

import com.quotes.obama.obamaquotes.data.PetContract.PetEntry; 
import com.quotes.obama.obamaquotes.data.PetDbHelper; 

import static android.content.ContentValues.TAG; 

//import android.content.CursorLoader; 

/** 
* Created by Sam on 30/10/2016. 
*/ 
public class AllQuotesFragment extends Fragment implements 
     LoaderManager.LoaderCallbacks<Cursor> { //}, android.support.v4.app.LoaderManager.LoaderCallbacks<Object> { 

    /** Identifier for the pet data loader */ 
    private static final int PET_LOADER = 0; 

    /** Adapter for the ListView */ 
    PetCursorAdapter mCursorAdapter; 

    /** so know when we have the database ready for display */ 
    static Boolean databaseLoaderComplete = false; 

    public AllQuotesFragment() { 
     // Required empty public constructor 
    } 

    /** 
    * Use this factory method to create a new instance of 
    * this fragment using the provided parameters. 
    * 
    * @return A new instance of fragment GameFragment. 
    */ 
    // TODO: Rename and change types and number of parameters 
    public static AllQuotesFragment newInstance() { 
     AllQuotesFragment fragment = new AllQuotesFragment(); 
     //Bundle args = new Bundle(); 
     //args.putString(TITLE, pageTitle); 
     return fragment; 
    } 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_quotes_all, container, false); 
     // inflate fragment_game into "container", 

     // Find the ListView which will be populated with the pet data 
     ListView petListView = (ListView) rootView.findViewById(R.id.list); 

     // Find and set empty view on the ListView, so that it only shows when the list has 0 items. 
     View emptyView = rootView.findViewById(R.id.empty_view); 
     petListView.setEmptyView(emptyView); 

     /* as per Edmund 
     * http://stackoverflow.com/questions/40517872/how-to-wait-for-cursorloader-to-complete/40530754?noredirect=1#comment68332991_40530754 */ 

     // To access our database, we instantiate our subclass of SQLiteOpenHelper 
     // and pass the context, which is the current activity. 
     PetDbHelper mDbHelper = new PetDbHelper(getContext()); 

     // Create and/or open a database to read from it 
     SQLiteDatabase db = mDbHelper.getReadableDatabase(); 

     // Perform this raw SQL query "SELECT * FROM pets" 
     // to get a Cursor that contains all rows from the pets table. 
     Cursor mCursor = db.rawQuery("SELECT * FROM " + PetEntry.TABLE_NAME, null); 


     // Setup an Adapter to create a list item for each row of pet data in the Cursor. 
     // There is no pet data yet (until the loader finishes) so pass in null for the Cursor. 
     mCursorAdapter = new PetCursorAdapter(getContext(), mCursor); // was null 
     petListView.setAdapter(mCursorAdapter); 

     // TODO Setup the item click listener? 
     Log.w(TAG, "about to initLoader"); 
     // Kick off the loader, need activity to get Context 

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

     Log.w(TAG, "All Quotes UI created, returning "); 
     return rootView; 

    } 
    @Override 
    public android.support.v4.content.Loader<Cursor> onCreateLoader(int i, Bundle bundle) { 
     // Define a projection that specifies the columns from the table we care about. 
     Log.i(TAG, "creating a loader"); 

     String[] projection = { 
       PetEntry._ID, 
       PetEntry.COLUMN_PET_NAME, 
       PetEntry.COLUMN_PET_BREED }; 


     // This loader will execute the ContentProvider's query method on a background thread 
     return new CursorLoader(getContext(), // Parent activity context 
       PetEntry.CONTENT_URI, // Provider content URI to query 
       projection,    // Columns to include in the resulting Cursor 
       null,     // No selection clause 
       null,     // No selection arguments 
       null);     // Default sort order 

    } 

    @Override 
    public void onLoadFinished(android.support.v4.content.Loader<Cursor> loader, Cursor data) { 
     // Update {@link PetCursorAdapter} with this new cursor containing updated pet data 
     mCursorAdapter.swapCursor(data); 
     Log.i(TAG, "database updated"); 
    } 

    @Override 
    public void onLoaderReset(android.support.v4.content.Loader<Cursor> loader) { 
     // Callback called when the data needs to be deleted 
     mCursorAdapter.swapCursor(null); 
     Log.i(TAG, "database reset"); 
    } 

Antwort

1

Das Fragment "gewinnen" sollte kein Problem sein, da onLoadFinished() die Cursor-Daten nach der Anzeige des Fragments laden sollte.

ersetzen:

getActivity().getLoaderManager() 

mit:

getLoaderManager() 

und stellen Sie sicher, dass Sie die Unterstützung LoaderManager mit einem Träger Fragment verwenden.

Geben Sie außerdem den Cursor anstelle von null an den Adapterkonstruktor.

0

Sie benötigen die natürliche Logik zu verwenden, verwenden Sie die Methode onLoadFinished()

+0

Ich habe versucht, die Flagge dort zu ändern, und es wird nie erreicht. Ich habe einen Log in die While-Schleife oben gesetzt und es spuckt einfach das Log in eine Endlosschleife, ich denke, die While-Schleife muss den Loader irgendwie daran hindern, abzuschließen. Gibt es eine andere Art zu warten, bis der Lader fertig ist? Ohne While-Schleife? –

0

[Editiert: Diese Antwort jetzt in den Kommentaren unten stehenden Vorschläge gemacht, so dass es keine Notwendigkeit, die Kommentare zu lesen. ]

Das Fragment "Winning" sollte kein Problem sein, da onLoadFinished() die Cursor-Daten laden sollte, nachdem das Fragment angezeigt wird.

Entfernen Sie die While-Schleife, damit OnCreateView() zurückgeben kann - ich nehme an, dass der Code in onCreateView() angezeigt wird.

Es ist auch wert zu ersetzen:

getActivity().getLoaderManager() 

mit:

getLoaderManager() 

und stellen Sie sicher, dass Sie die Unterstützung LoaderManager mit einem Träger Fragment verwenden.
Geben Sie auch den Cursor anstelle von null in den Adapterkonstruktor.

+0

Es ist nicht notwendig, die Ausführung zu unterbrechen, bis der Loader zurückkehrt. Zeigen Sie einfach die vorherigen Daten oder die leere Ansicht an, idealerweise mit einem 'Laden'-Symbol oder ähnlichem. –

+0

Hey Edmund, danke für deine Zeit. Du hast Recht, ich komme von onCreateView zurück. Wenn ich nicht auf die Rückgabe des Loaders warte, kehrt rootView zurück, und der PagerAdapter zeichnet das Fragment ohne Daten und wird nicht mit den Daten aktualisiert, wenn der Cursor loader beendet ist. 2. Wenn ich getActivity() loswerde, kann ich den Kontext (this) nicht mehr als Argument in initLoader übergeben. Ich würde Ihre Hilfe lieben, ich kann die App nicht mit einer leeren Seite öffnen und die Benutzer dazu zwingen, zu einer anderen Registerkarte zu wischen und dann zurück, um eine mit der Datenbank aktualisierte Ansicht zu erhalten. Vielleicht sollte ich mehr Code posten? –

+1

Wird onLoadFinished() aufgerufen? Ich vermute es ist. Da Sie sich in einem Fragment befinden, ist es sinnvoll, den Fragmentladeprogramm-Manager anstelle des Aktivitätsladeprogramm-Managers aufzurufen (obwohl ich dies noch nie versucht habe). In onActivityCreated() im Fragment sollte getLoaderManager() aufgerufen werden können.initLoader (PET_LOADER, savedInstanceState, this); –

Verwandte Themen