简体   繁体   中英

SQLite in Android - How to refresh the list

I'm making a wine list app. I'm also trying to use SQLite in it which I'm having a very hard time getting the hang of.

I have a number of activities but there are two that are relevant to this right now.

  • MainActivity - this just shows the names of the wines in a ListView
  • AddActivity - this has EditTexts for the wine name, price, and description.

The trouble I'm having currently is that when I add a wine to the list, when I get back to the MainActivity the list doesn't show the newly added Wine until I close the app and go back into it.

How do I fix this?


Here is my main method:

public class MainActivity extends AppCompatActivity {

    DatabaseHelper mDatabaseHelper;
    ListView listView;
    ArrayAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intentGoToAdd = new Intent(MainActivity.this, AddActivity.class);
                startActivity(intentGoToAdd);
            }
        });

        mDatabaseHelper = new DatabaseHelper(this);

        arrayListAndAdapter();

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long l) {
                SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();

                //Which columns I want to select
                String[] projection = {
                        WineContract.WineEntry.COLUMN_ID,
                        WineContract.WineEntry.COLUMN_WINE_NAME,
                        WineContract.WineEntry.COLUMN_WINE_PRICE,
                        WineContract.WineEntry.COLUMN_WINE_DESCRIPTION};

                Cursor cursor = db.query(WineContract.WineEntry.TABLE_NAME, projection,null,null,null,null,null);
                cursor.moveToPosition(position);
                Intent intentGoToDetails = new Intent(MainActivity.this,DetailsActivity.class);
                String name = cursor.getString(cursor.getColumnIndex(WineContract.WineEntry.COLUMN_WINE_NAME));
                String price = cursor.getString(cursor.getColumnIndex(WineContract.WineEntry.COLUMN_WINE_PRICE));
                String description = cursor.getString(cursor.getColumnIndex(WineContract.WineEntry.COLUMN_WINE_DESCRIPTION));
                intentGoToDetails.putExtra("NAME", name);
                intentGoToDetails.putExtra("PRICE", price);
                intentGoToDetails.putExtra("DESCRIPTION", description);
                startActivity(intentGoToDetails);
            }
        });
    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_deleteDB) {
            mDatabaseHelper.deleteDatabase();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    public void arrayListAndAdapter(){
        SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();

        //Which columns I want to select
        String[] projection = {
                WineContract.WineEntry.COLUMN_ID,
                WineContract.WineEntry.COLUMN_WINE_NAME,
                WineContract.WineEntry.COLUMN_WINE_PRICE,
                WineContract.WineEntry.COLUMN_WINE_DESCRIPTION};

        Cursor cursor = db.query(WineContract.WineEntry.TABLE_NAME, projection,null,null,null,null,null);

        ArrayList<String> mArrayList = new ArrayList<String>();
        while(cursor.moveToNext()) {
            mArrayList.add(cursor.getString(cursor.getColumnIndex(WineContract.WineEntry.COLUMN_WINE_NAME))); //add the item
        }
        listView = (ListView) findViewById(R.id.list);
        adapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, mArrayList);
        listView.setAdapter(adapter);
    }
}

Here is the AddActivity:

public class AddActivity extends AppCompatActivity {

    EditText editWineName, editWinePrice, editWineDescription;
    DatabaseHelper mDatabaseHelper;

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

        mDatabaseHelper = new DatabaseHelper(this);

        editWineName = (EditText) findViewById(R.id.editWineName);
        editWinePrice = (EditText) findViewById(R.id.editWinePrice);
        editWineDescription = (EditText) findViewById(R.id.editWineDescription);
    }

    public void toastMessage(String message){
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_deleteDB) {
            long result = mDatabaseHelper.addWine(editWineName.getText().toString(), editWinePrice.getText().toString(), editWineDescription.getText().toString() );
            if (result!=-1){
                toastMessage(editWineName.getText().toString() + " was added to the list.");
                finish();
            }else{
                toastMessage("Error");
            }
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

And if necessary, here is my DatabaseHelper class:

public class DatabaseHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "wines.db";
    private static final String SQL_CREATE =
            "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
            COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            COLUMN_WINE_NAME + " TEXT, " +
                    COLUMN_WINE_PRICE + " TEXT, " +
            COLUMN_WINE_DESCRIPTION + " TEXT);";



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

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }

    public long addWine(String name, String price, String description){
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(COLUMN_WINE_NAME, name);
        values.put(COLUMN_WINE_PRICE, price);
        values.put(COLUMN_WINE_DESCRIPTION, description);
        return db.insert(TABLE_NAME,null, values);
    }

    public void deleteDatabase(){
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_NAME,null,null);
    }
}

Your activity is only created once so onCreate is only called the first time. What you want is the data to be fresh every time MainActivity resumes. If you override the onResume method and put your arrayListAndAdapter() method and setOnItemClickListener you will get the desired effect. So here's the new code (you can remove this code from onCreate as well to prevent querying twice):

@Override
protected void onResume() {
    super.onResume();
    arrayListAndAdapter();

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long l) {
        SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();

        //Which columns I want to select
        String[] projection = {
                WineContract.WineEntry.COLUMN_ID,
                WineContract.WineEntry.COLUMN_WINE_NAME,
                WineContract.WineEntry.COLUMN_WINE_PRICE,
                WineContract.WineEntry.COLUMN_WINE_DESCRIPTION};

        Cursor cursor = db.query(WineContract.WineEntry.TABLE_NAME, projection,null,null,null,null,null);
        cursor.moveToPosition(position);
        Intent intentGoToDetails = new Intent(MainActivity.this,DetailsActivity.class);
        String name = cursor.getString(cursor.getColumnIndex(WineContract.WineEntry.COLUMN_WINE_NAME));
        String price = cursor.getString(cursor.getColumnIndex(WineContract.WineEntry.COLUMN_WINE_PRICE));
        String description = cursor.getString(cursor.getColumnIndex(WineContract.WineEntry.COLUMN_WINE_DESCRIPTION));
        intentGoToDetails.putExtra("NAME", name);
        intentGoToDetails.putExtra("PRICE", price);
        intentGoToDetails.putExtra("DESCRIPTION", description);
        startActivity(intentGoToDetails);

    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM