【问题标题】:Unable to get Listview to refresh from Database无法让 Listview 从数据库中刷新
【发布时间】:2011-10-24 13:45:45
【问题描述】:

无论我似乎尝试对此列表视图做什么,并试图让它在我点击按钮时动态更新它都不起作用并且总是抛出 NPE。

代码如下,我非常欢迎您提供帮助。我尝试过 requery,也尝试过 notifyDataSetChanged,但老实说,这只是我的第二个项目,也是第一个使用数据库或列表视图的项目,我会很努力。

数据库助手

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; 
import android.provider.BaseColumns;
import android.util.Log;

public class DatabaseHelper extends SQLiteOpenHelper {

private static final String TAG = DatabaseHelper.class.getSimpleName();

public static final String DATABASE_NAME = "reordermymeds.db";
public static final int DATABASE_VERSION = 3;
public static final String TABLE_NAME = "Medicines";
public static final String C_ID = BaseColumns._ID;
public static final String C_MED_NAME = "med_name"; 
public static final String TABLE_NAME_SURG = "Surgeries";
public static final String SURGERY_NAME = "sName";
public static final String SURGERY_TEL = "sTel";
public static final String SURGERY_MAIL = "sMail";



public DatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    // TODO Auto-generated constructor stub
}

@Override
public void onCreate(SQLiteDatabase db) {
    // TODO Auto-generated method stub
    String sql = String.format("CREATE TABLE %s (%s INTEGER PRIMARY KEY, %s     TEXT)", TABLE_NAME, C_ID, C_MED_NAME);
    String sql_surg = String.format(
            "create table %s (%s int primary key, %s TEXT, %s TEXT, %s TEXT)", 
            TABLE_NAME_SURG, C_ID, SURGERY_NAME, SURGERY_TEL, SURGERY_MAIL);

    Log.d(TAG, "onCreate sql: "+sql);

    db.execSQL(sql);
    db.execSQL(sql_surg);



}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub
    db.execSQL("drop table if exists " + TABLE_NAME);
    db.execSQL("drop table if exists " + TABLE_NAME_SURG);
    this.onCreate(db);
}

}

活动

import android.app.ListActivity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;



public class pills extends ListActivity {

public static final String C_MED_NAME = "med_name";
public SimpleCursorAdapter ladapter;

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

    try {

            DatabaseHelper DBHelper= new DatabaseHelper(this);
            SQLiteDatabase db = DBHelper.getReadableDatabase();


            Cursor cur = db.query("Medicines", null, null, null, null, null, null);
            startManagingCursor(cur);

            String [] columns = new String[] {C_MED_NAME};
            int [] to = new int[] {R.id.meditem};

            SimpleCursorAdapter ladapter = new SimpleCursorAdapter(this, R.layout.meditem, cur, columns, to);

            this.setListAdapter(ladapter);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }



    Button saveMed = (Button) findViewById(R.id.pills_newmedsubmit);
    saveMed.setOnClickListener(new OnClickListener() {



        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            final EditText newMed = (EditText) findViewById(R.id.pills_newmedtxtbox);

            if (newMed.getText().toString().equals("")) {

                    Context context = getApplicationContext();
                    CharSequence text = "Please type the name of a new prescription item.";
                    int duration = Toast.LENGTH_SHORT;

                    Toast toast= Toast.makeText(context, text, duration);
                    toast.show();
            }
            else
            {

                    String medName = newMed.getText().toString();

                    insertNewPrescriptionItem(medName);

                    EditText clearTextBox = (EditText) findViewById(R.id.pills_newmedtxtbox);
                    clearTextBox.setText("");

                    Context context = getApplicationContext();
                    CharSequence text = "Saved";
                    int duration = Toast.LENGTH_SHORT;

                    Toast toast = Toast.makeText(context, text, duration);
                    toast.show();


            }

        setListAdapter(ladapter);
        ladapter.notifyDataSetChanged();

        }


    });}

    private void insertNewPrescriptionItem (String medName){

        DatabaseHelper DbHelper = new DatabaseHelper(this);

        SQLiteDatabase db = DbHelper.getWritableDatabase();

        ContentValues cv = new ContentValues();

            cv.put(DatabaseHelper.C_MED_NAME, medName);

            db.insert(DatabaseHelper.TABLE_NAME, DatabaseHelper.C_MED_NAME, cv);
            db.close();
            }


}

当然,最后但并非最不重要的是堆栈跟踪。我可以看到错误所在的行,但是我尝试使用 Google 的每一次结果都是一样的。谁能证明我一定是犯了愚蠢的错误??

堆栈跟踪

08-11 01:21:26.095: ERROR/AndroidRuntime(15327): FATAL EXCEPTION: main
08-11 01:21:26.095: ERROR/AndroidRuntime(15327): java.lang.NullPointerException
08-11 01:21:26.095: ERROR/AndroidRuntime(15327):     at com.asurya.reordmymeds.pills$1.onClick(pills.java:90)
08-11 01:21:26.095: ERROR/AndroidRuntime(15327):     at android.view.View.performClick(View.java:2485)
08-11 01:21:26.095: ERROR/AndroidRuntime(15327):     at android.view.View$PerformClick.run(View.java:9080)
08-11 01:21:26.095: ERROR/AndroidRuntime(15327):     at android.os.Handler.handleCallback(Handler.java:587)
08-11 01:21:26.095: ERROR/AndroidRuntime(15327):     at android.os.Handler.dispatchMessage(Handler.java:92)
08-11 01:21:26.095: ERROR/AndroidRuntime(15327):     at android.os.Looper.loop(Looper.java:130)
08-11 01:21:26.095: ERROR/AndroidRuntime(15327):     at android.app.ActivityThread.main(ActivityThread.java:3683)
08-11 01:21:26.095: ERROR/AndroidRuntime(15327):     at java.lang.reflect.Method.invokeNative(Native Method)
08-11 01:21:26.095: ERROR/AndroidRuntime(15327):     at java.lang.reflect.Method.invoke(Method.java:507)
08-11 01:21:26.095: ERROR/AndroidRuntime(15327):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-11 01:21:26.095: ERROR/AndroidRuntime(15327):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-11 01:21:26.095: ERROR/AndroidRuntime(15327):     at dalvik.system.NativeStart.main(Native Method)
08-11 01:21:26.107: WARN/ActivityManager(110):   Force finishing activity com.asurya.reordmymeds/.pills

哎呀。如果我让你们都知道而不是自己计算它们会有所帮助:)

导致 NPE 的代码行是:

ladapter.notifyDataSetChanged();  

另外,如果我简单地注释掉这一行,应用程序运行良好,但您必须刷新 Activity 才能看到数据库中更新的数据。谢谢大家。

【问题讨论】:

  • 糟糕。如果我让你们都知道而不是自己计算它们会有所帮助:) 导致 NPE 的代码行是 laapter.notifyDataSetChanged();另外,如果我简单地注释掉这一行,应用程序运行良好,但您必须刷新 Activity 才能看到数据库中更新的数据。谢谢大家。

标签: android database listview dynamic refresh


【解决方案1】:
    import android.app.ListActivity;
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.SimpleCursorAdapter;
    import android.widget.Toast;

    public class pills extends ListActivity {

    public static final String C_MED_NAME = "med_name";
    public SimpleCursorAdapter ladapter;
    Context context;
    Cursor cur;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pills);
        context=this;
        try {

                DatabaseHelper DBHelper= new DatabaseHelper(this);
                SQLiteDatabase db = DBHelper.getReadableDatabase();


                cur = db.query("Medicines", null, null, null, null, null, null);
                startManagingCursor(cur);

                String [] columns = new String[] {C_MED_NAME};
                int [] to = new int[] {R.id.meditem};

                ladapter = new SimpleCursorAdapter(this, R.layout.meditem, cur, columns, to);

                this.setListAdapter(ladapter);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



        Button saveMed = (Button) findViewById(R.id.pills_newmedsubmit);
        saveMed.setOnClickListener(new OnClickListener() {



            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                final EditText newMed = (EditText) findViewById(R.id.pills_newmedtxtbox);

                if (newMed.getText().toString().equals("")) {

    //                    Context context = getApplicationContext();
                        CharSequence text = "Please type the name of a new prescription item.";
                        int duration = Toast.LENGTH_SHORT;

                        Toast toast= Toast.makeText(context, text, duration);
                        toast.show();
                }
                else
                {

                        String medName = newMed.getText().toString();

                        insertNewPrescriptionItem(medName);

                        EditText clearTextBox = (EditText) findViewById(R.id.pills_newmedtxtbox);
                        clearTextBox.setText("");

    //                  Context context = getApplicationContext();
                        CharSequence text = "Saved";
                        int duration = Toast.LENGTH_SHORT;

                        Toast toast = Toast.makeText(context, text, duration);
                        toast.show();


                }

            refresh();

            }


        });}

        private void insertNewPrescriptionItem (String medName){

            DatabaseHelper DbHelper = new DatabaseHelper(this);

            SQLiteDatabase db = DbHelper.getWritableDatabase();

            ContentValues cv = new ContentValues();

                cv.put(DatabaseHelper.C_MED_NAME, medName);

                db.insert(DatabaseHelper.TABLE_NAME, DatabaseHelper.C_MED_NAME, cv);
                db.close();
                }


    }
public void refresh(){
cur = db.query("Medicines", null, null, null, null, null, null);
ladapter.notifyDataSetChanged();
}

试试这个,我认为你的上下文是空的,这就是它发生的原因

【讨论】:

  • 恐怕没有帮助,这是同样的错误。 Logcat 仍然显示 laapter.notifyDataSetChanged();作为导致问题的行。
  • 恐怕还是一样。我已经看到使用扩展 BaseAdapter() 的类的其他代码示例。除了活动的首页之外,这是我需要的东西吗?这是我项目中仅有的两个类?
  • 好的,它现在可以工作了——但不完全。您对我的代码所做的更改当然已经解决了 NPE(谢谢),但它并没有像我想象的那样做,那就是刷新列表视图。
【解决方案2】:

一旦你设置了适配器,你就不需要做.setListAdapter()。将您的适配器声明为您的类中的全局变量(就像您在开始时所做的那样),然后在适配器数据发生更改的地方调用adapter.notifyDataSetChanged()。如果它不起作用,请尝试重新实例化适配器,然后调用notifyDataSetChanged()

在尝试删除适配器的类型定义时,您已经做了public SimpleCursorAdapter ladapter;,只是在尝试中向它提供数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 2016-02-01
    • 2014-01-10
    • 2011-10-11
    • 1970-01-01
    • 2018-08-30
    相关资源
    最近更新 更多