In this section we are gonna build an Android application that performs basic CRUD operations. CRUD is abbreviation of Create-Read-Update-Delete. When you store data on Parse it is built around ParseObject and each one contains key-value pairs of JSON-compatible data.
The values you can store in Back4App Database could be in type of String, Number, Bool, Array, Object, Date, File, Pointer, Relation and null.
You can get more information about data types by clicking here.
This tutorial uses a basic app created in Android Studio 4.1.1 with buildToolsVersion=30.0.2 , Compile SDK Version = 30.0.2 and targetSdkVersion 30
At any time, you can access the complete Project via our GitHub repositories.
Note: Follow the Install Parse SDK tutorial to create an Android Studio Project connected to Back4App.
A device (or virtual device) running Android 4.1 (Jelly Bean) or newer.
Understanding our Todo App
To better understand Parse on Android, you will see the CRUD operations implemented on a ToDo App. The application will have a simple interface, with a title and description text field to register a task and a list of registered tasks. You can update each task’s title or description.
Note:
In this tutorial we will make our own custom alert dialog. Therefore, the codes will be configured to follow the template. You can adjust it to your own design.
If you have any trouble, check the GitHub repositories for Kotlin and Java.
Let’s get started!
Following the next steps, you will be able to build a Todo App that will store the tasks at Back4App Database.
1 - Create Todo App Template
Go to Android Studio, and find activity_main.xml layout file from the Project (Project/app/res/layout/activity_main.xml) and then replace the code below with your own code. This xml code will be our MainActivity's design, and we will bind this views to our MainActivity.java class and use them.
XML
1 <?xml version="1.0" encoding="utf-8"?>
2 <androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"3xmlns:app="http://schemas.android.com/apk/res-auto"4xmlns:tools="http://schemas.android.com/tools"5android:layout_width="match_parent"6android:layout_height="match_parent"7tools:context=".MainActivity">
8
9 <!--Title-->>
10 <TextView11android:id="@+id/textView"12android:layout_width="0dp"13android:layout_height="wrap_content"14android:background="@color/blue_700"15android:gravity="center_horizontal"16android:padding="24dp"17android:text="TODO List"18android:textColor="@color/white"19app:layout_constraintEnd_toEndOf="parent"20app:layout_constraintStart_toStartOf="parent"21app:layout_constraintTop_toTopOf="parent"/>
22
23 <!--We will open a pop-up view when clicked to this button-->>
24 <com.google.android.material.floatingactionbutton.FloatingActionButton25android:id="@+id/fab"26style="@style/Widget.MaterialComponents.FloatingActionButton"27android:layout_width="wrap_content"28android:layout_height="wrap_content"29android:layout_margin="16dp"30android:scaleType="centerInside"31android:src="@drawable/ic_baseline_add_24"32app:backgroundTint="@color/blue_700"33app:fabSize="normal"34app:layout_constraintBottom_toBottomOf="parent"35app:layout_constraintEnd_toEndOf="parent"36app:tint="@color/white"/>
37
38 <!--We will show this text view when data list is empty-->>
39 <TextView40android:id="@+id/empty_text"41android:layout_width="wrap_content"42android:layout_height="wrap_content"43android:text="List is empty"44android:layout_marginTop="32dp"45android:textSize="20sp"46android:visibility="gone"47app:layout_constraintEnd_toEndOf="parent"48app:layout_constraintStart_toStartOf="parent"49app:layout_constraintTop_toBottomOf="@+id/textView"/>
50
51 <!--We will adapt the data list to this RecyclerView-->
52 <androidx.recyclerview.widget.RecyclerView53android:id="@+id/recyclerView"54android:layout_width="0dp"55android:layout_height="0dp"56app:layout_constraintBottom_toBottomOf="parent"57app:layout_constraintEnd_toEndOf="parent"58app:layout_constraintStart_toStartOf="parent"59app:layout_constraintTop_toBottomOf="@+id/textView">
60 </androidx.recyclerview.widget.RecyclerView>
61 </androidx.constraintlayout.widget.ConstraintLayout>
2 - Create Object
The create function will create a new Task with the title and description.
To add a TODO, we enter the title and description values in the pop-up that appears on the screen, set it to the ParseObject and save this object. We save this object in the database by using the function that Parse has provided us.
Note:
In this project we will make our own custom alert dialog. You can design your Alert dialog as you want and set it to the view of the dialog you will use later.
Java
Kotlin
1 openInputPopupDialogButton.setOnClickListener(fabButtonView ->{2 AlertDialog.Builder alertDialogBuilder =newAlertDialog.Builder(MainActivity.this);3 alertDialogBuilder.setTitle("Create a TODO");4 alertDialogBuilder.setCancelable(true);5initPopupViewControls();6//We are setting our custom popup view by AlertDialog.Builder7 alertDialogBuilder.setView(popupInputDialogView);8 final AlertDialog alertDialog = alertDialogBuilder.create();9 alertDialog.show();10 saveTodoButton.setOnClickListener(saveButtonView ->saveTodo(alertDialog));11 cancelUserDataButton.setOnClickListener(cancelButtonView -> alertDialog.cancel());12});1314//This is our saveTodo function15 private void saveTodo(AlertDialog alertDialog){16 ParseObject todo =newParseObject("Todo");17if(titleInput.getText().toString().length()!=0&& descriptionInput.getText().toString().length()!=0){18 alertDialog.cancel();19 progressDialog.show();20 todo.put("title", titleInput.getText().toString());21 todo.put("description", descriptionInput.getText().toString());22 todo.saveInBackground(e ->{23 progressDialog.dismiss();24if(e ==null){25//We saved the object and fetching data again26getTodoList();27}else{28//We have an error.We are showing error message here.29showAlert("Error", e.getMessage());30}31});32}else{33showAlert("Error","Please enter a title and description");34}35}
3 - Read Object
With the function that Parse has provided us, we can fetch all the data in a class as ParseObject list. We create a query like the one below and fetch all the data in the Todo class.
Java
Kotlin
1 private void getTodoList(){2 progressDialog.show();3 ParseQuery<ParseObject> query = ParseQuery.getQuery("Todo");4 query.orderByDescending("createdAt");5 query.findInBackground((objects, e)->{6 progressDialog.dismiss();7if(e ==null){8//We are initializing Todo object list to our adapter9initTodoList(objects);10}else{11showAlert("Error", e.getMessage());12}13});14}
In this function, we give the returned list as a parameter to our adapter, set this adapter, to our RecyclerView, and we print the values of each object of this list into its own views. And if list has no item, we are setting our empty_text, view’s as VISIBLE.
Java
Kotlin
1 private fun initTodoList(list: List<ParseObject>?){2if(list ==null|| list.isEmpty()){3 empty_text!!.visibility = View.VISIBLE
4return5}6 empty_text?.visibility = View.GONE
78 val adapter =TodoAdapter(list as ArrayList<ParseObject>, this)910 recyclerView?.layoutManager =LinearLayoutManager(this)11 recyclerView?.adapter = adapter
12}
4 - Update Object
With the edit button in the view of our adapter, we are performing our updates. With the MutableLivedata, object provided by Android, we can listen to the click event of the edit button on our home page. When this button is clicked, we open the same pop-up and this time we populate this pop up with the title and description values of the object we clicked. Then, when the user changes this description and title and press save, first we fetch from the database with the id of this object, then we set the new variables and save object again.
Note:
MutableLiveData is a subclass of LiveData which is used for some of it’s properties (setValue/postValue) and using these properties we can easily notify the ui.
Java
Kotlin
1 adapter.clickListenerToEdit.observe(this@MainActivity,{ parseObject ->2 val alertDialogBuilder = AlertDialog.Builder(this@MainActivity)3 alertDialogBuilder.setTitle("Update a TODO")4 alertDialogBuilder.setCancelable(true)56//We are initializing PopUp Views with title and description parameters of ParseObject78initPopupViewControls(9 parseObject.getString("title")!!,10 parseObject.getString("description")!!11)1213 alertDialogBuilder.setView(popupInputDialogView)14 val alertDialog = alertDialogBuilder.create()15 alertDialog.show()1617 saveTodoButton?.setOnClickListener { saveButtonView ->18if(titleInput?.text.toString().isNotEmpty()&& descriptionInput?.text.toString().isNotEmpty()){19 alertDialog.cancel()20 progressDialog?.show()21 parseObject.put("title", titleInput?.text.toString())22 parseObject.put("description", descriptionInput?.text.toString())23 parseObject.saveInBackground { e1 ->24 progressDialog?.dismiss()25if(e1 ==null){26getTodoList()27}else{28showAlert("Error", e1.message!!)29}30}31}else{32showAlert("Error","Please enter a title and description")33}34}35})
5 - Delete Object
We listen to the click event of the delete button in the view of our adapter with the MutableLivedataobject from the home page, as in the edit button. When the delete button is clicked, we give the object id of the ParseObject as a parameter to the delete function that Parse has provided us and delete this object from the database.
Java
Kotlin
1 adapter.onDeleteListener.observe(this@MainActivity,{ parseObject ->2 progressDialog?.show()3 parseObject.deleteInBackground { e ->4 progressDialog?.dismiss()5if(e ==null){6//We deleted the object and fetching data again.7getTodoList()8}else{9showAlert("Error", e.message!!)10}11}12})
It’s done!
At this point, you have learned how to do the basic CRUD operations with Parse on Android.