我正在尝试在每个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!事实证明,数据库中有一些部分未正确输入导致错误消息,问题已得到解决!
答案 0 :(得分:0)
异常的可能原因(未找到列 prog )是一种非常常见的误解,即每次DatabaseHelper(SQLiteOpenHelper的子类)被实例化时都会调用onCreate
方法。情况并非如此,onCreate
方法仅在创建数据库时调用一次。
因此onCreate
方法中的代码,通常在数据库中创建表只运行一次。因此,除非删除数据库或以其他方式调用onCreate
方法,否则不会应用对表的任何后续更改。
因此,假设表结构已更改为包含 prog 列。假设丢失现有数据不是问题,有2或3种简单方法来规避问题。他们是: -
onCreate
方法,则增加数据库版本号。当您的代码执行DROP表并调用onCreate
时,您可以使用3个选项中的任何一个,然后重新运行应用程序。