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
   
}
}

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