如何在列表视图项

时间:2018-02-16 10:58:32

标签: java android sqlite android-studio-3.0

我正在尝试在每个listview项目中创建一个进度条,并能够设置每个列表视图的最大值和进度。我正在使用sqlite数据库来存储2个值的信息但是当我尝试从数据库中检索值时发生错误。

这是MainActivity.java类

public class MainActivity extends AppCompatActivity {

DBAdapter myDb;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    openDB();
    populateListView();
    listViewItemLongClick();
    listViewItemClick();
}

private void openDB(){
    myDb = new DBAdapter(this);
    myDb.open();
}

public void onClick_AddTast (View v) {
    final AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this);
    View mView = getLayoutInflater().inflate(R.layout.creategoaldialog_layout, null);
    final EditText mSetProgbarVal = (EditText)mView.findViewById(R.id.progbarmaxvalue);
    Button mAccept = (Button)mView.findViewById(R.id.accept);
    Button mCancel = (Button)mView.findViewById(R.id.cancel);


    mBuilder.setView(mView);


    final AlertDialog dialog = mBuilder.create();
    dialog.show();

    mAccept.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(!mSetProgbarVal.getText().toString().isEmpty()){
                myDb.insertRow(mSetProgbarVal.getText().toString());
                dialog.dismiss();
            } else {
                Toast.makeText(MainActivity.this,"Please fill in required fields", Toast.LENGTH_SHORT).show();

            }
            populateListView();
        }
    });


    mCancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dialog.dismiss();
        }
    });

}

private void populateListView(){
    Cursor cursor = myDb.getAllRows();
    String[] fromFieldNames = new String[] {DBAdapter.KEY_ROWID,DBAdapter.KEY_AMT};
    int[] toViewIDs = new int[]{R.id.goal_id,R.id.progbarprog};
    SimpleCursorAdapter myCursorAdapter;
    myCursorAdapter = new SimpleCursorAdapter(getBaseContext(),R.layout.item_layout, cursor, fromFieldNames, toViewIDs, 0);
    myCursorAdapter.setViewBinder(new CustomViewBinder());
    ListView myList = (ListView)findViewById(R.id.goalList);
    myList.setAdapter(myCursorAdapter);
}

private class CustomViewBinder implements SimpleCursorAdapter.ViewBinder{
    @Override
    public boolean setViewValue(View view, Cursor cursor, int columnIndex){
        if (view.getId()==R.id.progbar){
            ProgressBar progress = (ProgressBar)view;
            progress.setMax(cursor.getInt(cursor.getColumnIndex(String.valueOf(myDb.getRow(1)))));
            return true;
        }
        return false;
    }
}


private void populateProgView(){
    Cursor cursor = myDb.getAllRows();
    String[] fromFieldNames = new String[] {DBAdapter.KEY_PROG};
    int[] toViewIDs = new int[]{R.id.progbarprog};
    SimpleCursorAdapter myCursorAdapter;
    myCursorAdapter = new SimpleCursorAdapter(this,R.layout.item_layout, cursor, fromFieldNames, toViewIDs, 0);
    myCursorAdapter.setViewBinder(new CustomViewBinder2());
    ListView myList = (ListView)findViewById(R.id.goalList);
    myList.setAdapter(myCursorAdapter);
}
private class CustomViewBinder2 implements SimpleCursorAdapter.ViewBinder{
    @Override
    public boolean setViewValue(View view, Cursor cursor, int columnIndex){
        if (view.getId()==R.id.progbar){
            ProgressBar progress = (ProgressBar)view;
            progress.setProgress(cursor.getInt(cursor.getColumnIndex(String.valueOf(myDb.getRow(2)))));
            return true;
        }
        return false;
    }
}

public void listViewItemClick(){
    final ListView myList = (ListView)findViewById(R.id.goalList);
    myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, final long id) {
            Context context = view.getContext();
            final EditText goalAmt = new EditText(context);
            goalAmt.setInputType(InputType.TYPE_CLASS_NUMBER);
            AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
                    .setTitle("Set Amount")
                    .setView(goalAmt)
                    .setPositiveButton("Update", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            String goalValue = String.valueOf(goalAmt.getText().toString());
                            myDb.insertProg(goalValue);
                            populateProgView();
                        }
                    })
                    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    })
                    .create();
            dialog.show();
        }
    });
}

public void onClickDeleteAllGoals(View v){
    myDb.deleteAll();
    populateListView();
}

private void listViewItemLongClick(){
    ListView myList = (ListView)findViewById(R.id.goalList);
    myList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            myDb.deleteRow(id);
            populateListView();

            return false;
        }
    });
  }
}

这是DBAdapter.java类

public class DBAdapter {

private static final String TAG = "DBAdapter"; //used for logging database version

//Field Names
public static final String KEY_ROWID = "_id";
public static final String KEY_AMT = "amt";
public static final String KEY_PROG = "prog";

public static final String[] ALL_KEYS = new String[]{KEY_ROWID, KEY_AMT};

//Column Numbers for each field name;
public static final int COL_ROWID = 0;
public static final int COL_AMT = 1;
public static final int COL_PROG = 2;

//Database Info
public static final String DATABASE_NAME = "dbGoals";
public static final String DATABASE_TABLE = "tblGoals";
public static final int DATABASE_VERSION = 1; //The Version number must be incremented

//SQL Statement to create database
private static final String DATABASE_CREATE_SQL = "CREATE TABLE " + DATABASE_TABLE + " (" +
        KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
        KEY_AMT + " INTEGER, " +
        KEY_PROG + " INTEGER " +");";

private final Context context;
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;


public DBAdapter(Context ctx){
    this.context = ctx;
    myDBHelper = new DatabaseHelper(context);
}


//Open the database connection
public DBAdapter open(){
    db = myDBHelper.getWritableDatabase();
    return this;
}

//Close the database connection
public void close(){
    myDBHelper.close();
}

//Add a new set of values to be inserted into the database.
public long insertRow(String amt){
    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_AMT, amt);

    //Insert the data into the database
    return db.insert(DATABASE_TABLE, null, initialValues);
}

public long insertProg(String prog){
    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_PROG, prog);

    //Insert the data into the database
    return db.insert(DATABASE_TABLE, null, initialValues);
}


//Delete a row from the database by rowId (primary key)
public boolean deleteRow(long rowId){
    String where = KEY_ROWID + "=" + rowId;
    return db.delete(DATABASE_TABLE, where, null) != 0;
}

public void deleteAll(){
    Cursor c = getAllRows();
    long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
    if (c.moveToFirst()){
        do {
            deleteRow(c.getLong((int) rowId));
        } while (c.moveToNext());
    }
    c.close();
}

//Return all data to database
public Cursor getAllRows(){
    String where = null;
    Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS, where,
            null, null, null, null, null);
    if (c != null){
        c.moveToFirst();
    }
    return c;
}

//Get a specific row (by rowId)
public  Cursor getRow(long rowId){
    String where = KEY_ROWID + "=" + rowId;
    Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS, where,
            null, null, null, null, null);
    if (c != null){
        c.moveToFirst();
    }
    return c;
}

private static class DatabaseHelper extends SQLiteOpenHelper {

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

    @Override
    public void  onCreate(SQLiteDatabase _db){
        _db.execSQL(DATABASE_CREATE_SQL);
    }

    @Override
    public void  onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion){
        Log.w(TAG, "Upgrading application's database from new version " + oldVersion + " to " + newVersion +
                ", which will destroy all old data!");

        //Destroy old database:
        _db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);

        //Recreate new database;
        onCreate(_db);
    }
  }
}

然后这是logcat错误消息

2-16 18:50:05.562 7084-7084/com.example.eugene.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
                                                                            Process: com.example.eugene.myapplication, PID: 7084
                                                                            java.lang.IllegalArgumentException: column 'prog' does not exist
                                                                                at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:303)
                                                                                at android.widget.SimpleCursorAdapter.findColumns(SimpleCursorAdapter.java:333)
                                                                                at android.widget.SimpleCursorAdapter.<init>(SimpleCursorAdapter.java:107)
                                                                                at com.example.eugene.myapplication.MainActivity.populateProgView(MainActivity.java:114)
                                                                                at com.example.eugene.myapplication.MainActivity.access$300(MainActivity.java:25)
                                                                                at com.example.eugene.myapplication.MainActivity$3$2.onClick(MainActivity.java:147)
                                                                                at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:162)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                at android.os.Looper.loop(Looper.java:135)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:5221)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

我是android studio的新手,我从本网站的教程和其他问题中得到了大部分代码。

EDIT!事实证明,数据库中有一些部分未正确输入导致错误消息,问题已得到解决!

1 个答案:

答案 0 :(得分:0)

异常的可能原因(未找到列 prog )是一种非常常见的误解,即每次DatabaseHelper(SQLiteOpenHelper的子类)被实例化时都会调用onCreate方法。情况并非如此,onCreate方法仅在创建数据库时调用一次。

因此onCreate方法中的代码,通常在数据库中创建表只运行一次。因此,除非删除数据库或以其他方式调用onCreate方法,否则不会应用对表的任何后续更改。

因此,假设表结构已更改为包含 prog 列。假设丢失现有数据不是问题,有2或3种简单方法来规避问题。他们是: -

  • 卸载应用程序。
  • 删除应用程序的数据。
  • 如果相应地编写了onUpgrade方法,即删除已更改的表,然后调用onCreate方法,则增加数据库版本号。

当您的代码执行DROP表并调用onCreate时,您可以使用3个选项中的任何一个,然后重新运行应用程序。