Membuat Android SQLite Sederhana

Pada tutorial Android SQLite kali ini kita akan mencoba membuat sebuah database baru dengan sebuah tabel (tabel Karyawan) kedalam aplikasi. Di dalam aplikasi Android SQLite ini akan dibuat sebuah class Data Access Object (DAO) yang berfungsi untuk menangani operasi database create, read, update, delete (CRUD) pada tabel. Data yang kita buat akan kita tampilkan kedalam ListView.
Struktur tabel Karyawan:

Field Type Key Extra
id int Primary Key auto_increment
nama text
gaji double
tgllahir date

Untuk lebih memudahkan dalam memahaminya langsung saja kita praktekan langkah – langkah berikut:
Buat project android seperti berikut:
Application Name                 : AndroidSQLite
Project Name                        : AndroidSQLite
Package Name                      : firman.salatigadev.androidsqlite
Minimum Required SDK    : Andoid 2.2
Target SDK                           : Android 4.2
Yang lain biarkan default.
Buka file colors.xml di direktori res/values/colors.xml dan isikan code menjadi seperti berikut:

res/values/colors.xml
<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <color name="transparent">#00000000</color>
    <color name="list_item_bg">#ffffff</color>
    <color name="view_divider_color">#BABABA</color>
</resources>

Buka file strings.xml di direktori res/values/strings.xml ubah isi code menjadi berikut:

res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">AndroidSQLite</string>
    <string name="add_kar">Tambah Karyawan</string>
    <string name="update_kar">Update Karyawan</string>
    <string name="nama">Nama Karyawan</string>
    <string name="tgllahir">Tanggal Lahir</string>
    <string name="gaji">Gaji Karyawan</string>
    <string name="update">Update</string>
    <string name="add">Add</string>
    <string name="reset">Reset</string>
    <string name="cancel">Cancel</string>

</resources>

Buka file res/menu/main.xml dan edit code seperti contoh dibawah ini. File ini akan mendefinisikan item menu dalam action bar untuk menambahkan data karyawan. Ketika item menu ini diklik, akan menampilkan AddFragment yang digunakan untuk menambahkan data karyawan ke database SQLite.

res/menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/action_add"
        android:icon="@android:drawable/ic_menu_add"
        android:orderInCategory="100"
        android:showAsAction="ifRoom|withText"
        android:title="@string/add_kar"/>

</menu>

Buka file res/layout/activity_main.xml dan edit code seperti pada contoh dibawah ini.
File ini berfungsi untuk mengatur letak file utama. Di sini kita mendefinisikan framelayout yang digunakan untuk menyimpan semua fragmen.

res/layout/activity_main.xml
<RelativeLayout 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=".MainActivity" >
 
   <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

Buat file fragment_add.xml pada direktori res/layout/ dan isikan code seperti pada contoh berikut.

res/layout/fragment_add.xml
<?xml version="1.0" encoding="UTF-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
 
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp" >
 
        <EditText
            android:id="@+id/edit_txt_nama"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="@string/nama"
            android:nextFocusDown="@+id/edit_txt_tgllahir"
            android:singleLine="true" />
 
        <EditText
            android:id="@+id/edit_txt_tgllahir"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/edit_txt_nama"
            android:hint="@string/tgllahir"
            android:nextFocusDown="@+id/edit_txt_gaji"
            android:singleLine="true" />
 
        <EditText
            android:id="@+id/edit_txt_gaji"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/edit_txt_tgllahir"
            android:hint="@string/gaji"
            android:inputType="numberDecimal"
            android:singleLine="true" />
 
        <LinearLayout
            android:id="@+id/layout_submit"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/edit_txt_gaji"
            android:layout_margin="5dp"
            android:orientation="horizontal"
            android:weightSum="2" >
 
            <Button
                android:id="@+id/button_add"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/add" />
 
            <Button
                android:id="@+id/button_reset"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/reset" />
        </LinearLayout>
    </RelativeLayout>
 
</ScrollView>

File layout diatas akan digunakan untuk class AddFragment yang berfungsi untuk menambahkan data karyawan (nama, tgllahir, gaji).
Buat file fragment_list.xml pada direktori res/layout/ dan isikan code seperti pada contoh berikut.

res/layout/fragment_list.xml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout 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"
    android:background="#EDEDED" >
 
    <ListView
        android:id="@+id/list_kar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@color/transparent"
        android:dividerHeight="10dp"
        android:drawSelectorOnTop="true"
        android:footerDividersEnabled="false"
        android:padding="10dp"
        android:scrollbarStyle="outsideOverlay" />
 
</RelativeLayout>

File layout diatas mendefinisikan sebuah ListView digunakan untuk class ListFragment yang berfungsi untuk menampilkan data karyawan kedalam bentuk list.
Buat file list_item.xml pada direktori res/layout/ dan isikan code seperti pada contoh berikut.

res/layout/list_item.xml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@color/list_item_bg"
    android:descendantFocusability="blocksDescendants" >
 
    <RelativeLayout
        android:id="@+id/layout_item"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
 
        <TextView
            android:id="@+id/txt_kar_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="6dp" />
 
        <TextView
            android:id="@+id/txt_kar_nama"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/txt_kar_id"
            android:padding="6dp" />
 
        <TextView
            android:id="@+id/txt_kar_tgllahir"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/txt_kar_nama"
            android:padding="6dp" />
 
        <TextView
            android:id="@+id/txt_kar_gaji"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/txt_kar_tgllahir"
            android:padding="6dp" />
    </RelativeLayout>
 
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_below="@+id/layout_item"
        android:background="@color/view_divider_color" />
 
</RelativeLayout>

File diatas mendefinisikan tata letak untuk item ListView Karyawan yang digunakan oleh class ListAdapter.

Membuat Database SQLite
DataBaseHelper
Pada folder src, buat class DataBaseHelper kedalam package firman.salatigadev.androidsqlite.db. Class ini akan meng-extends SQLiteOpenHelper yang menangani pembuatan manajemen database dan versi.

src/firman.salatigadev.androidsqlite.db/DataBaseHelper.java
package firman.salatigadev.androidsqlite.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DataBaseHelper extends SQLiteOpenHelper {
	
	private static final String DATABASE_NAME = "karyawandb";
    private static final int DATABASE_VERSION = 1;
 
    public static final String TABEL_KARYAWAN = "karyawan";
 
    public static final String ID  			 = "id";
    public static final String NAMA 		 = "nama";
    public static final String TANGGAL_LAHIR = "tgllahir";
    public static final String GAJI 		 = "gaji";
 
    public static final String CREATE_TABEL_KARYAWAN = "CREATE TABLE "
            + TABEL_KARYAWAN + "(" + ID + " INTEGER PRIMARY KEY, "
            + NAMA + " TEXT, " + GAJI + " DOUBLE, "
            + TANGGAL_LAHIR + " DATE" + ")";
 
    private static DataBaseHelper instance;
 
    public static synchronized DataBaseHelper getHelper(Context context) {
        if (instance == null)
            instance = new DataBaseHelper(context);
        return instance;
    }
 
    private DataBaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
 
    @Override
    public void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
    }
 
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABEL_KARYAWAN);
    }
 
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

KaryawanDBDAO
Buat class KaryawanDBDAO pada package firman.salatigadev.androidsqlite.db.

src/firman.salatigadev.androidsqlite.db/KaryawanDBDAO.java
package firman.salatigadev.androidsqlite.db;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;

public class KaryawanDBDAO {
	
	protected SQLiteDatabase database;
    private DataBaseHelper dbHelper;
    private Context mContext;
 
    public KaryawanDBDAO(Context context) {
        this.mContext = context;
        dbHelper = DataBaseHelper.getHelper(mContext);
        open();
        
    }
 
    public void open() throws SQLException {
        if(dbHelper == null)
            dbHelper = DataBaseHelper.getHelper(mContext);
        database = dbHelper.getWritableDatabase();
    }
    
    /*public void close() {
        dbHelper.close();
        database = null;
    }*/
}

Class diatas digunakan untuk menulis dan membaca dari database. Dibutuhkan objek SQLiteDatabase (yang mewakili database), diperoleh dengan memanggil getWritableDatabase() pada database helper.
Kemudian kita akan membuat class KaryawanDAO yang akan menghubungkan dan menggunakan objek SQLiteDatabase untuk menyediakan metode SQLite operasi CRUD (Create, Read, Update, Delete).
Memasukan Record Baru Pada Database SQLite
Karyawan

Dalam folder src, buat class Karyawan pada package firman.salatigadev.androidsqlite.to. Class ini merepresentasikan karyawan untuk disimpan dalam database dan class ini akan mengimplementasikan interface karena kita perlu untuk objek Karyawan sebagai argumen ketika menampilkan custom dialog fragmen untuk memperbarui data karyawan.

src/firman.salatigadev.androidsqlite.to/Karyawan.java
package firman.salatigadev.androidsqlite.to;

import java.util.Date;
import android.os.Parcel;
import android.os.Parcelable;

public class Karyawan implements Parcelable {
	
	private int id;
    private String nama;
    private Date tanggal_lahir;
    private double gaji;
 
    public Karyawan() {
        super();
    }
 
    private Karyawan(Parcel in) {
        super();
        this.id = in.readInt();
        this.nama = in.readString();
        this.tanggal_lahir = new Date(in.readLong());
        this.gaji = in.readDouble();
    }
 
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public String getNama() {
        return nama;
    }
 
    public void setNama(String nama) {
        this.nama = nama;
    }
 
    public Date getTanggalLahir() {
        return tanggal_lahir;
    }
 
    public void setTanggalLahir(Date tanggal_lahir) {
        this.tanggal_lahir = tanggal_lahir;
    }
 
    public double getGaji() {
        return gaji;
    }
 
    public void setGaji(double gaji) {
        this.gaji = gaji;
    }
 
    @Override
    public String toString() {
        return "Karyawan [id=" + id + ", nama=" + nama + ", tanggal_lahir="
                + tanggal_lahir + ", gaji=" + gaji + "]";
    }
 
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        return result;
    }
 
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Karyawan other = (Karyawan) obj;
        if (id != other.id)
            return false;
        return true;
    }
 
    @Override
    public int describeContents() {
        return 0;
    }
 
    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(getId());
        parcel.writeString(getNama());
        parcel.writeLong(getTanggalLahir().getTime());
        parcel.writeDouble(getGaji());
    }
 
    public static final Parcelable.Creator<Karyawan> CREATOR = new Parcelable.Creator<Karyawan>() {
        public Karyawan createFromParcel(Parcel in) {
            return new Karyawan(in);
        }
 
        public Karyawan[] newArray(int size) {
            return new Karyawan[size];
        }
    };
    
}

KaryawanDAO
Buat class KaryawanDAO di folder src dalam package firman.salatigadev.androidsqlite.db. Class ini meluaskan class KaryawanDBDAO dan mengimplementasikan operasi database seperti mengambil, menyimpan, update, dan menghapus objek karyawan.

src/firman.salatigadev.androidsqlite.db/KaryawanDAO.java
package firman.salatigadev.androidsqlite.db;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Locale;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;

import firman.salatigadev.androidsqlite.to.Karyawan;

public class KaryawanDAO extends KaryawanDBDAO {
	
	private static final String WHERE_ID_EQUALS = DataBaseHelper.ID
			+ " =?";
	private static final SimpleDateFormat formatter = new SimpleDateFormat(
			"yyyy-MM-dd", Locale.ENGLISH);

	public KaryawanDAO(Context context) {
		super(context);
	}
        
...
         public long save(Karyawan karyawan) {
		ContentValues values = new ContentValues();
		values.put(DataBaseHelper.NAMA, karyawan.getNama());
		Log.d("tgllahir", karyawan.getTanggalLahir().getTime() + "");
		values.put(DataBaseHelper.TANGGAL_LAHIR, formatter.format(karyawan.getTanggalLahir()));
		values.put(DataBaseHelper.GAJI, karyawan.getGaji());

		return database.insert(DataBaseHelper.TABEL_KARYAWAN, null, values);
	}
...

Di sini kita format ‘tanggal lahir’ sebagai ‘yyyy-mm-dd’ dengan menggunakan SimpleDateFormatter agar kompatibel dengan jenis tanggal SQLite. Untuk menyisipkan baris baru di SQLite, kita menggunakan ContentValues yang menentukan kunci nilai mewakili nama kolom tabel dan nilai data untuk kolom.

AddFragment
Dalam folder src, buat class AddFragment dalam package firman.salatigadev.androidsqlite.fragment. Fragment ini menampilkan form untuk memasukkan data karyawan seperti nama, tanggal lahir dan gaji. DatePickerDialog terbuka bila tanggal EditText lahir diklik. Aplikasi akan menjalankan tugas AsyncTask untuk menyimpan data karyawan dengan memanggil method save() pada class KaryawanDAO.

src/firman.salatigadev.androidsqlite.fragment/AddFragment.java
package firman.salatigadev.androidsqlite.fragment;

import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
 
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Toast;
 
import firman.salatigadev.androidsqlite.R;
import firman.salatigadev.androidsqlite.db.KaryawanDAO;
import firman.salatigadev.androidsqlite.to.Karyawan;

public class AddFragment extends Fragment implements OnClickListener {
	
	 //referensi form
    private EditText namaEtxt;
    private EditText gajiEtxt;
    private EditText tgllahirEtxt;
    private Button addButton;
    private Button resetButton;
 
    private static final SimpleDateFormat formatter = new SimpleDateFormat(
            "yyyy-MM-dd", Locale.ENGLISH);
 
    DatePickerDialog datePickerDialog;
    Calendar dateCalendar;
 
    Karyawan karyawan = null;
    private KaryawanDAO karyawanDAO;
    private AddTask task;
 
    public static final String ARG_ITEM_ID = "add_fragment";
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        karyawanDAO = new KaryawanDAO(getActivity());
    }
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_add, container,
                false);
 
        findViewsById(rootView);
 
        setListeners();
 
        if (savedInstanceState != null) {
            dateCalendar = Calendar.getInstance();
            if (savedInstanceState.getLong("dateCalendar") != 0)
                dateCalendar.setTime(new Date(savedInstanceState
                        .getLong("dateCalendar")));
        }
 
        return rootView;
    }
 
    private void setListeners() {
    	tgllahirEtxt.setOnClickListener(this);
        Calendar newCalendar = Calendar.getInstance();
        datePickerDialog = new DatePickerDialog(getActivity(),
                new OnDateSetListener() {
 
                    public void onDateSet(DatePicker view, int year,
                            int monthOfYear, int dayOfMonth) {
                        dateCalendar = Calendar.getInstance();
                        dateCalendar.set(year, monthOfYear, dayOfMonth);
                        tgllahirEtxt.setText(formatter.format(dateCalendar
                                .getTime()));
                    }
 
                }, newCalendar.get(Calendar.YEAR),
                newCalendar.get(Calendar.MONTH),
                newCalendar.get(Calendar.DAY_OF_MONTH));
 
        addButton.setOnClickListener(this);
        resetButton.setOnClickListener(this);
    }
 
    protected void resetAllFields() {
    	namaEtxt.setText("");
    	gajiEtxt.setText("");
        tgllahirEtxt.setText("");
    }
 
    private void setKaryawan() {
    	karyawan = new Karyawan();
    	karyawan.setNama(namaEtxt.getText().toString());
    	karyawan.setGaji(Double.parseDouble(gajiEtxt.getText()
                .toString()));
        if (dateCalendar != null)
        	karyawan.setTanggalLahir(dateCalendar.getTime());
    }
 
    @Override
    public void onResume() {
        getActivity().setTitle(R.string.add_kar);
        getActivity().getActionBar().setTitle(R.string.add_kar);
        super.onResume();
    }
 
    @Override
    public void onSaveInstanceState(Bundle outState) {
        if (dateCalendar != null)
            outState.putLong("dateCalendar", dateCalendar.getTime().getTime());
    }
 
    private void findViewsById(View rootView) {
    	namaEtxt = (EditText) rootView.findViewById(R.id.edit_txt_nama);
    	gajiEtxt = (EditText) rootView.findViewById(R.id.edit_txt_gaji);
    	tgllahirEtxt = (EditText) rootView.findViewById(R.id.edit_txt_tgllahir);
    	tgllahirEtxt.setInputType(InputType.TYPE_NULL);
 
        addButton = (Button) rootView.findViewById(R.id.button_add);
        resetButton = (Button) rootView.findViewById(R.id.button_reset);
    }
 
    @Override
    public void onClick(View view) {
        if (view == tgllahirEtxt) {
            datePickerDialog.show();
        } else if (view == addButton) {
            setKaryawan();
 
            task = new AddTask(getActivity());
            task.execute((Void) null);
        } else if (view == resetButton) {
            resetAllFields();
        }
    }
 
    public class AddTask extends AsyncTask<Void, Void, Long> {
 
        private final WeakReference<Activity> activityWeakRef;
 
        public AddTask(Activity context) {
            this.activityWeakRef = new WeakReference<Activity>(context);
        }
 
        @Override
        protected Long doInBackground(Void... arg0) {
            long result = karyawanDAO.save(karyawan);
            return result;
        }
 
        @Override
        protected void onPostExecute(Long result) {
            if (activityWeakRef.get() != null
                    && !activityWeakRef.get().isFinishing()) {
                if (result != -1)
                    Toast.makeText(activityWeakRef.get(), "Simpan Karyawan",
                            Toast.LENGTH_LONG).show();
            }
        }
    }
}

Mengambil Record Dari Database SQLite
KaryawanDAO
Pada class KaryawanDAO di atas, tambahkan dibawah method getKaryawans() untuk mendapatkan semua record dari database.

src/firman.salatigadev.androidsqlite.db/KaryawanDAO.java
public ArrayList<Karyawan> getKaryawans() {
		ArrayList<Karyawan> karyawans = new ArrayList<Karyawan>();

		Cursor cursor = database.query(DataBaseHelper.TABEL_KARYAWAN,
				new String[] { DataBaseHelper.ID,
						DataBaseHelper.NAMA,
						DataBaseHelper.TANGGAL_LAHIR,
						DataBaseHelper.GAJI }, null, null, null,
				null, null);

		while (cursor.moveToNext()) {
			Karyawan karyawan = new Karyawan();
			karyawan.setId(cursor.getInt(0));
			karyawan.setNama(cursor.getString(1));
			try {
				karyawan.setTanggalLahir(formatter.parse(cursor.getString(2)));
			} catch (ParseException e) {
				karyawan.setTanggalLahir(null);
			}
			karyawan.setGaji(cursor.getDouble(3));

			karyawans.add(karyawan);
		}
		return karyawans;
	}	

ListAdapter
Buat class ListAdapter di folder src baru dalam package firman.salatigadev.androidsqlite.adapter. Ini adalah custom list yang menampilkan data karyawan (id, nama, tanggal lahir dan gaji).

src/firman.salatigadev.androidsqlite.adapter/ListAdapter.java
package firman.salatigadev.androidsqlite.adapter;

import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
 
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
 
import firman.salatigadev.androidsqlite.R;
import firman.salatigadev.androidsqlite.to.Karyawan;

public class ListAdapter extends ArrayAdapter<Karyawan> {
	
	private Context context;
    List<Karyawan> karyawans;
 
    private static final SimpleDateFormat formatter = new SimpleDateFormat(
            "yyyy-MM-dd", Locale.ENGLISH);
 
    public ListAdapter(Context context, List<Karyawan> karyawans) {
        super(context, R.layout.list_item, karyawans);
        this.context = context;
        this.karyawans = karyawans;
    }
 
    private class ViewHolder {
        TextView idTxt;
        TextView namaTxt;
        TextView tgllahirTxt;
        TextView gajiTxt;
    }
 
    @Override
    public int getCount() {
        return karyawans.size();
    }
 
    @Override
    public Karyawan getItem(int position) {
        return karyawans.get(position);
    }
 
    @Override
    public long getItemId(int position) {
        return 0;
    }
 
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.list_item, null);
            holder = new ViewHolder();
 
            holder.idTxt = (TextView) convertView
                    .findViewById(R.id.txt_kar_id);
            holder.namaTxt = (TextView) convertView
                    .findViewById(R.id.txt_kar_nama);
            holder.tgllahirTxt = (TextView) convertView
                    .findViewById(R.id.txt_kar_tgllahir);
            holder.gajiTxt = (TextView) convertView
                    .findViewById(R.id.txt_kar_gaji);
 
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        Karyawan karyawan = (Karyawan) getItem(position);
        holder.idTxt.setText(karyawan.getId() + "");
        holder.namaTxt.setText(karyawan.getNama());
        holder.gajiTxt.setText(karyawan.getGaji() + "");
 
        holder.tgllahirTxt.setText(formatter.format(karyawan.getTanggalLahir()));
 
        return convertView;
    }
 
    @Override
    public void add(Karyawan karyawan) {
    	karyawans.add(karyawan);
        notifyDataSetChanged();
        super.add(karyawan);
    }
 
    @Override
    public void remove(Karyawan karyawan) {
    	karyawans.remove(karyawan);
        notifyDataSetChanged();
        super.remove(karyawan);
    }
    
}

Menampilkan Record kedalam Listview
ListFragment
Dalam folder src buat class ListFragment baru dalam package firman.salatigadev.androidsqlite.fragment. Class Fragment ini menjalankan method getKaryawans() pada KaryawanDAO dan menampilkan daftar tampilan karyawan kedalam ListView.
Ketika item daftar diklik maka akan menampilkan fragment dialog untuk memperbarui rincian karyawan. Pada item daftar, klik dan tahan agak lama maka akan menghapus data karyawan dari database.

src/firman.salatigadev.androidsqlite.fragment/ListFragment.java
package firman.salatigadev.androidsqlite.fragment;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
 
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import android.widget.Toast;
 
import firman.salatigadev.androidsqlite.R;
import firman.salatigadev.androidsqlite.adapter.ListAdapter;
import firman.salatigadev.androidsqlite.db.KaryawanDAO;
import firman.salatigadev.androidsqlite.to.Karyawan;

public class ListFragment extends Fragment implements OnItemClickListener,
OnItemLongClickListener {
	
	public static final String ARG_ITEM_ID = "list_karyawan";
	 
    Activity activity;
    ListView karyawanListView;
    ArrayList<Karyawan> karyawans;
 
    ListAdapter karyawanListAdapter;
    KaryawanDAO karyawanDAO;
 
    private GetTask task;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activity = getActivity();
        karyawanDAO = new KaryawanDAO(activity);
    }
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_list, container,
                false);
        findViewsById(view);
 
        task = new GetTask(activity);
        task.execute((Void) null);
 
        karyawanListView.setOnItemClickListener(this);
        karyawanListView.setOnItemLongClickListener(this);
        return view;
    }
 
    private void findViewsById(View view) {
    	karyawanListView = (ListView) view.findViewById(R.id.list_kar);
    }
 
    @Override
    public void onResume() {
        getActivity().setTitle(R.string.app_name);
        getActivity().getActionBar().setTitle(R.string.app_name);
        super.onResume();
    }
 
    @Override
    public void onItemClick(AdapterView<?> list, View arg1, int position,
            long arg3) {
    	Karyawan karyawan = (Karyawan) list.getItemAtPosition(position);
 
        if (karyawan != null) {
            Bundle arguments = new Bundle();
            arguments.putParcelable("selectedKaryawan", karyawan);
            CustomDialogFragment customDialogFragment = new CustomDialogFragment();
            customDialogFragment.setArguments(arguments);
            customDialogFragment.show(getFragmentManager(),
                    CustomDialogFragment.ARG_ITEM_ID);
        }
    }
 
    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view,
            int position, long arg3) {
    	Karyawan karyawan = (Karyawan) parent.getItemAtPosition(position);
 
        //AsyncTask menghapus data dari database
    	karyawanDAO.delete(karyawan);
        karyawanListAdapter.remove(karyawan);
        return true;
    }
 
    public class GetTask extends AsyncTask<Void, Void, ArrayList<Karyawan>> {
 
        private final WeakReference<Activity> activityWeakRef;
 
        public GetTask(Activity context) {
            this.activityWeakRef = new WeakReference<Activity>(context);
        }
 
        @Override
        protected ArrayList<Karyawan> doInBackground(Void... arg0) {
            ArrayList<Karyawan> karyawanList = karyawanDAO.getKaryawans();
            return karyawanList;
        }
 
        @Override
        protected void onPostExecute(ArrayList<Karyawan> karList) {
            if (activityWeakRef.get() != null
                    && !activityWeakRef.get().isFinishing()) {
                Log.d("karyawan", karList.toString());
                karyawans = karList;
                if (karList != null) {
                    if (karList.size() != 0) {
                    	karyawanListAdapter = new ListAdapter(activity,
                        		karList);
                    	karyawanListView.setAdapter(karyawanListAdapter);
                    } else {
                        Toast.makeText(activity, "Records Karyawan Tidak Ada",
                                Toast.LENGTH_LONG).show();
                    }
                }
 
            }
        }
    }
 
    /*
     * This method is invoked from MainActivity onFinishDialog() method. It is
     * called from CustomEmpDialogFragment when an employee record is updated.
     * This is used for communicating between fragments.
     */
    public void updateView() {
        task = new GetTask(activity);
        task.execute((Void) null);
    }
    
}

Update Data Pada Database SQLite
KaryawanDAO
Pada class KaryawanDAO di atas, tambahkan method berikut untuk meng-update data dari database.

src/firman.salatigadev.androidsqlite.db/KaryawanDAO.java
public long update(Karyawan karyawan) {
		ContentValues values = new ContentValues();
		values.put(DataBaseHelper.NAMA, karyawan.getNama());
		values.put(DataBaseHelper.TANGGAL_LAHIR, formatter.format(karyawan.getTanggalLahir()));
		values.put(DataBaseHelper.GAJI, karyawan.getGaji());

		long result = database.update(DataBaseHelper.TABEL_KARYAWAN, values,
				WHERE_ID_EQUALS,
				new String[] { String.valueOf(karyawan.getId()) });
		Log.d("Hasil Update :", "=" + result);
		return result;

	}

CustomDialogFragment
Buat class CustomDialogFragment pada folder src dalam package firman.salatigadev.androidsqlite.fragment. Class akan menerima obyek karyawan dan menampilkan dialog dengan rincian update data karyawan (nama, tgl lahir, gaji). Jika update berhasil, maka akan memanggil method onFinishDialog() pada MainActivity untuk memberitahu ListView(ListFragment).

src/firman.salatigadev.androidsqlite.fragment/CustomDialogFragment.java
package firman.salatigadev.androidsqlite.fragment;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
 
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
 
import firman.salatigadev.androidsqlite.MainActivity;
import firman.salatigadev.androidsqlite.R;
import firman.salatigadev.androidsqlite.db.KaryawanDAO;
import firman.salatigadev.androidsqlite.to.Karyawan;

public class CustomDialogFragment extends DialogFragment {
	
	//referensi form
    private EditText namaEtxt;
    private EditText gajiEtxt;
    private EditText tgllahirEtxt;
    private LinearLayout submitLayout;
 
    private Karyawan karyawan;
 
    private static final SimpleDateFormat formatter = new SimpleDateFormat(
            "yyyy-MM-dd", Locale.ENGLISH);
    
    KaryawanDAO karyawanDAO;
    
    public static final String ARG_ITEM_ID = "emp_dialog_fragment";
 
    public interface DialogFragmentListener {
        void onFinishDialog();
    }
 
    public CustomDialogFragment() {
 
    }
 
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
    	karyawanDAO = new KaryawanDAO(getActivity());
 
        Bundle bundle = this.getArguments();
        karyawan = bundle.getParcelable("selectedKaryawan");
 
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();
 
        View customDialogView = inflater.inflate(R.layout.fragment_add, null);
        builder.setView(customDialogView);
 
        namaEtxt = (EditText) customDialogView.findViewById(R.id.edit_txt_nama);
        gajiEtxt = (EditText) customDialogView
                .findViewById(R.id.edit_txt_gaji);
        tgllahirEtxt = (EditText) customDialogView.findViewById(R.id.edit_txt_tgllahir);
        submitLayout = (LinearLayout) customDialogView
                .findViewById(R.id.layout_submit);
        submitLayout.setVisibility(View.GONE);
 
        setValue();
 
        builder.setTitle(R.string.update_kar);
        builder.setCancelable(false);
        builder.setPositiveButton(R.string.update,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        try {
                        	karyawan.setTanggalLahir(formatter.parse(tgllahirEtxt.getText().toString()));
                        } catch (ParseException e) {
                            Toast.makeText(getActivity(),
                                    "Format data tidak valid!",
                                    Toast.LENGTH_SHORT).show();
                            return;
                        }
                        karyawan.setNama(namaEtxt.getText().toString());
                        karyawan.setGaji(Double.parseDouble(gajiEtxt
                                .getText().toString()));
                        long result = karyawanDAO.update(karyawan);
                        if (result > 0) {
                            MainActivity activity = (MainActivity) getActivity();
                            activity.onFinishDialog();
                        } else {
                            Toast.makeText(getActivity(),
                                    "Unable to update employee",
                                    Toast.LENGTH_SHORT).show();
                        }
                    }
                });
        builder.setNegativeButton(R.string.cancel,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });
 
        AlertDialog alertDialog = builder.create();
 
        return alertDialog;
    }
 
    private void setValue() {
        if (karyawan != null) {
        	namaEtxt.setText(karyawan.getNama());
        	gajiEtxt.setText(karyawan.getGaji() + "");
        	tgllahirEtxt.setText(formatter.format(karyawan.getTanggalLahir()));
        }
    }
}

Hapus Data Dari Database SQLite
KaryawanDAO

Pada class KaryawanDAO di atas, tambahkan method berikut untuk menghapus data dari database.

src/firman.salatigadev.androidsqlite.db/KaryawanDAO.java
public int delete(Karyawan karyawan) {
		return database.delete(DataBaseHelper.TABEL_KARYAWAN, WHERE_ID_EQUALS,
				new String[] { karyawan.getId() + "" });
	}

ListFragment akan memanggil method delete() pada item ketika diklik agak lama.
Code Class KaryawanDAO Lengkap

src/firman.salatigadev.androidsqlite.db/KaryawanDAO.java
package firman.salatigadev.androidsqlite.db;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Locale;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;

import firman.salatigadev.androidsqlite.to.Karyawan;

public class KaryawanDAO extends KaryawanDBDAO {
	
	private static final String WHERE_ID_EQUALS = DataBaseHelper.ID
			+ " =?";
	private static final SimpleDateFormat formatter = new SimpleDateFormat(
			"yyyy-MM-dd", Locale.ENGLISH);

	public KaryawanDAO(Context context) {
		super(context);
	}

	public long save(Karyawan karyawan) {
		ContentValues values = new ContentValues();
		values.put(DataBaseHelper.NAMA, karyawan.getNama());
		Log.d("tgllahir", karyawan.getTanggalLahir().getTime() + "");
		values.put(DataBaseHelper.TANGGAL_LAHIR, formatter.format(karyawan.getTanggalLahir()));
		values.put(DataBaseHelper.GAJI, karyawan.getGaji());

		return database.insert(DataBaseHelper.TABEL_KARYAWAN, null, values);
	}

	public long update(Karyawan karyawan) {
		ContentValues values = new ContentValues();
		values.put(DataBaseHelper.NAMA, karyawan.getNama());
		values.put(DataBaseHelper.TANGGAL_LAHIR, formatter.format(karyawan.getTanggalLahir()));
		values.put(DataBaseHelper.GAJI, karyawan.getGaji());

		long result = database.update(DataBaseHelper.TABEL_KARYAWAN, values,
				WHERE_ID_EQUALS,
				new String[] { String.valueOf(karyawan.getId()) });
		Log.d("Hasil Update :", "=" + result);
		return result;

	}

	public int delete(Karyawan karyawan) {
		return database.delete(DataBaseHelper.TABEL_KARYAWAN, WHERE_ID_EQUALS,
				new String[] { karyawan.getId() + "" });
	}

	public ArrayList<Karyawan> getKaryawans() {
		ArrayList<Karyawan> karyawans = new ArrayList<Karyawan>();

		Cursor cursor = database.query(DataBaseHelper.TABEL_KARYAWAN,
				new String[] { DataBaseHelper.ID,
						DataBaseHelper.NAMA,
						DataBaseHelper.TANGGAL_LAHIR,
						DataBaseHelper.GAJI }, null, null, null,
				null, null);

		while (cursor.moveToNext()) {
			Karyawan karyawan = new Karyawan();
			karyawan.setId(cursor.getInt(0));
			karyawan.setNama(cursor.getString(1));
			try {
				karyawan.setTanggalLahir(formatter.parse(cursor.getString(2)));
			} catch (ParseException e) {
				karyawan.setTanggalLahir(null);
			}
			karyawan.setGaji(cursor.getDouble(3));

			karyawans.add(karyawan);
		}
		return karyawans;
	}	
	
	//Mengambil satu record karyawan dengan id yang diberikan
	public Karyawan getKaryawan(long id) {
		Karyawan karyawan = null;

		String sql = "SELECT * FROM " + DataBaseHelper.TABEL_KARYAWAN
				+ " WHERE " + DataBaseHelper.ID + " = ?";

		Cursor cursor = database.rawQuery(sql, new String[] { id + "" });

		if (cursor.moveToNext()) {
			karyawan = new Karyawan();
			karyawan.setId(cursor.getInt(0));
			karyawan.setNama(cursor.getString(1));
			try {
				karyawan.setTanggalLahir(formatter.parse(cursor.getString(2)));
			} catch (ParseException e) {
				karyawan.setTanggalLahir(null);
			}
			karyawan.setGaji(cursor.getDouble(3));
		}
		return karyawan;
	}
}

MainActivity
Class MainActivity adalah class utama ketika aplikasi dijalankan, kita tambahkan ListFragment. Activity ini akan menangani method onBackPressed() dan akan menunjukkan dialog peringatan ketika ingin berhenti/keluar aplikasi.

src/firman.salatigadev.androidsqlite/MainActivity.java
package firman.salatigadev.androidsqlite;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.Menu;
import android.view.MenuItem;
 
import firman.salatigadev.androidsqlite.fragment.CustomDialogFragment.DialogFragmentListener;
import firman.salatigadev.androidsqlite.fragment.AddFragment;
import firman.salatigadev.androidsqlite.fragment.ListFragment;

public class MainActivity extends FragmentActivity implements DialogFragmentListener {
	
	private Fragment contentFragment;
    private ListFragment karyawanListFragment;
    private AddFragment karyawanAddFragment;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		FragmentManager fragmentManager = getSupportFragmentManager();
		
		/*
         * This is called when orientation is changed.
         */
        if (savedInstanceState != null) {
            if (savedInstanceState.containsKey("content")) {
                String content = savedInstanceState.getString("content");
                if (content.equals(AddFragment.ARG_ITEM_ID)) {
                    if (fragmentManager
                            .findFragmentByTag(AddFragment.ARG_ITEM_ID) != null) {
                        setFragmentTitle(R.string.add_kar);
                        contentFragment = fragmentManager
                                .findFragmentByTag(AddFragment.ARG_ITEM_ID);
                    }
                }
            }
            if (fragmentManager.findFragmentByTag(ListFragment.ARG_ITEM_ID) != null) {
                karyawanListFragment = (ListFragment) fragmentManager
                        .findFragmentByTag(ListFragment.ARG_ITEM_ID);
                contentFragment = karyawanListFragment;
            }
        } else {
        	karyawanListFragment = new ListFragment();
            setFragmentTitle(R.string.app_name);
            switchContent(karyawanListFragment, ListFragment.ARG_ITEM_ID);
        }
    }
 
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        if (contentFragment instanceof AddFragment) {
            outState.putString("content", AddFragment.ARG_ITEM_ID);
        } else {
            outState.putString("content", ListFragment.ARG_ITEM_ID);
        }
        super.onSaveInstanceState(outState);
    }

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_add:
            setFragmentTitle(R.string.add_kar);
            karyawanAddFragment = new AddFragment();
            switchContent(karyawanAddFragment, AddFragment.ARG_ITEM_ID);
 
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
 
    /*
     * We consider EmpListFragment as the home fragment and it is not added to
     * the back stack.
     */
    public void switchContent(Fragment fragment, String tag) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        while (fragmentManager.popBackStackImmediate())
            ;
 
        if (fragment != null) {
            FragmentTransaction transaction = fragmentManager
                    .beginTransaction();
            transaction.replace(R.id.content_frame, fragment, tag);
            
            if (!(fragment instanceof ListFragment)) {
                transaction.addToBackStack(tag);
            }
            transaction.commit();
            contentFragment = fragment;
        }
    }
 
    protected void setFragmentTitle(int resourseId) {
        setTitle(resourseId);
        getActionBar().setTitle(resourseId);
 
    }
 
    /*
     * We call super.onBackPressed(); when the stack entry count is > 0. if it
     * is instanceof EmpListFragment or if the stack entry count is == 0, then
     * we prompt the user whether to quit the app or not by displaying dialog.
     * In other words, from EmpListFragment on back press it quits the app.
     */
    @Override
    public void onBackPressed() {
        FragmentManager fm = getSupportFragmentManager();
        if (fm.getBackStackEntryCount() > 0) {
            super.onBackPressed();
        } else if (contentFragment instanceof ListFragment
                || fm.getBackStackEntryCount() == 0) {
            //tampilkan dialog ketika keluar
            onShowQuitDialog();
        }
    }
 
    public void onShowQuitDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setCancelable(false);
 
        builder.setMessage("Anda Ingin Keluar?");
        builder.setPositiveButton(android.R.string.yes,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        finish();
                    }
                });
        builder.setNegativeButton(android.R.string.no,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });
        builder.create().show();
    }
 
    @Override
    public void onFinishDialog() {
        if (karyawanListFragment != null) {
        	karyawanListFragment.updateView();
        }
    }
}

Running aplikasi.
           

You may also like...

3 Responses

  1. I do accept as true with all of the ideas you have offered to your post.
    They’re very convincing and will definitely work.
    Still, the posts are too quick for newbies. May you please prolong them a bit from subsequent time?
    Thanks for the post.

  2. girls hookup says:

    I have been browsing online more than 2 hours today, yet I never
    found any interesting article like yours. It’s pretty worth enough for me.
    In my view, if all web owners and bloggers made good content as you
    did, the web will be a lot more useful than ever before.

  3. Fikri says:

    Assalamualaikum, saya ingin tanya ketika kita sudah tau masing-masing gaji pegawai. Gimana cara untuk menghitung total dari gaji pegawai tersebut. Trims

Leave a Reply

Your email address will not be published. Required fields are marked *