Dokumen tersebut memberikan tutorial singkat tentang pembuatan aplikasi resep masakan sederhana menggunakan database SQLite untuk menyimpan dan menampilkan data resep, mencakup penjelasan tentang layout, activity, dan implementasi database.
2. ➢ Tujuan
Membuat Aplikasi Resep masakan sederhana dengan menampilkan data data
yang telah ada pada database SQLite.
➢ Materi
• Splash Screen
• Progress Bar
• ListView Layouting
• SQLite database
• Database Search
➢ Tool
Eclipse + Android SDK (adt bundle)
➢ Pembahasan
Persiapkan IDE anda untuk memulai koding, disini saya memakai eclipse
Kepler. Buat project baru dengan klik tab File di menu bar kemudian
pilih New dan pilih Android Application Project. Untuk Penamaan
terserah anda, saya memberikan nama project AndroidSimpleRecipe.
3. Kemudian untuk basic layout untuk app resep ini kita membutuhkan
beberapa file layout diantaranya adalah.
splashbe.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@+drawable/splashbe"
android:gravity="center_horizontal"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/activity_splash_progress_bar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginTop="370dp"/>
</LinearLayout>
Pada layout splashbe bisa kita liat struktur layout nya menggunakan
Linear layoot dengan tambahan palette berupa progress bar untuk
mempercantik tampilan loading splash, dan untuk backgroud nya sendiri
meload dari res/drawable/splashbe.jpg. Sedangkan untuk file java nya
adalah sebagai berikut:
Splashbe.java
package id.creatorb.resep;
import id.creatorb.resep.Task.TaskFinishedListener;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ProgressBar;
public class Splashbe extends Activity implements TaskFinishedListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// menampilkan background splashbe
setContentView(R.layout.splashbe);
// mencari progress bar
ProgressBar progressBar = (ProgressBar)
findViewById(R.id.activity_splash_progress_bar);
// memulai progress bar
new Task(progressBar, this).execute("www.google.co.uk"); // lewati langkah
ini karena ini hanyalah contoh untuk meload loading request dan tidak digunakan
disini.
4. }
// method untuk mengakhiri asynctask
@Override
public void onTaskFinished() {
completeSplash();
}
private void completeSplash(){
startApp();
finish(); // sisipkan perintah finish agar tidak melanjutkan
perulangan.
}
private void startApp() {
Intent intent = new Intent(Splashbe.this, MainActivity.class);
startActivity(intent);
}
}
dalam class Splashbe melakukan extends dengan TaskFinishedListener
dimana activity tersebut ada pada class Task berikut.
Task.java
package id.creatorb.resep;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ProgressBar;
public class Task extends AsyncTask<String, Integer, Integer> {
public interface TaskFinishedListener {
void onTaskFinished(); //menambahkan parameter finished untuk mencegah
task di ulang kembali
// progress bar berjalan ketika ada sesuatu yang hendak di update dibelakang
layar
private final ProgressBar progressBar;
// listener untuk mendeteksi proses telah berakhir
private final TaskFinishedListener finishedListener;
public Task(ProgressBar progressBar, TaskFinishedListener finishedListener) {
this.progressBar = progressBar;
this.finishedListener = finishedListener;
}
@Override
protected Integer doInBackground(String... params) {
Log.i("Tutorial", "Starting task with url: "+params[0]);
if(resourcesDontAlreadyExist()){
downloadResources();
}
5. // memungkinkan untuk kembali pada permintaan yang tereksekusi
return 1234;
}
private boolean resourcesDontAlreadyExist() {
// melakukan permintaan pada app internal utk melihat apakah progress sudah
complete atau belom
// memungkinkan yang telah dicek disimpan pada shared preference untuk
kecepatan load jika sewaktu2 aplikasi dijalankan kembali
return true; // jika true maka akan muncul setiap saat
}
private void downloadResources() {
// meniru beberapa proses downloading
int count = 10;
for (int i = 0; i < count; i++) {
// update progress sebanyak x
int progress = (int) ((i / (float) count) * 100);
publishProgress(progress);
// lama loading di lakukan
try { Thread.sleep(1000); } catch (InterruptedException ignore)
{}
}
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressBar.setProgress(values[0]); // menjalankan progress bar di ui
}
@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
finishedListener.onTaskFinished(); // pemberitahuan progress bar
selesai
}
}
6. Dari konfigurasi activity splash diatas maka akan memiliki layout
seperti ini.
Pada Splashbe.java sendiri terdapat Intent(Splashbe.this,
MainActivity.class) dengan kata lain ketika activity splashbe berakhir
maka app akan meload activity main / class MainActivity. Untuk layout
dari MainActivity sendiri ada pada main.xml berikut kodingannya.
Main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/btn"
android:layout_toLeftOf="@+id/btn"
android:hint="Cari Resep">
<requestFocus />
</EditText>
7. <Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:onClick="search_db"
android:text="Search"
android:textColor="#FFFFFF"
android:background="#C0C0C0" />
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/et" >
</ListView>
</RelativeLayout>
Diatas kita menggunakan beberapa palette diantaranya EditText untuk
memberikan akses input pada user yang nantinya akan digunakan untuk
fitur pencarian, kemudian button sebagai tombol eksekusi pencarian
data dan terakhir listview menampilkan data data yang ada pada
database dalam bentuk list / daftar. Berikut class dari main.
MainActivity.java
package id.creatorb.resep;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class MainActivity extends Activity {
//deklarasi
protected ListView lv;
protected ListAdapter adapter;
SQLiteDatabase db;
Cursor cursor;
EditText et_db;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
8. super.onCreate(savedInstanceState);
setContentView(R.layout.main);
db = (new DB_Resep(this)).getWritableDatabase();
lv = (ListView) findViewById(R.id.lv);
et_db = (EditText) findViewById(R.id.et);
try {
//select dari database resep, menampilkan nya secara urut sesuai abjad
cursor = db.rawQuery("SELECT * FROM resep ORDER BY nama ASC",
null);
adapter = new SimpleCursorAdapter(this, R.layout.isi_lv, cursor,
new String[] { "nama", "bahan", "img" }, new int[] {
R.id.tv_nama, R.id.tvBahan, R.id.imV });
lv.setAdapter(adapter);
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
detail(position);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
//method pencarian pada search box
public void search_db(View v) {
String edit_db = et_db.getText().toString();
if (!edit_db.equals("")) {
try {
cursor = db.rawQuery("SELECT * FROM resep WHERE nama
LIKE ?",
new String[] { "%" + edit_db + "%" });
adapter = new SimpleCursorAdapter(
this,
R.layout.isi_lv,
cursor,
new String[] { "nama", "bahan", "img" },
new int[] { R.id.tv_nama, R.id.tvBahan,
R.id.imV });
if (adapter.getCount() == 0) {
Toast.makeText(
this,
"Tidak ada " + edit_db
+ "",
Toast.LENGTH_SHORT).show();
} else {
lv.setAdapter(adapter);
}
} catch (Exception e) {
e.printStackTrace();
9. }
} else {
try {
cursor = db.rawQuery("SELECT * FROM resep ORDER BY nama
ASC",
null);
adapter = new SimpleCursorAdapter(
this,
R.layout.isi_lv,
cursor,
new String[] { "nama", "bahan", "img" },
new int[] { R.id.tv_nama, R.id.tvBahan,
R.id.imV });
lv.setAdapter(adapter);
lv.setTextFilterEnabled(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void detail(int position) {
int im = 0;
String _id = "";
String nama = "";
String bahan = "";
String cara = "";
if (cursor.moveToFirst()) {
cursor.moveToPosition(position);
im = cursor.getInt(cursor.getColumnIndex("img"));
nama = cursor.getString(cursor.getColumnIndex("nama"));
bahan = cursor.getString(cursor.getColumnIndex("bahan"));
cara = cursor.getString(cursor.getColumnIndex("cara"));
}
Intent iIntent = new Intent(this, DB_Parse.class);
iIntent.putExtra("dataIM", im);
iIntent.putExtra("dataNama", nama);
iIntent.putExtra("dataBahan", bahan);
iIntent.putExtra("dataCara", cara);
setResult(RESULT_OK, iIntent);
startActivityForResult(iIntent, 99);
}
}
Dari main activity diatas bisa kita lihat, disana meload data tabel
resep dari database db_resep yang telah disediakan (dibahas dalam
pembahasan selanjutnya) dan kemudian mengambil data nama resep dan
gambar / image yang tersedia pada resep tersebut selanjutnya di
parsing pada layout main.xml dengan tv_nama untuk nama resep dan imV
untuk gambar resep.
10. Pada activity main diatas juga ada method untuk pencarian pada search
box yang nantinya ketika button search di eksekusi maka pencarian
akan dilakukan pada database db_resep dan kemudian di tampilkan
sesuai layout sebelumnya (main.xml) dan jika tidak ditemukan data
maka akan muncul kembalian pesan untuk memberi tahukan bahwa data
yang sedang di cari tidak ada dalam database.
Dan berikut untuk menampilkan isi data yang ada dalam bentuk
listview.
isi_lv.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="@+id/imV"
android:layout_width="50px"
android:layout_height="50px"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_weight="1"
android:gravity="left"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/tv_nama"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/imV"
android:layout_marginLeft="3px"
android:text="TextView"
android:layout_weight="1"
android:gravity="center"
android:textSize="10pt"
android:textColor="#808080"
android:textStyle="bold" />
</RelativeLayout>
11. Tampilan nya seperti berikut:
Jika melakukan pencarian (ex: udang) maka akan tampil seperti ini.
12. Selanjutnya adalah pembahasan mengenai database db_resep. Database
ini berakar pada salah satu class yang bernama DB_Resep dimana semua
data yang ditampilkan tertampung menjadi satu dalam class ini.
DB_Resep.java
package id.creatorb.resep;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DB_Resep extends SQLiteOpenHelper {
//pembuatan database dengan nama db_resep
final static String DB_NAME = "db_resep";
public DB_Resep(Context context) {
super(context, DB_NAME, null, 1);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
//pada database db_resep membuat tabel baru bernama resep untuk di isi dengan
beberapa field diantaranya id (INT) nama (TEXT) bahan (TEXT) cara (TEXT) dan img
String sql = "CREATE TABLE IF NOT EXISTS resep(_id INTEGER PRIMARY KEY
AUTOINCREMENT, nama TEXT, bahan TEXT, cara TEXT, img BLOB)";
db.execSQL(sql);
//berikut ini adalah beberapa cuplikan content dari database
ContentValues values = new ContentValues();
values.put("_id", "1");
values.put("nama", "Bubur Candil");
values.put("bahan", "Tepung ketan putih 200 gr, Tepung beras putih 50
gr, Air 100 ml, Pewarna makanan (merah,hijau,kuning) secukupnya, Gula jawa / gula
merah 200 gr, Air 1 ltr, Santan 500 ml, Garam ½ sdt, Daun pandan 1 lbr");
values.put("cara","Pertama Masukkan tepung ketan dan tepung beras dalam
wadah, Kemudian tuangkan air sedikit demi sedikit hingga kalis (kental dan
lengket), Selanjutnya Basahi tangan dengan air lalu uleni lagi bila terasa adonan
masih kurang kalis. Setelah itu pisahkan adonan menjadi 3 bagian, lalu berikan
pewarna pada masing-masing adonan, Setelah itu bentuk bulat-bulat seperti kelereng.
Masak gula jawa dan air 1 ltr, biarkan hingga mendidih dan gula larut lalu saring
kemudian didihkan lagi, lalu cemplungkan bulatan adonan kedalamnya, biarkan hingga
mengapung. Lalu masukkan santan,garam,daun pandan. Aduk rata hingga mendidih, dan
kini bubur candil siap disajikan");
values.put("img", R.drawable.buburcandil); //memasukkan gambar dari
drawable
db.insert("resep", "_id", values);
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS resep");
13. onCreate(db);
}
}
dan untuk pencarian dan pencocokan masing masing string dan
ditampilkan keseluruhan (lengkap) item yang ada tidak seperti di
main.xml yang memang fungsinya sebagai thumbnail. Semuanya ada pada
resep.xml yang menampilkan image pada posisi top dalam layout dan
beberapa palette seperti scrollview untuk memudahkan content dalam
bentuk dinamis / responsif dan lain diantaranya adalah TextView.
Resep.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/paper"
android:orientation="vertical" >
< ImageVie w
android:id="@+id/iv_detail"
android:layout_width="fill_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:src="@drawable/buburcandil" />
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="10dp"
android:layout_below="@+id/iv_detail"
android:background="#3D3C3A" />
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/button1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_heigh t = "match_parent "
android:orientation="vertical" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLef t = "true "
android:layout_belo w = "@+id/iv_detail "
14. android:layout_marginTop="3dp"
android:tex t = "Resep "
android:textColor="#6e7b8b"
android:textStyle="bold" />
<TextView
android:id="@+id/tvNama"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLef t = "true "
android:layout_belo w = "@+id/textView2 "
android:tex t = "TextView "
android:textColor="#8b7b8b"
android:textStyle="italic" />
<TextView
android:id="@+id/tvTD"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLef t = "true "
android:layout_belo w = "@+id/tvNama "
android:tex t = "Bahan "
android:textColor="#6e7b8b"
android:textStyle="bold" />
<TextView
android:id="@+id/tvBahan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLef t = "true "
android:layout_belo w = "@+id/tvTD "
android:tex t = "TextView "
android:textColor="#8b7b8b"
android:textStyle="italic" />
<TextView
android:id="@+id/tvK"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLef t = "true "
android:layout_belo w = "@+id/tvBahan "
android:tex t = "Cara Memasak "
android:textColor="#6e7b8b"
android:textStyle="bold" />
<TextView
android:id="@+id/tvCara"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLef t = "true "
android:layout_belo w = "@+id/tvK "
android:tex t = "TextView "
android:textColor="#8b7b8b"
android:textStyle="italic" />
</LinearLayout>
15. </ScrollView>
</RelativeLayout>
dan class dari layout resep.xml diatas untuk memastikan parsing dari
database pada layout resep.xml ada pada DB_Parse.java
package id.creatorb.resep;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import androi d . widge t . Galler y;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.TextView;
public class DB_Parse extends Activity {
ImageView Im;
TextView tv_nama, tv_bahan, tv_cara, id;
Gallery gallery;
ImageSwitcher imageSwitcher;
Integer[] imageIDs = new Integer[3];
int msg_im;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.resep);
Intent iIdentifikasi = getIntent();
msg_im = iIdentifikasi.getIntExtra("dataIM", 0);
String msg_nama = iIdentifikasi.getStringExtra("dataNama");
String msg_bahan = iIdentifikasi.getStringExtra("dataBahan");
String msg_cara = iIdentifikasi.getStringExtra("dataCara");
Im = (ImageView) findViewById(R.id.iv_detail);
tv_nama = (TextView) findViewById(R.id.tvNama);
tv_bahan = (TextView) findViewById(R.id.tvBahan);
tv_cara = (TextView) findViewById(R.id.tvCara);
Im.setImageResource(msg_im);
tv_nama.setText(msg_nama);
tv_bahan.setText(msg_bahan);
tv_cara.setText(msg_cara);
}
}
16. Tampilannya akan tampak seperti ini
Okkay, kini anda bisa membuat aplikasi resep masakan anda sendiri
dengan mudah dan simple. Untuk pemahaman lebih lanjut mengenai konsep
dari aplikasi diatas silahkan melihat source code yang telah
disediakan.