【问题标题】:Can't update ListView using Adapter无法使用适配器更新 ListView
【发布时间】:2014-10-23 15:25:06
【问题描述】:

我有这样的问题。我有一个 ListView,首先我使用适配器从 SQLIte 数据库中填充它。然后我实现了搜索,想把新的搜索数据放到这个ListView中(方法doMySearch),但是我得到了同样的结果——数据没有更新。可以做些什么来修复它?代码如下:

package com.example.citycode;

import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SimpleCursorAdapter;

public class MainActivity extends ActionBarActivity {

  ListView lvData,lvData1;
  DBHelper db;
  SimpleCursorAdapter scAdapter;
  Cursor cursor;
  Cursor cursor1;

  final String LOG_TAG = "myLogs";
  final String LOG_TAG1 = "myLogs1";

  /** Called when the activity is first created. */
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // открываем подключение к БД
    db = new DBHelper(this);
    db.open();

    // Get the intent, verify the action and get the query
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String query = intent.getStringExtra(SearchManager.QUERY);
      doMySearch(query);
    }

    // получаем курсор
    cursor = db.getAllData();
    startManagingCursor(cursor);

    // Формируем столбцы сопоставления
    String[] from = new String[] { DBHelper.COLUMN_r_name, DBHelper.COLUMN_region, DBHelper.COLUMN_code};
    int[] to = new int[] { R.id.city_name, R.id.region_name, R.id.city_code };

    // создааем адаптер и настраиваем список
    scAdapter = new SimpleCursorAdapter(this, R.layout.item, cursor, from, to);
    lvData = (ListView) findViewById(R.id.listdata);
    lvData.setAdapter(scAdapter);
  }

  public void doMySearch(String query) {
        lvData1 = (ListView) findViewById(R.id.listdata);
        //Ищем совпадения
        Log.d(LOG_TAG, "Before get the C");
        cursor1 = db.fetchRecordsByQuery(query);
        Log.d(LOG_TAG, "After get the C");
        String t = Integer.toString(cursor1.getCount());
        Log.d(LOG_TAG, t);
        startManagingCursor(cursor1);
        String[] from = new String[] { DBHelper.COLUMN_r_name, DBHelper.COLUMN_region, DBHelper.COLUMN_code};
        int[] to = new int[] { R.id.city_name, R.id.region_name, R.id.city_code };
        SimpleCursorAdapter scAdapter1;

        scAdapter = new SimpleCursorAdapter(this,
                R.layout.item, cursor1, from, to);

        Log.d(LOG_TAG, "Setting the adapter");
        //Обновляем адаптер
        logCursor(cursor1);
        lvData1.setAdapter(scAdapter);
        Log.d(LOG_TAG, "Adapter was set");
      }

//вывод в лог данных из курсора
 void logCursor(Cursor c) {
   if (c != null) {
     if (c.moveToFirst()) {
       String str;
       do {
         str = "";
         for (String cn : c.getColumnNames()) {
           str = str.concat(cn + " = " + c.getString(c.getColumnIndex(cn)) + "; ");
         }
         Log.d(LOG_TAG1, str);
       } while (c.moveToNext());
     }
   } else
     Log.d(LOG_TAG1, "Cursor is null");
 }



     @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);

        // Associate searchable configuration with the SearchView
        SearchManager searchManager =
               (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView =
                (SearchView) menu.findItem(R.id.action_settings).getActionView();
        searchView.setSearchableInfo(
                searchManager.getSearchableInfo(getComponentName()));

        return true;
    }


  protected void onDestroy() {
    super.onDestroy();
    // закрываем подключение при выходе
    db.close();
  }

}

【问题讨论】:

  • 在您的onCreate 中,您首先使用doMySearch(query) 进行搜索,然后继续使用db.getAllData();,这将覆盖您的搜索结果。对于初学者,请尝试在doMySearch(query) 之后插入return

标签: android sqlite listview android-listview


【解决方案1】:

目前,您可以通过调用db.getAllData() 覆盖您的搜索结果。

由于doMySearch 与您的onCreate 几乎相同,请尝试删除您的doMySearch 并添加以下代码(替换onCreate,添加onNewIntentloadData,执行搜索或加载所有否则数据)。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Get the ListView once.
    lvData = (ListView) findViewById(R.id.listdata);

    // открываем подключение к БД
    db = new DBHelper(this);
    db.open();

    loadData(getIntent());

}

// Also handle calls to onNewIntent.
@Override
protected void onNewIntent(Intent intent) {
    loadData(intent);
}

// Perform a search or load all data.
private void loadData(Intent intent){
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
        cursor = db.fetchRecordsByQuery(query);
    } else {
        cursor = db.getAllData();
    }

    startManagingCursor(cursor);

    // Формируем столбцы сопоставления
    String[] from = new String[] { DBHelper.COLUMN_r_name, DBHelper.COLUMN_region, DBHelper.COLUMN_code};
    int[] to = new int[] { R.id.city_name, R.id.region_name, R.id.city_code };

    // создааем адаптер и настраиваем список
    scAdapter = new SimpleCursorAdapter(this, R.layout.item, cursor, from, to);
    lvData.setAdapter(scAdapter);
}

【讨论】:

  • 非常感谢!现在可以了!但是为什么我不能使用 doMySearch 方法更改 ListView 数据呢?为什么数据没有更新?你的认识是最好的吗?还是为搜索做另一个活动更好?你怎么看?再次感谢!
  • 您也可以使用doMySearch 方法,但在onCreate 中调用它后,您必须确保填充ListView >all 来自数据库的结果(在您的示例中,doMySearch 下面大约三行您开始从数据库中获取所有条目并将它们设置为ListView。它现在的工作方式也减少了冗余代码,这总是一件好事。:)
  • 如果可能的话,能否请您使用 doMySearch 方法显示变体?使用它的唯一方法不是选择所有数据吗?但为什么?您的变体当然要好得多。但我想了解我的问题)
  • 如果您仍想使用doMySearch,只需在onCreate 中调用它之后添加return;,在if 语句结束之前。正如我所说:在onCreate 中,您在数据库中搜索并填写列表,但随后您从数据库中获取所有内容并覆盖列表内容,因此不会显示搜索结果。
  • 如果我的回答对您有帮助,请将其标记为已接受,以便其他有类似问题的人知道如何解决。谢谢! :)
【解决方案2】:

你试过scAdapter.notifyDataSetChanged(); 吗?每当您希望视图反映数据中的更新时,这都是常见的调用。

【讨论】:

  • 我应该在哪里写?你能写下所有的代码吗?问题是我试过了,但可能在错误的地方..
【解决方案3】:

尝试删除lvData1并使用doMySearch中的lvData,然后删除:

lvData1 = (ListView) findViewById(R.id.listdata);

您在onCreated 中有一个findViewById

【讨论】:

    【解决方案4】:

    你可以这样试试,

               runOnUiThread(new Runnable() {
                    public void run() {
                        scAdapter.notifyDataSetChanged()
                    }
                });
    

    试试这个,我评论了一些行“// Comment Tharaka”并添加了一些行“//DO Tharaka”

    public class MainActivity extends ActionBarActivity {
    
      ListView lvData,lvData1;
      DBHelper db;
      SimpleCursorAdapter scAdapter;
      Cursor cursor;
      Cursor cursor1;
    
      final String LOG_TAG = "myLogs";
      final String LOG_TAG1 = "myLogs1";
    
      /** Called when the activity is first created. */
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        // открываем подключение к БД
        db = new DBHelper(this);
        db.open();
    
        // Get the intent, verify the action and get the query
        Intent intent = getIntent();
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
          String query = intent.getStringExtra(SearchManager.QUERY);
          doMySearch(query);
        }
    
        // получаем курсор
        cursor = db.getAllData();
        startManagingCursor(cursor);
    
        // Формируем столбцы сопоставления
        // Comment Tharaka String[] from = new String[] { DBHelper.COLUMN_r_name, DBHelper.COLUMN_region, DBHelper.COLUMN_code};
        // Comment Tharaka int[] to = new int[] { R.id.city_name, R.id.region_name, R.id.city_code };
    
        // создааем адаптер и настраиваем список
        // Comment Tharaka scAdapter = new SimpleCursorAdapter(this, R.layout.item, cursor, from, to);
        // Comment Tharaka lvData = (ListView) findViewById(R.id.listdata);
        // Comment Tharaka lvData.setAdapter(scAdapter);
      }
    
      public void doMySearch(String query) {
            lvData1 = (ListView) findViewById(R.id.listdata);
            //Ищем совпадения
            Log.d(LOG_TAG, "Before get the C");
            cursor1 = db.fetchRecordsByQuery(query);
            Log.d(LOG_TAG, "After get the C");
            String t = Integer.toString(cursor1.getCount());
            Log.d(LOG_TAG, t);
            startManagingCursor(cursor1);
            String[] from = new String[] { DBHelper.COLUMN_r_name, DBHelper.COLUMN_region, DBHelper.COLUMN_code};
            int[] to = new int[] { R.id.city_name, R.id.region_name, R.id.city_code };
            SimpleCursorAdapter scAdapter1;
    
            scAdapter = new SimpleCursorAdapter(this,
                    R.layout.item, cursor1, from, to);
    
            //DO Tharaka
            lvData.setAdapter(scAdarpter);
            Log.d(LOG_TAG, "Setting the adapter");
            //Обновляем адаптер
            logCursor(cursor1);
            lvData1.setAdapter(scAdapter);
            Log.d(LOG_TAG, "Adapter was set");
          }
    
    //вывод в лог данных из курсора
     void logCursor(Cursor c) {
       if (c != null) {
         if (c.moveToFirst()) {
           String str;
           do {
             str = "";
             for (String cn : c.getColumnNames()) {
               str = str.concat(cn + " = " + c.getString(c.getColumnIndex(cn)) + "; ");
             }
             Log.d(LOG_TAG1, str);
           } while (c.moveToNext());
         }
       } else
         Log.d(LOG_TAG1, "Cursor is null");
     }
    
    
    
         @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
    
            // Associate searchable configuration with the SearchView
            SearchManager searchManager =
                   (SearchManager) getSystemService(Context.SEARCH_SERVICE);
            SearchView searchView =
                    (SearchView) menu.findItem(R.id.action_settings).getActionView();
            searchView.setSearchableInfo(
                    searchManager.getSearchableInfo(getComponentName()));
    
            return true;
        }
    
    
      protected void onDestroy() {
        super.onDestroy();
        // закрываем подключение при выходе
        db.close();
      }
    
    }
    

    【讨论】:

    • 它不起作用。或者我放错地方了。请显示整个代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多