Membuat Aplikasi CRUD SQLite dengan Content Provider dan Circular Reveal Animation di Android Part2
di part pertama kita sudah melakukan persiapan untuk project ini, selanjutnya kita akan
membuat class DBHelper di java
pertama
buat dulu package data di java kemudian buat class EmployeeDbHelper dan masukan
kode di bawah:
package com.giviews.employee.data;
import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by asus on 22/10/2017.
*/
public final class EmployeeDbHelper extends SQLiteOpenHelper{
public static final String LOG_TAG = EmployeeDbHelper.class.getSimpleName();
public static final String DATABASE_NAME = "employee.db";
private static final int DATABASE_VERSION = 1;
public EmployeeDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
//Create String to contains the SQL table
String SQL_CREATE_EMPLOYEES_TABLE = "CREATE TABLE " + EmployeeContract.EmployeeEntry.TABLE_NAME + "("
+ EmployeeContract.EmployeeEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ EmployeeContract.EmployeeEntry.COLUMN_FIRSTNAME + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_LASTNAME + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_TITLE + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_DEPARTMENT + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_CITY + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_PHONE + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_IMAGE + " BLOB NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_EMAIL + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_EMPLOYEE_GENDER + " INTEGER NOT NULL" + " );";
//EXECUTE THE SQL STATEMENT
db.execSQL(SQL_CREATE_EMPLOYEES_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
//on upgrade
}
}
import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by asus on 22/10/2017.
*/
public final class EmployeeDbHelper extends SQLiteOpenHelper{
public static final String LOG_TAG = EmployeeDbHelper.class.getSimpleName();
public static final String DATABASE_NAME = "employee.db";
private static final int DATABASE_VERSION = 1;
public EmployeeDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
//Create String to contains the SQL table
String SQL_CREATE_EMPLOYEES_TABLE = "CREATE TABLE " + EmployeeContract.EmployeeEntry.TABLE_NAME + "("
+ EmployeeContract.EmployeeEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ EmployeeContract.EmployeeEntry.COLUMN_FIRSTNAME + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_LASTNAME + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_TITLE + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_DEPARTMENT + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_CITY + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_PHONE + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_IMAGE + " BLOB NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_EMAIL + " TEXT NOT NULL, "
+ EmployeeContract.EmployeeEntry.COLUMN_EMPLOYEE_GENDER + " INTEGER NOT NULL" + " );";
//EXECUTE THE SQL STATEMENT
db.execSQL(SQL_CREATE_EMPLOYEES_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
//on upgrade
}
}
pada kelas
DbHelper di atas kita sudah membuat database dan tablenya.
Sekarang
kita buat class baru dengan nama EmployeeContract dan masukan kode berikut:
package com.giviews.employee.data; import android.content.Context; import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; /** * Created by asus on 22/10/2017. */ public final class EmployeeDbHelper extends SQLiteOpenHelper{ public static final String LOG_TAG = EmployeeDbHelper.class.getSimpleName(); public static final String DATABASE_NAME = "employee.db"; private static final int DATABASE_VERSION = 1; public EmployeeDbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { //Create String to contains the SQL table String SQL_CREATE_EMPLOYEES_TABLE = "CREATE TABLE " + EmployeeContract.EmployeeEntry.TABLE_NAME + "(" + EmployeeContract.EmployeeEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + EmployeeContract.EmployeeEntry.COLUMN_FIRSTNAME + " TEXT NOT NULL, " + EmployeeContract.EmployeeEntry.COLUMN_LASTNAME + " TEXT NOT NULL, " + EmployeeContract.EmployeeEntry.COLUMN_TITLE + " TEXT NOT NULL, " + EmployeeContract.EmployeeEntry.COLUMN_DEPARTMENT + " TEXT NOT NULL, " + EmployeeContract.EmployeeEntry.COLUMN_CITY + " TEXT NOT NULL, " + EmployeeContract.EmployeeEntry.COLUMN_PHONE + " TEXT NOT NULL, " + EmployeeContract.EmployeeEntry.COLUMN_IMAGE + " BLOB NOT NULL, " + EmployeeContract.EmployeeEntry.COLUMN_EMAIL + " TEXT NOT NULL, " + EmployeeContract.EmployeeEntry.COLUMN_EMPLOYEE_GENDER + " INTEGER NOT NULL" + " );"; //EXECUTE THE SQL STATEMENT db.execSQL(SQL_CREATE_EMPLOYEES_TABLE); } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) { //on upgrade } }
kemudian
buat lagi class baru dengan nama EmployeeProvider dan masukan kode berikut:
package com.giviews.employee.data; import android.app.SearchManager; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.util.Log; import java.util.HashMap; /** * Created by asus on 24/10/2017. */ public class EmployeeProvider extends ContentProvider { public static final String LOG_TAG = EmployeeProvider.class.getSimpleName(); private static final int EMPLOYEES = 100; private static final int EMPLOYEE_ID = 101; private static final int SEARCH_SUGGEST = 102; private static final HashMap<String, String> SEARCH_SUGGEST_PROJECTION_MAP; static { SEARCH_SUGGEST_PROJECTION_MAP = new HashMap<String, String>(); SEARCH_SUGGEST_PROJECTION_MAP.put(EmployeeContract.EmployeeEntry._ID, EmployeeContract.EmployeeEntry._ID); SEARCH_SUGGEST_PROJECTION_MAP.put(SearchManager.SUGGEST_COLUMN_TEXT_1, EmployeeContract.EmployeeEntry.COLUMN_FIRSTNAME + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_1); SEARCH_SUGGEST_PROJECTION_MAP.put(SearchManager.SUGGEST_COLUMN_TEXT_2, EmployeeContract.EmployeeEntry.COLUMN_LASTNAME + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_2); SEARCH_SUGGEST_PROJECTION_MAP.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, EmployeeContract.EmployeeEntry._ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID); } private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); public static final Uri SEARCH_SUGGEST_URI = Uri.parse("content://" + EmployeeContract.CONTENT_ATHORITY + "/" + EmployeeContract.PATH_EMPLOYEES + "/" + SearchManager.SUGGEST_URI_PATH_QUERY); static { sUriMatcher.addURI(EmployeeContract.CONTENT_ATHORITY, EmployeeContract.PATH_EMPLOYEES, EMPLOYEES); sUriMatcher.addURI(EmployeeContract.CONTENT_ATHORITY, EmployeeContract.PATH_EMPLOYEES + "/#", EMPLOYEE_ID); } public EmployeeProvider(){ sUriMatcher.addURI(EmployeeContract.CONTENT_ATHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST); sUriMatcher.addURI(EmployeeContract.CONTENT_ATHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST); } private EmployeeDbHelper mDbHelper; @Override public boolean onCreate() { mDbHelper = new EmployeeDbHelper(getContext()); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase database = mDbHelper.getReadableDatabase(); Cursor cursor; SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); queryBuilder.setTables(EmployeeContract.EmployeeEntry.TABLE_NAME); int match = sUriMatcher.match(uri); switch (match) { case SEARCH_SUGGEST: selectionArgs = new String[] { "%" + selectionArgs[0] + "%", "%" + selectionArgs[0] + "%"}; queryBuilder.setProjectionMap(SEARCH_SUGGEST_PROJECTION_MAP); cursor = queryBuilder.query(database, projection, selection, selectionArgs, null, null, sortOrder); break; case EMPLOYEES: cursor = database.query(EmployeeContract.EmployeeEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); break; case EMPLOYEE_ID: selection = EmployeeContract.EmployeeEntry._ID + "=?"; selectionArgs = new String[] {String.valueOf(ContentUris.parseId(uri))}; cursor = database.query(EmployeeContract.EmployeeEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); break; default: throw new IllegalArgumentException("Cannot query unknown uri" + uri); } cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } @Override public Uri insert(Uri uri, ContentValues contentValues) { final int match = sUriMatcher.match(uri); switch (match) { case EMPLOYEES: return insertEmployee(uri, contentValues); default: throw new IllegalArgumentException("Inserted is not supported for " + uri); } } private Uri insertEmployee(Uri uri, ContentValues values) { String firstname = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_FIRSTNAME); if (firstname == null) { throw new IllegalArgumentException("Employee require a firstname"); } String lastname = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_LASTNAME); if (lastname == null) { throw new IllegalArgumentException("Employee requires a lastname"); } String department = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_DEPARTMENT); if (department == null) { throw new IllegalArgumentException("Employee requires a lastname"); } String title = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_TITLE); if (title == null) { throw new IllegalArgumentException("Employee requires a title"); } String city = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_CITY); if (city == null) { throw new IllegalArgumentException("Employee requires a city"); } String phone = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_PHONE); if (phone == null) { throw new IllegalArgumentException("Employee requires a phone number"); } String email = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_EMAIL); if (email == null) { throw new IllegalArgumentException("Employee requires an email"); } //check gender is valid Integer gender = values.getAsInteger(EmployeeContract.EmployeeEntry.COLUMN_EMPLOYEE_GENDER); if (gender == null || !EmployeeContract.EmployeeEntry.isValidGender(gender)) { throw new IllegalArgumentException("Employee requires valid gender"); } //get writable database SQLiteDatabase database = mDbHelper.getWritableDatabase(); //Insert new Employee with given values Long id = database.insert(EmployeeContract.EmployeeEntry.TABLE_NAME, null, values); if (id == -1) { Log.e(LOG_TAG, "Failed to insert row for" + uri); return null; } getContext().getContentResolver().notifyChange(uri, null); return ContentUris.withAppendedId(uri, id); } @Override public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) { final int match = sUriMatcher.match(uri); switch (match) { case EMPLOYEES: return updateEmployee(uri, contentValues, selection, selectionArgs); case EMPLOYEE_ID: selection = EmployeeContract.EmployeeEntry._ID + "=?"; selectionArgs = new String[] {String.valueOf(ContentUris.parseId(uri))}; return updateEmployee(uri, contentValues, selection, selectionArgs); default: throw new IllegalArgumentException("Update is not supported for " + uri); } } private int updateEmployee(Uri uri, ContentValues values, String selection, String[] selectionArgs) { if (values.containsKey(EmployeeContract.EmployeeEntry.COLUMN_FIRSTNAME)){ String firstname = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_FIRSTNAME); if (firstname == null) { throw new IllegalArgumentException("Employee requires a firstname"); } } if (values.containsKey(EmployeeContract.EmployeeEntry.COLUMN_LASTNAME)){ String lastname = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_LASTNAME); if (lastname == null) { throw new IllegalArgumentException("Employess requires a lastname"); } } if (values.containsKey(EmployeeContract.EmployeeEntry.COLUMN_TITLE)){ String title = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_TITLE); if (title == null) { throw new IllegalArgumentException("Employee requires a title"); } } if (values.containsKey(EmployeeContract.EmployeeEntry.COLUMN_DEPARTMENT)) { String department = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_DEPARTMENT); if (department == null) { throw new IllegalArgumentException("Employee requires a department"); } } if (values.containsKey(EmployeeContract.EmployeeEntry.COLUMN_CITY)) { String city = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_CITY); if (city == null) { throw new IllegalArgumentException("Employee requires a city"); } } if (values.containsKey(EmployeeContract.EmployeeEntry.COLUMN_PHONE)) { String phone = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_PHONE); if (phone == null) { throw new IllegalArgumentException("Employee requires a phone number"); } } if (values.containsKey(EmployeeContract.EmployeeEntry.COLUMN_EMAIL)) { String email = values.getAsString(EmployeeContract.EmployeeEntry.COLUMN_EMAIL); if (email == null) { throw new IllegalArgumentException("Employee require an email"); } } if (values.containsKey(EmployeeContract.EmployeeEntry.COLUMN_EMPLOYEE_GENDER)) { Integer gender = values.getAsInteger(EmployeeContract.EmployeeEntry.COLUMN_EMPLOYEE_GENDER); if (gender == null || !EmployeeContract.EmployeeEntry.isValidGender(gender)) { throw new IllegalArgumentException("Employee require a valid gender"); } } if (values.size() == 0) { return 0; } SQLiteDatabase database = mDbHelper.getWritableDatabase(); int rowsUpdated = database.update(EmployeeContract.EmployeeEntry.TABLE_NAME, values, selection, selectionArgs); if (rowsUpdated != 0) { getContext().getContentResolver().notifyChange(uri, null); } return rowsUpdated; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase database = mDbHelper.getWritableDatabase(); int rowsDeleted; final int match = sUriMatcher.match(uri); switch (match) { case EMPLOYEES: //delete all rows rowsDeleted = database.delete(EmployeeContract.EmployeeEntry.TABLE_NAME, selection, selectionArgs); break; case EMPLOYEE_ID: selection = EmployeeContract.EmployeeEntry._ID + "=?"; selectionArgs = new String[] {String.valueOf(ContentUris.parseId(uri))}; rowsDeleted = database.delete(EmployeeContract.EmployeeEntry.TABLE_NAME, selection, selectionArgs); break; default: throw new IllegalArgumentException("Deletion is not support for " + uri); } if (rowsDeleted != 0) { getContext().getContentResolver().notifyChange(uri, null); } return rowsDeleted; } @Override public String getType(Uri uri) { final int match = sUriMatcher.match(uri); switch (match) { case EMPLOYEES: return EmployeeContract.EmployeeEntry.CONTENT_LIST_TYPE; case EMPLOYEE_ID: return EmployeeContract.EmployeeEntry.CONTENT_ITEM_TYPE; case SEARCH_SUGGEST: return null; default: throw new IllegalArgumentException("Unknown URI " + uri + " with match " + match); } } }
pada class
EmployeeProvider diatas kita sudah membuat fungsi untuk CRUD nya yaitu fungsi
untuk menambahkan data, merubah data, memparsing data dan menghapus data.
setelah
kita membuat class-class diatas selanjutnya kita akan membuat desain antarmuka
untuk aplikasi kita
pertama
kita buat layout activity_employee seperti berikut:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.giviews.employee.EmployeeActivity"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar_setting" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" android:theme="@style/AppTheme.AppBarOverlay" /> <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_below="@+id/toolbar_setting"> </ListView> <!--Empty List--> <RelativeLayout android:id="@+id/empty_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true"> <ImageView android:id="@+id/img" android:layout_width="100dp" android:layout_height="100dp" android:src="@drawable/ic_notifications" android:layout_centerInParent="true"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Belum Ada Data" android:gravity="center" android:layout_below="@+id/img" /> </RelativeLayout> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:src="@drawable/ic_person_add"/> </RelativeLayout>
selanjutnya
buat layout activity_editor seperti berikut:
<?xml version="1.0" encoding="utf-8"?> <com.hendraanggrian.widget.RevealFrameLayout android:id="@+id/revealLayout" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.giviews.employee.EmployeeEditor"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar_setting" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" android:theme="@style/AppTheme.AppBarOverlay" /> <android.support.design.widget.CoordinatorLayout android:layout_marginTop="56dp" android:id="@+id/root_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorAccent"> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:padding="20dp" android:orientation="vertical"> <ImageView android:id="@+id/profileImageView" android:layout_width="200dp" android:layout_height="200dp" android:layout_gravity="center" android:background="@color/colorAccent" android:scaleType="centerCrop" android:src="@drawable/ic_account_circle_black"/> <Button android:layout_margin="10dp" android:layout_gravity="center" android:id="@+id/pickImage" android:layout_width="90dp" android:layout_height="wrap_content" android:text="Select Image" /> <EditText android:id="@+id/firstName" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Fist Name"/> <EditText android:id="@+id/lastName" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Last Name"/> <EditText android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Title"/> <EditText android:id="@+id/department" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Department"/> <EditText android:id="@+id/city" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="City"/> <EditText android:id="@+id/phone" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="number" android:hint="Phone Number"/> <EditText android:id="@+id/email" android:inputType="textEmailAddress" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Email"/> <Spinner android:id="@+id/spinner_gender" android:layout_width="wrap_content" android:layout_height="32dp" android:paddingRight="16dp" android:spinnerMode="dropdown"/> </LinearLayout> </ScrollView> </android.support.design.widget.CoordinatorLayout> </com.hendraanggrian.widget.RevealFrameLayout>
selanjutnya
buat layout list_item untuk menampilkan data listviewnya:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp"> <TextView android:id="@+id/firstname" android:textStyle="bold" android:textSize="17dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/lastname" android:textStyle="bold" android:layout_marginLeft="5dp" android:textSize="17dp" android:layout_toEndOf="@+id/firstname" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/firstname" /> <TextView android:id="@+id/titleview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/lastname"/> </RelativeLayout>
sampai
disini dulu part ke2 nya akan kita lanjutkan di part ke 3 memfungsikan layout yang sudah kita buat