简体   繁体   中英

How to display SQLite database data on a fragment from a navigation drawer?

I'm struggling to show content using a navigation drawer. Basically I have a database showing five categories of noodles. each category is listed as a fragment in a navigation drawer. But I don't know how to connect an activity (for instance a list of noodles) to such a fragment. Can someone please help? Here are my codes:

One of the five fragment classes:

 public class KoreanFragment extends Fragment { public KoreanFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_korean, container, false); } } 
Main Activity Class displays the drawer:

 public class NoodleActivity extends AppCompatActivity { private Cursor cursor; private SQLiteDatabase database; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_noodle); //set up toolbar as the normal app bar Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); ListView noodleListPerCategory = findViewById(R.id.selected_noodleList); SQLiteOpenHelper databaseHelper = new DatabaseHelper(this); try { database = databaseHelper.getReadableDatabase(); cursor = database.query("NOODLE", new String[]{"_id", "NAME"}, null, null, null, null, null); //create the cursor adapter to fill the list view with values from the database SimpleCursorAdapter listAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, new String[]{"NAME"}, new int[]{android.R.id.text2}, 0); noodleListPerCategory.setAdapter(listAdapter); } catch (SQLiteException e) { Toast toast = Toast.makeText(this, "Database error", Toast.LENGTH_SHORT); toast.show(); } //show item detail using the listener when an item is clicked AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //starts DetailActivity Intent intent = new Intent(NoodleActivity.this, DetailActivity.class); intent.putExtra(DetailActivity.CHOSEN_NOODLE_ITEM, (int) id); startActivity(intent); } }; //connects the listener to the list view noodleListPerCategory.setOnItemClickListener(itemClickListener); } /** *This method is called when the database and cursor need to be closed. * They are closed when the cursor adapter doesn't need them anymore. * */ @Override public void onDestroy(){ super.onDestroy(); cursor.close(); database.close(); } } 

A class showing the list of noodles from a database:

 public class DatabaseHelper extends SQLiteOpenHelper { //the name for the database private static final String DATABASENAME = "NoodleDB"; //the initial version of the database private static final int DATABASEVERSION = 1; private Noodle noodle; DatabaseHelper(Context context) { super(context, DATABASENAME, null, DATABASEVERSION); } @Override public void onCreate(SQLiteDatabase db) { updateDatabase(db, 0, DATABASEVERSION); } /** * this method updates the database if the db helper's version number is higher than the version number on the db. * * @param db The SQLite database * @param currentVersion The user's version number of the database * @param updatedVersion The new version of the database written in the helper's code */ @Override public void onUpgrade(SQLiteDatabase db, int currentVersion, int updatedVersion) { updateDatabase(db, currentVersion, updatedVersion); } /** * This method is called when you want to set the database back to its previous version * * @param db The SQLite database * @param currentVersion The user's version number of the database * @param updatedVersion The new version of the database written in the helper's code */ public void onDowngrade(SQLiteDatabase db, int currentVersion, int updatedVersion) { } /** * This method is for adding new noodle dish to the database */ private static void addNoodle(SQLiteDatabase database, Noodle noodle) { ContentValues noodleValues = new ContentValues(); noodleValues.put("NAME", noodle.getName()); noodleValues.put("DESCRIPTION", noodle.getDescription()); noodleValues.put("IMAGEID", noodle.getPhotoID()); noodleValues.put("RESTAURANT", noodle.getSuggestedRestaurant()); database.insert("NOODLE", null, noodleValues); database.close(); } private void updateDatabase(SQLiteDatabase db, int currentVersion, int updatedVersion) { if(currentVersion >= 1 || currentVersion < 1 ) { //execute SQL on the db and create a new NOODLE table db.execSQL("CREATE TABLE NOODLE (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT, " + "NAME TEXT, " + "DESCRIPTION TEXT, " + "IMAGEID INTEGER, " + "RESTAURANT TEXT, " + "FAVORITE NUMERIC, " + "CATEGORY TEXT);"); addNoodle(db, new Noodle("Spicy Ramen", "Chicken broth, marinated pork, chilli and bean sprouts", R.drawable.spicyramen, "Totemo", "japanese")); addNoodle(db, new Noodle("Tokyo Ramen", "Dashi-based broth, marinated pork and fermented bamboo shoots", R.drawable.tokyo, "Totemo", "japanese")); addNoodle(db, new Noodle("Vegetarian Ramen", "Mushroom dashi-based broth, tofu, pak choi, miso and corn", R.drawable.vegetarianramen, "Ramen Manga", "japanese")); addNoodle(db, new Noodle("Miso Ramen", "Miso broth, marinated pork, egg, spring onion and bean sprouts", R.drawable.miso, "Cafe Steigman", "japanese")); addNoodle(db, new Noodle("Tonkatsu Ramen", "Pork bone based broth, grilled pork, spicy garlic with miso", R.drawable.tonkatsu, "Blue Light Yokohama", "japanese")); addNoodle(db, new Noodle("Shio Ramen", "Seasalt broth, pork, egg, quail and vegetable", R.drawable.shio, "Ai Ramen", "japanese")); addNoodle(db, new Noodle("Nabeyaki Udon", "Udon noodles in fish broth with chicken, shrimp, egg and leek", R.drawable.udon, "Ki-mama Ramen", "japanese")); } if(currentVersion <=2) { } } } 

DatabaseHelper class

 public class NoodleActivity extends AppCompatActivity { private Cursor cursor; private SQLiteDatabase database; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_noodle); //set up toolbar as the normal app bar Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); ListView noodleListPerCategory = findViewById(R.id.selected_noodleList); SQLiteOpenHelper databaseHelper = new DatabaseHelper(this); try { database = databaseHelper.getReadableDatabase(); cursor = database.query("NOODLE", new String[]{"_id", "NAME"}, null, null, null, null, null); //create the cursor adapter to fill the list view with values from the database SimpleCursorAdapter listAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, new String[]{"NAME"}, new int[]{android.R.id.text2}, 0); noodleListPerCategory.setAdapter(listAdapter); } catch (SQLiteException e) { Toast toast = Toast.makeText(this, "Database error", Toast.LENGTH_SHORT); toast.show(); } //show item detail using the listener when an item is clicked AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //starts DetailActivity Intent intent = new Intent(NoodleActivity.this, DetailActivity.class); intent.putExtra(DetailActivity.CHOSEN_NOODLE_ITEM, (int) id); startActivity(intent); } }; //connects the listener to the list view noodleListPerCategory.setOnItemClickListener(itemClickListener); } /** *This method is called when the database and cursor need to be closed. * They are closed when the cursor adapter doesn't need them anymore. * */ @Override public void onDestroy(){ super.onDestroy(); cursor.close(); database.close(); } } 

Right now....the database is not created and I don't know how to display data on the fragments, let alone filtered by category. :(

I believe all you have to do is create an instance of you DatabaseHelper and then access the database from that either via an SQLiteDatabase instance or via methods within or via the DatabaseHelper as you would from an activity. You do need a Context, which can be obtained via the getActivity method or the getContext method.

eg (assuming you your KoreanFragment is where you wish to access the database and display the data; and that the data is to be displayed via a ListView ) :-

    public class KoreanFragment extends Fragment {

        Databasehelper mDBHlpr = new DatabaseHelper(getContext()); //<<<<<<<<
        SQLiteDatabase mDatabase = mDBHlpr.getWriteableDatabase(); //<<<<<<<<
        ListView mMyListView; //<<<<<<<< 
        SimpleCursorAdpater mSCA; //<<<<<<<<
        Cursor mCsr; //<<<<<<<<

        //????????Alternative SQLiteDatabase = new DatabaseHelper(getActivity()).getWriteableDatabase();

        public KoreanFragment() {
            // Required empty public constructor
        }
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View view =  inflater.inflate(R.layout.fragment_korean, container, false); //<<<<<<<< don't return as yet
            mMyListView = view.findViewByid(R.id.mylistview); //<<<<<<<< get the Listview to be populated

            mCsr = getAllRows(); //<<<<<<<< get data as cursor
            mSCA = new SimpleCursorAdapter(getContext(),android.R.layout.simple_list_item_1,mCsr,new String[]{"NAME"},new int[]{android.R.id.text1},0); //<<<<<<<< prepare adapater for ListView
            mMyListView.setAdapter(mSCA); //<<<<<<<< attach the adapter to the ListView
            return view; //<<<<<<<<

        }

        //<<<<<<<< new method to query the database an extract all rows from the NOODLE table
        private Cursor getAllRows() {
             return mDatabase.query("NOODLE",null,null,null,null,null,null);
        }
    }

You should really close the Cursor when done with it so you might add the following to overide the onDetach method:-

        @Override
        public void onDetach() {
            super.onDetach();
            mCsr.close();
        }

You may wish to make use of the List eg to delete a row if it is longClicked.

This could be done by 1) adding the following method :-

        private void setItemLongClickListener() {
            mMyListview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                mDatabase.delete("NOODLE","_id=?",new String[]{Long.toString(id)});
                mCsr = getAllRows();
                mSCA.swapCursor(mCsr);
                return true;
            }
        });

and 2) adding the following line immediately after the line mMyListView.setAdapter(mSCA); :-

        setItemLongClickListener();

Notes

  • I've indicated the new/changed code using //<<<<<<<<
  • The above is in-principle/theory code as opposed to tested code so there may be typos or errors.
  • mylistview as in mMyListView = view.findViewByid(R.id. mylistview ); would very likely have to be added to the layout, likely with a name to suit your naming conventions.

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