Android SQLite database is the most preferred way to store persistence data in android applications. In this tutorial, we will learn to create and manage the SQLite database in an android application with an example and we will create a simple SQLite database for the events management app.
This app will have the functionality of creating, reading, updating, and deleting events with a step-by-step guide. You will also be able to download the source code of this application and run it in your android studio.
1. Create a new Android Studio Project.
Create a new android studio project and name it as “Sqlite Events App”.
colors.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#d11617</color> <color name="colorPrimaryDark">#B31718</color> <color name="colorAccent">#FF4081</color> <color name="white">#FFFFFF</color> </resources>
2. Creating models Package
Right-click on your app package name and create new package models.
3. Creating Event.java Model
Right-click on the newly created models package and create a new class with the name of Event.
The event Model will have the following items.
- Events database table definition.
- Getters and setters for all the event fields.
- Constructor.
package com.tutorialscache.sqliteeventsapp.models; import android.util.Log; public class Event { public static final String TABLE_NAME = "events"; public static final String COLUMN_ID = "id"; public static final String COLUMN_TITLE = "title"; public static final String COLUMN_EVENT_DATE = "event_date"; public static final String COLUMN_VENUE = "venue"; public static final String COLUMN_DATE_CREATED = "dateCreated"; public static final String CREATE_EVENTS_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_TITLE + " VARCHAR," + COLUMN_EVENT_DATE + " VARCHAR," + COLUMN_VENUE + " VARCHAR," + COLUMN_DATE_CREATED + " VARCHAR" + ")"; private long id; private String title; private String eventDate; private String venue; private String dateCreated; public Event() { } public Event(long id, String title, String eventDate, String venue, String dateCreated) { this.id = id; this.title = title; this.eventDate = eventDate; this.venue = venue; this.dateCreated = dateCreated; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getEventDate() { return eventDate; } public void setEventDate(String eventDate) { this.eventDate = eventDate; } public String getVenue() { return venue; } public void setVenue(String venue) { this.venue = venue; } public String getDateCreated() { return dateCreated; } public void setDateCreated(String dateCreated) { this.dateCreated = dateCreated; } public long getId() { return id; } public void setId(long id) { this.id = id; } @Override public String toString() { Log.d("response ","Title: "+title); return super.toString(); } }
4. Database Helper
Create a new package with the name “database”. Under that package create a new class and name it “SqliteDBHelper”.
Expand SqliteDBHelper with SQLiteOpenHelper and implement its methods.
SqliteDBHelper class will have all the CRUD methods.
onCreate method will be called once the app will be installed the first time so in this method we will create an events table.
onUpgrade method will be called once we will change the database version it will remove the previously created events table and recreate it.
In addition, we also have a database version and database in our Helper.
package com.tutorialscache.sqliteeventsapp.database; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import com.tutorialscache.sqliteeventsapp.models.Event; public class SqliteDBHelper extends SQLiteOpenHelper { // Database Version private static final int DATABASE_VERSION = 1; // Database Name private static final String DATABASE_NAME = "events_db"; /** * Instantiates a new Database helper. * * @param context the context */ public SqliteDBHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } // Creating Tables @Override public void onCreate(SQLiteDatabase db) { db.execSQL(Event.CREATE_EVENTS_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // Drop older table if existed db.execSQL("DROP TABLE IF EXISTS " + Event.TABLE_NAME); // Create tables again onCreate(db); } }
4.1 Create / Insert Event
Following the CRUD sequence first, we will start by creating an event option. Because once events will be created only then we will be able to update or delete them. We need a writable database instance by using getWritableDatabase to insert data.
public Long createEvent(Event event) { // writable database instance SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(Event.COLUMN_TITLE, event.getTitle()); values.put(Event.COLUMN_EVENT_DATE, event.getEventDate()); values.put(Event.COLUMN_VENUE, event.getVenue()); values.put(Event.COLUMN_DATE_CREATED, event.getDateCreated()); //saving data long id = db.insert(Event.TABLE_NAME, null, values); // close db connection db.close(); return id; }
4.2 Reading / Retrieving Events
The second step prior to crud is reading. We have two functions to getEventByID which will return and specific Event and the second one is getAllEvents which will result in all Events stored in the events table.
a. getEventByID
public Event getEventByID(long id) { // get readable database SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.query(Event.TABLE_NAME, new String[]{ Event.COLUMN_ID, Event.COLUMN_TITLE, Event.COLUMN_EVENT_DATE, Event.COLUMN_VENUE, Event.COLUMN_DATE_CREATED}, Event.COLUMN_ID + "=?", new String[]{String.valueOf(id)}, null, null, null, null); if (cursor != null) cursor.moveToFirst(); // prepare event object Event event = new Event( Long.parseLong(cursor.getString(cursor.getColumnIndex(Event.COLUMN_ID))), cursor.getString(cursor.getColumnIndex(Event.COLUMN_TITLE)), cursor.getString(cursor.getColumnIndex(Event.COLUMN_EVENT_DATE)), cursor.getString(cursor.getColumnIndex(Event.COLUMN_VENUE)), cursor.getString(cursor.getColumnIndex(Event.COLUMN_DATE_CREATED))); // close the db connection cursor.close(); return event; }
b. getAllEvents
public ArrayList<Event> getAllEvents() { ArrayList<Event> noteArrayList = new ArrayList<>(); // Select All Events Query String selectQuery = "SELECT * FROM " + Event.TABLE_NAME + " ORDER BY " + Event.COLUMN_EVENT_DATE + " DESC"; //Instance of database SQLiteDatabase db = this.getWritableDatabase(); @SuppressLint("Recycle") Cursor cursor = db.rawQuery(selectQuery, null); //looping all rows if (cursor.moveToFirst()) { do { Event event = new Event(); event.setId(Long.parseLong(cursor.getString(cursor.getColumnIndex(Event.COLUMN_ID)))); // getting the id event.setTitle(cursor.getString(cursor.getColumnIndex(Event.COLUMN_TITLE))); event.setEventDate(cursor.getString(cursor.getColumnIndex(Event.COLUMN_EVENT_DATE))); event.setVenue(cursor.getString(cursor.getColumnIndex(Event.COLUMN_VENUE))); event.setDateCreated(cursor.getString(cursor.getColumnIndex(Event.COLUMN_DATE_CREATED))); noteArrayList.add(event); // add to the arrayList event.toString(); } while (cursor.moveToNext()); } db.close(); return noteArrayList; }
4.3 Updating Event
public int updateEvent(Event event) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(Event.COLUMN_TITLE, event.getTitle()); values.put(Event.COLUMN_EVENT_DATE, event.getEventDate()); values.put(Event.COLUMN_VENUE, event.getVenue()); // updating event row return db.update(Event.TABLE_NAME, values, Event.COLUMN_ID + " = ?", new String[]{String.valueOf(event.getId())}); }
4.4 Deleting Event
public void deleteEvent(Event event) { SQLiteDatabase db = this.getWritableDatabase(); db.delete(Event.TABLE_NAME, Event.COLUMN_ID + " = ?", new String[]{String.valueOf(event.getId())}); db.close(); }
Here is the complete code of SqliteDBHelper.java class.
package com.tutorialscache.sqliteeventsapp.database; import android.annotation.SuppressLint; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; import com.tutorialscache.sqliteeventsapp.models.Event; import java.util.ArrayList; import java.util.Calendar; public class SqliteDBHelper extends SQLiteOpenHelper { // Database Version private static final int DATABASE_VERSION = 1; // Database Name private static final String DATABASE_NAME = "events_db"; public SqliteDBHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } // Creating Tables @Override public void onCreate(SQLiteDatabase db) { db.execSQL(Event.CREATE_EVENTS_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // Drop older table db.execSQL("DROP TABLE IF EXISTS " + Event.TABLE_NAME); // Recreate table onCreate(db); } /** * Insert event long. * @param event the event * @return the long created event id */ public Long createEvent(Event event) { // writable database instance SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(Event.COLUMN_TITLE, event.getTitle()); values.put(Event.COLUMN_EVENT_DATE, event.getEventDate()); values.put(Event.COLUMN_VENUE, event.getVenue()); values.put(Event.COLUMN_DATE_CREATED, event.getDateCreated()); //saving data long id = db.insert(Event.TABLE_NAME, null, values); // close db connection db.close(); return id; } /** * Gets event by id. * @param id the id * @return the event by id */ public Event getEventByID(long id) { // get readable database SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.query(Event.TABLE_NAME, new String[]{ Event.COLUMN_ID, Event.COLUMN_TITLE, Event.COLUMN_EVENT_DATE, Event.COLUMN_VENUE, Event.COLUMN_DATE_CREATED}, Event.COLUMN_ID + "=?", new String[]{String.valueOf(id)}, null, null, null, null); if (cursor != null) cursor.moveToFirst(); // prepare event object Event event = new Event( Long.parseLong(cursor.getString(cursor.getColumnIndex(Event.COLUMN_ID))), cursor.getString(cursor.getColumnIndex(Event.COLUMN_TITLE)), cursor.getString(cursor.getColumnIndex(Event.COLUMN_EVENT_DATE)), cursor.getString(cursor.getColumnIndex(Event.COLUMN_VENUE)), cursor.getString(cursor.getColumnIndex(Event.COLUMN_DATE_CREATED))); // close the db connection cursor.close(); return event; } /** * Gets all events. * @return the all events */ public ArrayList<Event> getAllEvents() { ArrayList<Event> noteArrayList = new ArrayList<>(); // Select All Events Query String selectQuery = "SELECT * FROM " + Event.TABLE_NAME + " ORDER BY " + Event.COLUMN_EVENT_DATE + " DESC"; //Instance of database SQLiteDatabase db = this.getWritableDatabase(); @SuppressLint("Recycle") Cursor cursor = db.rawQuery(selectQuery, null); //looping all rows if (cursor.moveToFirst()) { do { Event event = new Event(); event.setId(Long.parseLong(cursor.getString(cursor.getColumnIndex(Event.COLUMN_ID)))); // getting the id event.setTitle(cursor.getString(cursor.getColumnIndex(Event.COLUMN_TITLE))); event.setEventDate(cursor.getString(cursor.getColumnIndex(Event.COLUMN_EVENT_DATE))); event.setVenue(cursor.getString(cursor.getColumnIndex(Event.COLUMN_VENUE))); event.setDateCreated(cursor.getString(cursor.getColumnIndex(Event.COLUMN_DATE_CREATED))); noteArrayList.add(event); // add to the arrayList event.toString(); } while (cursor.moveToNext()); } db.close(); return noteArrayList; } /** * Update event int. * * @param event the event * @return the int */ public int updateEvent(Event event) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(Event.COLUMN_TITLE, event.getTitle()); values.put(Event.COLUMN_EVENT_DATE, event.getEventDate()); values.put(Event.COLUMN_VENUE, event.getVenue()); // updating event row return db.update(Event.TABLE_NAME, values, Event.COLUMN_ID + " = ?", new String[]{String.valueOf(event.getId())}); } /** * Delete event. * @param event the event */ public void deleteEvent(Event event) { SQLiteDatabase db = this.getWritableDatabase(); db.delete(Event.TABLE_NAME, Event.COLUMN_ID + " = ?", new String[]{String.valueOf(event.getId())}); db.close(); } }
5. CreateEventActivity.java
Create a new activity named CreateEventActivity.java which will also create a layout file name activity_create_event.xml
Add the following code to the files. I have added comments inside the code so you can understand them easily.
activity_create_event.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="vertical"> <EditText android:id="@+id/titleET" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Event Title" android:inputType="text" android:maxLines="1" android:layout_margin="10dp"/> <EditText android:id="@+id/venueET" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Event Venue" android:inputType="text" android:maxLines="1" android:layout_margin="10dp"/> <EditText android:id="@+id/eventDateET" android:layout_below="@id/venueET" android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true" android:editable="false" android:focusable="false" android:ems="12" android:hint="Event Date" android:inputType="date" android:maxLines="1" android:layout_margin="10dp"/> <Button android:id="@+id/createEventButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAllCaps="false" android:text="Create Event" android:textColor="@color/white" android:background="@color/colorPrimary" android:layout_gravity="center_horizontal" android:textSize="12sp" android:layout_margin="10dp"/> </LinearLayout>
CreateEventActivity.java
package com.tutorialscache.sqliteeventsapp; import android.annotation.SuppressLint; import android.app.DatePickerDialog; import android.app.TimePickerDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.MenuItem; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.DatePicker; import android.widget.EditText; import android.widget.Spinner; import android.widget.TimePicker; import android.widget.Toast; import com.tutorialscache.sqliteeventsapp.database.SqliteDBHelper; import com.tutorialscache.sqliteeventsapp.models.Event; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.Locale; import java.util.Objects; public class CreateEventActivity extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "CreateEventActivity"; private static Date eventDate; private String startDateStr; private EditText titleEditText; private EditText eventDateET; private EditText venueEditText; private Button createEventButton; private Calendar myCalendar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_create_event); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setTitle("Create New Event"); titleEditText = findViewById(R.id.titleET); eventDateET = findViewById(R.id.eventDateET); venueEditText = findViewById(R.id.venueET); createEventButton = findViewById(R.id.createEventButton); createEventButton.setOnClickListener(this); eventDateET.setOnClickListener(this); createEventButton.setOnClickListener(this); } /** * Called when a view has been clicked. * @param v The view that was clicked. */ @Override public void onClick(View v) { if (v == eventDateET) { getDate(); } if (v == createEventButton) { //getting text from edit texts String title = titleEditText.getText().toString().trim(); String eventDate = eventDateET.getText().toString().trim(); String venue = venueEditText.getText().toString().trim(); if (!TextUtils.isEmpty(title) && !TextUtils.isEmpty(eventDate) && !TextUtils.isEmpty(venue)) { long temp_id = 1; Event event = new Event(temp_id,title, eventDate, venue,Calendar.getInstance().getTime().toString()); SqliteDBHelper databaseHelper = new SqliteDBHelper(getApplicationContext()); databaseHelper.createEvent(event); Toast.makeText(getApplicationContext(), "Event Created Successfully. Total Events "+databaseHelper.getAllEvents().size(), Toast.LENGTH_LONG).show(); titleEditText.setText(""); eventDateET.setText(""); venueEditText.setText(""); } else { Toast.makeText(getApplicationContext(), "Please fill fields to continue", Toast.LENGTH_SHORT).show(); } } } private void getDate() { myCalendar = Calendar.getInstance(); DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { myCalendar.set(Calendar.YEAR, year); myCalendar.set(Calendar.MONTH, monthOfYear); myCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth); String myFormat = "dd/MM/yyyy"; SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US); try { eventDate = sdf.parse(sdf.format(myCalendar.getTime())); startDateStr = sdf.format(myCalendar.getTime()); getTime(); } catch (ParseException e) { e.printStackTrace(); } } }; new DatePickerDialog(CreateEventActivity.this, date, myCalendar .get(Calendar.YEAR), myCalendar.get(Calendar.MONTH), myCalendar.get(Calendar.DAY_OF_MONTH)).show(); } private void getTime() { Calendar mCurrentTime = Calendar.getInstance(); int hour = mCurrentTime.get(Calendar.HOUR_OF_DAY); int minute = mCurrentTime.get(Calendar.MINUTE); TimePickerDialog mTimePicker; mTimePicker = new TimePickerDialog(CreateEventActivity.this, new TimePickerDialog.OnTimeSetListener() { @SuppressLint({"SetTextI18n", "DefaultLocale"}) @Override public void onTimeSet(TimePicker timePicker, int hourOfDay, int minute) { boolean isPM = (hourOfDay >= 12); String time = " " + String.format("%02d:%02d:00 %s", (hourOfDay == 12 || hourOfDay == 0) ? 12 : hourOfDay % 12, minute, isPM ? "PM" : "AM"); eventDateET.setText(startDateStr.concat(time)); } }, hour, minute, false); mTimePicker.setTitle("Select Time"); mTimePicker.show(); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // Respond to the action bar's Up/Home button case android.R.id.home: finish(); return true; } return super.onOptionsItemSelected(item); } }
Right-click on the res directory and create a new menu file main_menu.xml and the following code.
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/createEvent" android:title="Create Event" app:showAsAction="always" /> </menu>
7. MainActivity.java
First, we will simply implement the menu so we can test creating an event feature for now. In the next phase, we will be adding other features like listing all events, updating events, and deleting events.
Use the below code to make use of the main menu and navigate to create an event activity.
package com.tutorialscache.sqliteeventsapp; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } //creating option menu @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_menu, menu); // return true so that the menu pop up is opened return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.createEvent: //move to create event page Intent intent = new Intent(getApplicationContext(),CreateEventActivity.class); startActivity(intent); return true; } return super.onOptionsItemSelected(item); } }
It is suggested to test your previously integrated code before moving forward so you make sure create event functionality is integrated successfully.
Event Listing on the Home page is our next phase. So let’s move on by first creating a row.
8. event_row.xml
Create a new layout resource file and name it event_row and use the following code.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:background="@color/colorPrimary" android:padding="6dp" android:elevation="2dp" xmlns:android="http://schemas.android.com/apk/res/android"> <ImageView android:id="@+id/eventIcon" android:src="@drawable/ic_event" android:layout_centerVertical="true" android:layout_marginRight="5dp" android:scaleType="fitXY" android:layout_width="48dp" android:layout_height="48dp" /> <TextView android:id="@+id/eventNameTV" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@+id/eventIcon" android:text="Event Name" android:layout_marginRight="50dp" android:textColor="#FFF" android:textStyle="bold" android:textSize="16dp" /> <TextView android:id="@+id/venueTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:layout_toRightOf="@+id/eventIcon" android:text="Venue" android:textColor="@color/white" android:textSize="14dp" android:layout_below="@id/eventNameTV" /> <TextView android:id="@+id/dateTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="1/1/2019 - 2/2/2019" android:layout_toRightOf="@+id/eventIcon" android:textColor="@color/white" android:textSize="14dp" android:layout_below="@+id/venueTextView" /> <ImageView android:id="@+id/optionsImageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="4dp" android:src="@drawable/ic_more" android:layout_alignParentTop="true" android:layout_alignParentRight="true"/> </RelativeLayout>
The next step is to add the RecyclerView support library into your build.gradle(Module: app)
implementation 'com.android.support:recyclerview-v7:26.1.0'
9. EventRecyclerViewAdapter.java
EventRecyclerViewAdapter will be used to display events on our recycler view.
Before creating EventRecyclerViewAdapter you need to create a new package name called an adapter.
Next, create a new class “EventRecyclerViewAdapter.java” under the adapter package and add the following code.
package com.tutorialscache.sqliteeventsapp.adapter; import android.content.Context; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.tutorialscache.sqliteeventsapp.R; import com.tutorialscache.sqliteeventsapp.models.Event; import java.util.ArrayList; /** * The type Event recycler view adapter. */ public class EventRecyclerViewAdapter extends RecyclerView.Adapter<EventRecyclerViewAdapter.ViewHolder> { private ArrayList<Event> mData; private LayoutInflater mInflater; private ItemClickListener mClickListener; /** * Instantiates a new Event recycler view adapter. * * @param context the context * @param data the data */ // data is passed into the constructor public EventRecyclerViewAdapter(Context context, ArrayList<Event> data) { this.mInflater = LayoutInflater.from(context); this.mData = data; } // inflates the row layout from xml when needed @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = mInflater.inflate(R.layout.event_row, parent, false); return new ViewHolder(view); } // binds the data to the TextView in each row @Override public void onBindViewHolder(@NonNull final ViewHolder holder, int position) { holder.eventNameTextView.setText(mData.get(position).getTitle()); holder.venueTextView.setText(mData.get(position).getVenue()); holder.dateTextView.setText(mData.get(position).getEventDate()); } // total number of rows @Override public int getItemCount() { if (mData != null) return mData.size(); else return 0; } /** * Gets item. * @param id the id * @return the item */ // convenience method for getting data at click position public Event getItem(int id) { return mData.get(id); } /** * Sets click listener. * @param itemClickListener the item click listener */ // allows clicks events to be caught public void setClickListener(ItemClickListener itemClickListener) { this.mClickListener = itemClickListener; } /** * The interface Item click listener. */ // parent activity will implement this method to respond to click events public interface ItemClickListener { /** * On item click. * @param view the view * @param position the position */ void onItemClick(View view, int position); } /** * The type View holder. */ // stores and recycles views as they are scrolled off screen public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { TextView eventNameTextView,venueTextView,dateTextView; ImageView optionsImageView; /** * Instantiates a new View holder. * @param itemView the item view */ ViewHolder(View itemView) { super(itemView); eventNameTextView = itemView.findViewById(R.id.eventNameTV); venueTextView = itemView.findViewById(R.id.venueTextView); dateTextView = itemView.findViewById(R.id.dateTextView); optionsImageView = itemView.findViewById(R.id.optionsImageView); optionsImageView.setOnClickListener(this); } @Override public void onClick(View view) { if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition()); } } }
10. activity_main.xml
Add a ListView inside activity_main.xml and assign id listView.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.tutorialscache.sqliteeventsapp.MainActivity" android:background="#e9e9e9"> <android.support.v7.widget.RecyclerView android:id="@+id/eventsRecycleView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
11. MainActivity.java
Now we will write code to getAllEvents in MainActivity. As a result of this, we will be able to see all events on a recycler view. In other words, we need to populate our Home page with previously created events. Therefore, we are going to implement MainActivity for EventRecyclerViewAdapter.
package com.tutorialscache.sqliteeventsapp; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.Switch; import android.widget.Toast; import com.tutorialscache.sqliteeventsapp.adapter.EventRecyclerViewAdapter; import com.tutorialscache.sqliteeventsapp.database.SqliteDBHelper; import com.tutorialscache.sqliteeventsapp.models.Event; import java.util.ArrayList; public class MainActivity extends AppCompatActivity implements EventRecyclerViewAdapter.ItemClickListener { private static final String TAG = "MainActivity"; private EventRecyclerViewAdapter adapter; private ArrayList<Event> events; private SqliteDBHelper sqliteDBHelper; private int totalEvents = 0; private RecyclerView recyclerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //DB Helper Instance sqliteDBHelper = new SqliteDBHelper(MainActivity.this); setContentView(R.layout.activity_main); // set up the RecyclerView recyclerView = findViewById(R.id.eventsRecycleView); recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); loadEvents(); } @Override protected void onResume() { if (totalEvents != sqliteDBHelper.getAllEvents().size()){ //update events home events.clear(); loadEvents(); } super.onResume(); } private void loadEvents() { // Fetch all events and save in Events ArrayList events = sqliteDBHelper.getAllEvents(); totalEvents = events.size(); Log.d(TAG, "Total Events: "+totalEvents); if (totalEvents==0){ Toast.makeText(getApplicationContext(),"No Events found.",Toast.LENGTH_SHORT).show(); } adapter = new EventRecyclerViewAdapter(getApplicationContext(), events); adapter.setClickListener(this); recyclerView.setAdapter(adapter); } //creating option menu @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_menu, menu); // return true so that the menu pop up is opened return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.createEvent: //move to create event page Intent intent = new Intent(getApplicationContext(),CreateEventActivity.class); startActivity(intent); return true; } return super.onOptionsItemSelected(item); } @Override public void onItemClick(View view, int position) { } }
11.1 Deleting Event Confirmation Dialog
A new AlertDialog is added in the onItemClick method of MainActivity. As a result of this user will be able to see a confirmation dialog whether its wants to delete or update an event.
@Override public void onItemClick(View view, final int position) { final Event event = adapter.getItem(position); Log.d("response ",event.getTitle()); new AlertDialog.Builder(MainActivity.this) .setTitle(event.getTitle()) .setMessage("What is your desired action?") .setPositiveButton("Update", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { //update Event Activity in Next Step } }) .setNegativeButton("Delete", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "Event Deleted Successfully", Toast.LENGTH_SHORT).show(); sqliteDBHelper.deleteEvent(event); events.remove(position); adapter.notifyDataSetChanged(); } }) .setNeutralButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }) .setIcon(android.R.drawable.ic_dialog_info) .setCancelable(true) .show(); }
The last and final step of our sqilte integration is Updating existing events. Above all steps will give you a complete app but to have a full app with updated event functionality you need to keep following the next step.
12. UpdateEventActivity.Java
We will create a new activity named UpdateEventActivity but with this activity, we will use XML of our existing CreateEventActivity, as a result of this it will save our effort and time. For instance, we need to update the event title, venue, or event date all of these views are already in create event activity so we will continue with activity_create_event.xml.
package com.tutorialscache.sqliteeventsapp; import android.annotation.SuppressLint; import android.app.DatePickerDialog; import android.app.TimePickerDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.DatePicker; import android.widget.EditText; import android.widget.TimePicker; import android.widget.Toast; import com.tutorialscache.sqliteeventsapp.database.SqliteDBHelper; import com.tutorialscache.sqliteeventsapp.models.Event; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Locale; public class UpdateEventActivity extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "UpdateEventActivity"; private static Date eventDate; private String startDateStr; private EditText titleEditText; private EditText eventDateET; private EditText venueEditText; private Button createEventButton; private Calendar myCalendar; private Event event; private SqliteDBHelper sqliteDBHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_create_event); getSupportActionBar().setDisplayHomeAsUpEnabled(true); sqliteDBHelper = new SqliteDBHelper(UpdateEventActivity.this); event = sqliteDBHelper.getEventByID(getIntent().getExtras().getLong("id")); getSupportActionBar().setTitle("Update Event"); titleEditText = findViewById(R.id.titleET); titleEditText.setText(event.getTitle()); eventDateET = findViewById(R.id.eventDateET); eventDateET.setText(event.getEventDate()); venueEditText = findViewById(R.id.venueET); venueEditText.setText(event.getVenue()); createEventButton = findViewById(R.id.createEventButton); createEventButton.setOnClickListener(this); eventDateET.setOnClickListener(this); createEventButton.setOnClickListener(this); createEventButton.setText("Save"); } /** * Called when a view has been clicked. * @param v The view that was clicked. */ @Override public void onClick(View v) { if (v == eventDateET) { getDate(); } if (v == createEventButton) { //getting text from edit texts String title = titleEditText.getText().toString().trim(); String eventDate = eventDateET.getText().toString().trim(); String venue = venueEditText.getText().toString().trim(); if (!TextUtils.isEmpty(title) && !TextUtils.isEmpty(eventDate) && !TextUtils.isEmpty(venue)) { long temp_id = 1; Event event = new Event(temp_id,title, eventDate, venue,Calendar.getInstance().getTime().toString()); sqliteDBHelper.updateEvent(event); Toast.makeText(getApplicationContext(), "Event Updated Successfully.", Toast.LENGTH_LONG).show(); } else { Toast.makeText(getApplicationContext(), "Please fill fields to continue", Toast.LENGTH_SHORT).show(); } } } private void getDate() { myCalendar = Calendar.getInstance(); DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { myCalendar.set(Calendar.YEAR, year); myCalendar.set(Calendar.MONTH, monthOfYear); myCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth); String myFormat = "dd/MM/yyyy"; SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US); try { eventDate = sdf.parse(sdf.format(myCalendar.getTime())); startDateStr = sdf.format(myCalendar.getTime()); getTime(); } catch (ParseException e) { e.printStackTrace(); } } }; new DatePickerDialog(UpdateEventActivity.this, date, myCalendar .get(Calendar.YEAR), myCalendar.get(Calendar.MONTH), myCalendar.get(Calendar.DAY_OF_MONTH)).show(); } private void getTime() { Calendar mCurrentTime = Calendar.getInstance(); int hour = mCurrentTime.get(Calendar.HOUR_OF_DAY); int minute = mCurrentTime.get(Calendar.MINUTE); TimePickerDialog mTimePicker; mTimePicker = new TimePickerDialog(UpdateEventActivity.this, new TimePickerDialog.OnTimeSetListener() { @SuppressLint({"SetTextI18n", "DefaultLocale"}) @Override public void onTimeSet(TimePicker timePicker, int hourOfDay, int minute) { boolean isPM = (hourOfDay >= 12); String time = " " + String.format("%02d:%02d:00 %s", (hourOfDay == 12 || hourOfDay == 0) ? 12 : hourOfDay % 12, minute, isPM ? "PM" : "AM"); eventDateET.setText(startDateStr.concat(time)); } }, hour, minute, false); mTimePicker.setTitle("Select Time"); mTimePicker.show(); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // Respond to the action bar's Up/Home button case android.R.id.home: finish(); return true; } return super.onOptionsItemSelected(item); } }
Update Event Intent in onclick listener of MainActivity. As a result of a positive button click (Update), it will bring up the Edit Event Page.
@Override public void onItemClick(View view, final int position) { final Event event = adapter.getItem(position); Log.d("response ",event.getTitle()); new AlertDialog.Builder(MainActivity.this) .setTitle(event.getTitle()) .setMessage("What action do you want to perform?") .setPositiveButton("Update", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { //update Event Activity Intent intent = new Intent(getApplicationContext(),UpdateEventActivity.class); intent.putExtra("id",event.getId()); startActivity(intent); } }) .setNegativeButton("Delete", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "Event Deleted Successfully", Toast.LENGTH_SHORT).show(); sqliteDBHelper.deleteEvent(event); events.remove(position); adapter.notifyDataSetChanged(); } }) .setNeutralButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }) .setIcon(android.R.drawable.ic_dialog_info) .setCancelable(true) .show(); } }
Comments are closed.