Заполненный Android список Поиск по базе данных - Как? - PullRequest
0 голосов
/ 30 марта 2011

Я получил ListActivity, который заполняется данными из базы данных.Это действие также позволяет искать данные в базе данных.

DatabaseHelper dbHelper;
SimpleCursorAdapter adapter;
Cursor c;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    final Intent queryIntent = getIntent();
    final String queryAction = queryIntent.getAction();
    if (Intent.ACTION_SEARCH.equals(queryAction)) {
        String searchKeywords = queryIntent.getStringExtra(SearchManager.QUERY);
        doSearch(searchKeywords);
    }
}

@Override
public void onStart() {
    try {
        super.onStart();
        dbHelper=new DatabaseHelper(this);
        c = dbHelper.getAllMagazines();
        startManagingCursor(c);

        adapter = new SimpleCursorAdapter(this,
                android.R.layout.simple_list_item_2, c,
                new String[] {"editionName", "magazineName"},
                new int[] {android.R.id.text1, android.R.id.text2});

        /** Adapter setzen**/
        this.setListAdapter(adapter);
    }
    catch(Exception ex) {
    }
}

Это показывает мне данные из базы данных в ListView.Так что нет проблем здесь.Когда я выполняю поиск, вызывается следующая функция:

private void doSearch(String search) {    
    dbHelper=new DatabaseHelper(this);
    c = dbHelper.searchEditions(getIntent().getStringExtra("search"));
    startManagingCursor(c);

    adapter = new SimpleCursorAdapter(this,
            android.R.layout.simple_list_item_2, c,
            new String[] {"editionName", "magazineName"},
            new int[] {android.R.id.text1, android.R.id.text2});

    this.setListAdapter(adapter);
}

Я установил ListAdapter на новый адаптер с результатами поиска.Но в ResultView of Search он по-прежнему показывает мне все данные из базы данных, которую я получаю в onStart ().Если я отключаю setListAdapter в onStart (), все работает нормально, и он показывает мне searchresulst.

Как я могу сказать ListView показывать результаты поиска, когда ListView уже заполнен данными?

ПОЛНЫЙ КОД:

public class MagazineViewController extends ListActivity { 

    DatabaseHelper dbHelper;
    SimpleCursorAdapter adapter;
    Cursor c;

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

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        final Intent queryIntent = getIntent();
        final String queryAction = queryIntent.getAction();
        if (Intent.ACTION_SEARCH.equals(queryAction)) {
            String searchKeywords = queryIntent.getStringExtra(SearchManager.QUERY);
            doSearch(searchKeywords);
        }
    }

    @Override
    public void onStart() {
        try {
            super.onStart();
            dbHelper=new DatabaseHelper(this);

            c = dbHelper.getAllMagazines();
            startManagingCursor(c);

            Log.d("CURSOR COUNT", ""+c.getCount());

            adapter = new SimpleCursorAdapter(this,
                    android.R.layout.simple_list_item_2, c,
                    new String[] {"editionName", "magazineName"},
                    new int[] {android.R.id.text1, android.R.id.text2});

            this.setListAdapter(adapter);
        }
        catch(Exception ex) {
        }
    }

    private void doSearch(String search) {    
        dbHelper=new DatabaseHelper(this);

        /** Daten aus der Datenbank abfragen**/
        Cursor cur = dbHelper.searchEditions(getIntent().getStringExtra("search"));
        startManagingCursor(cur);

        Log.d("CURSOR COUNT", ""+cur.getCount());

        final ListView view = getListView();
        final SimpleCursorAdapter cursorAdapter = ((SimpleCursorAdapter) view.getAdapter());
        cursorAdapter.changeCursor(cur);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.magazinemenu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.preferences:
                startActivity (new Intent (this, PreferencesViewController.class));
                break;
        }
        return true;
    }
}

LogCat:

 03-30 16:29:43.381: ERROR/AndroidRuntime(546): FATAL EXCEPTION: main
03-30 16:29:43.381: ERROR/AndroidRuntime(546): java.lang.RuntimeException: Unable to start activity ComponentInfo{package/package.MagazineViewController}: java.lang.NullPointerException
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.os.Looper.loop(Looper.java:123)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.ActivityThread.main(ActivityThread.java:4627)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at java.lang.reflect.Method.invokeNative(Native Method)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at java.lang.reflect.Method.invoke(Method.java:521)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at dalvik.system.NativeStart.main(Native Method)
03-30 16:29:43.381: ERROR/AndroidRuntime(546): Caused by: java.lang.NullPointerException
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at package.MagazineViewController.doSearch(MagazineViewController.java:111)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at package.MagazineViewController.onCreate(MagazineViewController.java:40)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     ... 11 more

Код ошибки в строке 111, это cursorAdapter.changeCursor (cur);

Ответы [ 2 ]

1 голос
/ 30 марта 2011

MagazineViewController.class:

public class MagazineViewController extends ListActivity { 

DatabaseHelper dbHelper;
SimpleCursorAdapter adapter = null;
Cursor c;

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

    requestWindowFeature(Window.FEATURE_NO_TITLE);

    final Intent queryIntent = getIntent();
    final String queryAction = queryIntent.getAction();
    if (Intent.ACTION_SEARCH.equals(queryAction)) {
        String searchKeywords = queryIntent.getStringExtra(SearchManager.QUERY);
        doSearch(searchKeywords);
    }

    dbHelper=new DatabaseHelper(this);
}

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

    dbHelper=new DatabaseHelper(this);

    c = dbHelper.getAllMagazines();
    startManagingCursor(c);

    Log.d("CURSOR COUNT", ""+c.getCount());

    adapter = new SimpleCursorAdapter(this,
                android.R.layout.simple_list_item_2, c,
                new String[] {"editionName", "magazineName"},
                new int[] {android.R.id.text1, android.R.id.text2});


    this.setListAdapter(adapter);
}

private void doSearch(String search) {    
    dbHelper=new DatabaseHelper(this);

    Cursor cur = dbHelper.searchEditions(search);
    startManagingCursor(cur);

    Log.d("CURSOR2 COUNT", ""+cur.getCount());

    adapter.changeCursor(cur);
}

DatabaseHelper.class:

public class DatabaseHelper extends SQLiteOpenHelper {

public static final String DATABASE_NAME = "magazineDB";
public static final String TABLE_MAGAZINE = "magazine";
public static final String TABLE_EDITION = "edition";
public static final String TABLE_ARTICLE = "article";
public static final String TABLE_KEYWORDS = "keywords";

public DatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null,1);
}


@Override
public void onCreate(SQLiteDatabase db) {

    db.execSQL("CREATE TABLE " + TABLE_MAGAZINE + " (magazineId INTEGER PRIMARY KEY, " +
"magazineName TEXT);");

    /** Tabelle "Edition" erstellen **/
    db.execSQL("CREATE TABLE " + TABLE_EDITION + " (_id INTEGER PRIMARY KEY AUTOINCREMENT," +
"editionId INTEGER, " +
"editionName TEXT, " +
"editionContent TEXT, " +
"magazine_id INTEGER NOT NULL, " +
"FOREIGN KEY (magazine_id) REFERENCES " + TABLE_MAGAZINE + "(magazineId));");

    db.execSQL("CREATE TRIGGER fki_edition_magazine_id " +
            " BEFORE INSERT ON "+ TABLE_EDITION +
            " FOR EACH ROW BEGIN"+
            " SELECT CASE WHEN ((SELECT magazineId FROM "+ TABLE_MAGAZINE +" WHERE magazineId = new.magazine_id ) IS NULL)"+
            " THEN RAISE (ABORT,'Foreign Key Violation') END;"+
            "  END;");

}


@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS "+TABLE_MAGAZINE);
    db.execSQL("DROP TABLE IF EXISTS "+TABLE_EDITION);
    db.execSQL("DROP TABLE IF EXISTS "+TABLE_ARTICLE);

    db.execSQL("DROP TRIGGER IF EXISTS fki_edition_magazine_id");

    onCreate(db);
}

Cursor getAllMagazines() {
    SQLiteDatabase db=this.getWritableDatabase();
    Cursor cur= db.rawQuery("SELECT * FROM edition, magazine WHERE edition.magazine_id = magazine.magazineId", null);
    return cur; 
}

public Cursor searchEditions (String searchtext) {
    SQLiteDatabase db=this.getWritableDatabase();
    Cursor cur= db.rawQuery("SELECT * FROM edition, magazine WHERE edition.magazine_id = magazine.magazineId AND edition.editionContent LIKE '%" + searchtext + "%'" ,null);

    return cur;
}
0 голосов
/ 30 марта 2011

Попробуйте вызвать SimpleCursorAdapter. changeCursor на существующем адаптере вместо создания нового экземпляра адаптера.

Не думаю, что вам нужны эти строки:

final ListView view = getListView();
final SimpleCursorAdapter cursorAdapter = ((SimpleCursorAdapter) view.getAdapter());

Chage:

cursorAdapter.changeCursor(cur);

Кому:

adapter.changeCursor(cur);
...