(Tutorial Android) Tutorial Crud With Sqlite Database Android
SQLite ialah light weight database yang sanggup menyimpan data di device Android. Database ini sudah ditanamkan pada Android OS. SQLite sama halnya dengan DBMS lainnya, yaitu memakai query untuk memproses datanya, dan yang membedakannya dengan DBMS lainnya ialah tidak perlu connector untuk terhubung ke database ini alasannya ialah sudah include di Android.
Pada kali ini aku akan membahas bagaimana menyimpan dan mengakses data di SQLite. Atau biasa kita sebut CRUD ajalah :D
Simak tutorialnya berikut :
Tambahkan library yang diperlukan.
Kita buat desain dulu. Pertama buat layout dengan nama activity_main.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" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context="com.wimso.android_sqlite.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/lvContact" android:layout_width="match_parent" android:layout_height="wrap_content"/> <android.support.design.widget.FloatingActionButton android:id="@+id/add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:src="@drawable/ic_add_black_24dp" android:tint="#FFFFFF" app:rippleColor="#F48FB1" android:layout_marginRight="@dimen/activity_horizontal_margin" android:layout_marginBottom="@dimen/activity_horizontal_margin" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_marginEnd="@dimen/activity_horizontal_margin" /> </RelativeLayout>
Kemudian layout activity_act.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="@dimen/activity_horizontal_margin"> <EditText android:id="@+id/personText" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPersonName" android:hint="Insert person name" android:ems="10" android:layout_marginBottom="@dimen/margin_10" /> <EditText android:id="@+id/phoneText" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="phone" android:ems="10" android:hint="Insert phone number" android:layout_marginBottom="@dimen/margin_10" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/btnAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/add"/> <Button android:id="@+id/btnEdit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/edit" /> <Button android:id="@+id/btnDelete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/delete"/> </LinearLayout> </LinearLayout>
Kemudian. Layout list_contact_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="@dimen/margin_10"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/thumb" android:layout_width="60dp" android:layout_height="60dp" android:src="@mipmap/ic_launcher" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="@dimen/margin_10" android:orientation="vertical"> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" android:text="Small Text"/> <TextView android:id="@+id/phone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:text="Small Text" /> </LinearLayout> </LinearLayout> </LinearLayout>
Selanjutnya buat kelas sebagai “constant” dengan nama ContactField.java
package com.wimso.android_sqlite.constant; /** * Created by wim on 4/26/16. */ public class ContactField { public static akibat String TABLE_NAME = "contact"; public static akibat String COLUMN_ID = "contact_id"; public static akibat String COLUMN_NAME = "contact_name"; public static akibat String COLUMN_PHONE = "contact_phone"; }
Buat kelas model untuk kontak dengan nama Contact.java
package com.wimso.android_sqlite.model; import android.os.Parcel; import android.os.Parcelable; /** * Created by wim on 4/26/16. */ public class Contact implements Parcelable { private int id; private String name; private String phone; public Contact() { } protected Contact(Parcel in) { this.id = in.readInt(); this.name = in.readString(); this.phone = in.readString(); } public static akibat Parcelable.Creator<Contact> CREATOR = new Parcelable.Creator<Contact>() { @Override public Contact createFromParcel(Parcel source) { return new Contact(source); } @Override public Contact[] newArray(int size) { return new Contact[size]; } }; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(this.id); dest.writeString(this.name); dest.writeString(this.phone); } }
Kemudian buat kelas dengan nama LetterTile.java, jadi kelas ini nanti fungsinya untuk menampilkan thumbail kontak dengan abjad pertama dari nama kontak. Kebayang gag? Yah nanti aja lihat hasilnya.
package com.wimso.android_sqlite.widget; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; import android.text.TextPaint; import com.wimso.android_sqlite.R; /** * Created by wim on 5/2/16. */ public class LetterTile { /** The number of available tile colors (see R.array.letter_tile_colors) */ private static akibat int NUM_OF_TILE_COLORS = 8; /** The {@link TextPaint} used to draw the letter onto the tile */ private akibat TextPaint mPaint = new TextPaint(); /** The bounds that enclose the letter */ private akibat Rect mBounds = new Rect(); /** The {@link Canvas} to draw on */ private akibat Canvas mCanvas = new Canvas(); /** The first char of the name being displayed */ private akibat char[] mFirstChar = new char[1]; /** The background colors of the tile */ private akibat TypedArray mColors; /** The font size used to display the letter */ private akibat int mTileLetterFontSize; /** The default image to display */ private akibat Bitmap mDefaultBitmap; /** * Constructor forLetterTileProvider
* * @param context The {@link Context} to use */ public LetterTile(Context context) { akibat Resources res = context.getResources(); mPaint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL)); mPaint.setColor(Color.WHITE); mPaint.setTextAlign(Paint.Align.CENTER); mPaint.setAntiAlias(true); mColors = res.obtainTypedArray(R.array.letter_tile_colors); mTileLetterFontSize = res.getDimensionPixelSize(R.dimen.tile_letter_font_size); mDefaultBitmap = BitmapFactory.decodeResource(res, android.R.drawable.sym_def_app_icon); } /** * @param displayName The name used to create the letter for the tile * @param key The key used to generate the background color for the tile * @param width The desired width of the tile * @param height The desired height of the tile * @return A {@link Bitmap} that contains a letter used in the English * alphabet or digit, if there is no letter or digit available, a * default image is shown instead */ public Bitmap getLetterTile(String displayName, String key, int width, int height) { akibat Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); akibat char firstChar = displayName.charAt(0); akibat Canvas c = mCanvas; c.setBitmap(bitmap); c.drawColor(pickColor(key)); if (isEnglishLetterOrDigit(firstChar)) { mFirstChar[0] = Character.toUpperCase(firstChar); mPaint.setTextSize(mTileLetterFontSize); mPaint.getTextBounds(mFirstChar, 0, 1, mBounds); c.drawText(mFirstChar, 0, 1, 0 + width / 2, 0 + height / 2 + (mBounds.bottom - mBounds.top) / 2, mPaint); } else { c.drawBitmap(mDefaultBitmap, 0, 0, null); } return bitmap; } /** * @param c The char to check * @return True ifc
is in the English alphabet or is a digit, * false otherwise */ private static boolean isEnglishLetterOrDigit(char c) { return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9'; } /** * @param key The key used to generate the tile color * @return A new or previously chosen color forkey
used as the * tile background color */ private int pickColor(String key) { // String.hashCode() is not supposed to change across java versions, so // this should guarantee the same key always maps to the same color akibat int color = Math.abs(key.hashCode()) % NUM_OF_TILE_COLORS; try { return mColors.getColor(color, Color.BLACK); } finally { mColors.recycle(); } } }
Buat sebuah listener yang berfungsi dikala RecyclerView di klik.
package com.wimso.android_sqlite.listener; import android.view.View; /** * Created by wim on 5/2/16. */ public interface RecyclerItemClickListener { void onItemClick(int position, View view); }
Buat adapter dengan nama ContactListAdapter.java
package com.wimso.android_sqlite.adapter; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.wimso.android_sqlite.R; import com.wimso.android_sqlite.listener.RecyclerItemClickListener; import com.wimso.android_sqlite.model.Contact; import com.wimso.android_sqlite.widget.LetterTile; import java.util.ArrayList; import java.util.List; /** * Created by wim on 5/1/16. */ public class ContactListAdapter extends RecyclerView.Adapter<ContactListAdapter.ContactHolder>{ private List<Contact> contactList; private Context context; private RecyclerItemClickListener recyclerItemClickListener; public ContactListAdapter(Context context) { this.context = context; this.contactList = new ArrayList<>(); } private void add(Contact item) { contactList.add(item); notifyItemInserted(contactList.size() - 1); } public void addAll(List<Contact> contactList) { for (Contact contact : contactList) { add(contact); } } public void remove(Contact item) { int position = contactList.indexOf(item); if (position > -1) { contactList.remove(position); notifyItemRemoved(position); } } public void clear() { while (getItemCount() > 0) { remove(getItem(0)); } } public Contact getItem(int position) { return contactList.get(position); } @Override public ContactHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_contact_item, parent, false); akibat ContactHolder contactHolder = new ContactHolder(view); contactHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int adapterPos = contactHolder.getAdapterPosition(); if (adapterPos != RecyclerView.NO_POSITION) { if (recyclerItemClickListener != null) { recyclerItemClickListener.onItemClick(adapterPos, contactHolder.itemView); } } } }); return contactHolder; } @Override public void onBindViewHolder(ContactHolder holder, int position) { akibat Contact contact = contactList.get(position); akibat Resources res = context.getResources(); akibat int tileSize = res.getDimensionPixelSize(R.dimen.letter_tile_size); LetterTile letterTile = new LetterTile(context); Bitmap letterBitmap = letterTile.getLetterTile(contact.getName(), String.valueOf(contact.getId()), tileSize, tileSize); holder.thumb.setImageBitmap(letterBitmap); holder.name.setText(contact.getName()); holder.phone.setText(contact.getPhone()); } @Override public int getItemCount() { return contactList.size(); } public void setOnItemClickListener(RecyclerItemClickListener recyclerItemClickListener) { this.recyclerItemClickListener = recyclerItemClickListener; } static class ContactHolder extends RecyclerView.ViewHolder { ImageView thumb; TextView name; TextView phone; public ContactHolder(View itemView) { super(itemView); thumb = (ImageView) itemView.findViewById(R.id.thumb); name = (TextView) itemView.findViewById(R.id.name); phone = (TextView) itemView.findViewById(R.id.phone); } } }
Nah, kini kita buat kelas untuk konfiguras database SQLite berserta method-method untuk CRUD. Buat dengan nama SQLiteDB.
package com.wimso.android_sqlite.db; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import com.wimso.android_sqlite.constant.ContactField; import com.wimso.android_sqlite.model.Contact; /** * Created by wim on 4/26/16. */ public class SQLiteDB extends SQLiteOpenHelper { // If you change the database schema, you must increment the database version. public static akibat int DATABASE_VERSION = 1; public static akibat String DATABASE_NAME = "Contact.db"; private static akibat String TEXT_TYPE = " TEXT"; private static akibat String COMMA_SEP = ","; private static akibat String SQL_CREATE_ENTRIES = "CREATE TABLE " + ContactField.TABLE_NAME + " (" + ContactField.COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + ContactField.COLUMN_NAME + TEXT_TYPE + COMMA_SEP + ContactField.COLUMN_PHONE + TEXT_TYPE + " )"; private static akibat String SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS " + ContactField.TABLE_NAME; public SQLiteDB(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(SQL_CREATE_ENTRIES); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL(SQL_DELETE_ENTRIES); onCreate(db); } public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { onUpgrade(db, oldVersion, newVersion); } public void create(Contact contact){ // Gets the data repository in write mode SQLiteDatabase db = getWritableDatabase(); // Create a new map of values, where column names are the keys ContentValues values = new ContentValues(); values.put(ContactField.COLUMN_NAME, contact.getName()); values.put(ContactField.COLUMN_PHONE, contact.getPhone()); // Insert the new row, returning the primary key value of the new row long newRowId; newRowId = db.insert( ContactField.TABLE_NAME, null, values); } public Cursor retrieve(){ SQLiteDatabase db = getReadableDatabase(); // Define a projection that specifies which columns from the database // you will actually use after this query. String[] projection = { ContactField.COLUMN_ID, ContactField.COLUMN_NAME, ContactField.COLUMN_PHONE }; // How you want the results sorted in the resulting Cursor String sortOrder = ContactField.COLUMN_NAME + " ASC"; Cursor c = db.query( ContactField.TABLE_NAME, // The table to query projection, // The columns to return null, // The columns for the WHERE clause null, // The values for the WHERE clause null, // don't group the rows null, // don't filter by row groups sortOrder // The sort order ); return c; } public void update(Contact contact){ SQLiteDatabase db = getReadableDatabase(); // New value for one column ContentValues values = new ContentValues(); values.put(ContactField.COLUMN_NAME, contact.getName()); values.put(ContactField.COLUMN_PHONE, contact.getPhone()); // Which row to update, based on the ID String selection = ContactField.COLUMN_ID + " LIKE ?"; String[] selectionArgs = { String.valueOf(contact.getId()) }; int count = db.update( ContactField.TABLE_NAME, values, selection, selectionArgs); } public void delete(int id){ SQLiteDatabase db = getReadableDatabase(); // Define 'where' part of query. String selection = ContactField.COLUMN_ID + " LIKE ?"; // Specify arguments in placeholder order. String[] selectionArgs = { String.valueOf(id) }; // Issue SQL statement. db.delete(ContactField.TABLE_NAME, selection, selectionArgs); } }
Nah, kini kita masuk ke activity. Buat kelas dengan nama MainActivity.java
package com.wimso.android_sqlite; import android.database.Cursor; import android.support.design.widget.FloatingActionButton; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import com.wimso.android_sqlite.adapter.ContactListAdapter; import com.wimso.android_sqlite.db.SQLiteDB; import com.wimso.android_sqlite.listener.RecyclerItemClickListener; import com.wimso.android_sqlite.model.Contact; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity implements RecyclerItemClickListener { private RecyclerView lvContact; private FloatingActionButton btnAdd; private ContactListAdapter contactListAdapter; private LinearLayoutManager linearLayoutManager; private SQLiteDB sqLiteDB; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lvContact = (RecyclerView) findViewById(R.id.lvContact); btnAdd = (FloatingActionButton) findViewById(R.id.add); linearLayoutManager = new LinearLayoutManager(this); contactListAdapter = new ContactListAdapter(this); contactListAdapter.setOnItemClickListener(this); lvContact.setLayoutManager(linearLayoutManager); lvContact.setAdapter(contactListAdapter); btnAdd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ActActivity.start(MainActivity.this); } }); } @Override protected void onStart() { super.onStart(); loadData(); } void loadData(){ sqLiteDB = new SQLiteDB(this); List<Contact> contactList = new ArrayList<>(); Cursor cursor = sqLiteDB.retrieve(); Contact contact; if (cursor.moveToFirst()) { do { contact = new Contact(); contact.setId(cursor.getInt(0)); contact.setName(cursor.getString(1)); contact.setPhone(cursor.getString(2)); contactList.add(contact); }while (cursor.moveToNext()); } contactListAdapter.clear(); contactListAdapter.addAll(contactList); } @Override public void onItemClick(int position, View view) { ActActivity.start(this, contactListAdapter.getItem(position)); } }
Lanjut ke ActActivity.java
package com.wimso.android_sqlite; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import com.wimso.android_sqlite.db.SQLiteDB; import com.wimso.android_sqlite.model.Contact; /** * Created by docotel on 5/2/16. */ public class ActActivity extends AppCompatActivity implements View.OnClickListener{ private EditText personName; private EditText phone; private Button btnAdd, btnEdit, btnDelete; private SQLiteDB sqLiteDB; private Contact contact; public static void start(Context context){ Intent intent = new Intent(context, ActActivity.class); context.startActivity(intent); } public static void start(Context context, Contact contact){ Intent intent = new Intent(context, ActActivity.class); intent.putExtra(ActActivity.class.getSimpleName(), contact); context.startActivity(intent); } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_act); personName = (EditText) findViewById(R.id.personText); phone = (EditText) findViewById(R.id.phoneText); btnAdd = (Button) findViewById(R.id.btnAdd); btnEdit = (Button) findViewById(R.id.btnEdit); btnDelete = (Button) findViewById(R.id.btnDelete); btnAdd.setOnClickListener(this); btnEdit.setOnClickListener(this); btnDelete.setOnClickListener(this); contact = getIntent().getParcelableExtra(ActActivity.class.getSimpleName()); if(contact != null){ btnAdd.setVisibility(View.GONE); personName.setText(contact.getName()); phone.setText(contact.getPhone()); }else{ btnEdit.setVisibility(View.GONE); btnDelete.setVisibility(View.GONE); } sqLiteDB = new SQLiteDB(this); } @Override public void onClick(View v) { if(v == btnAdd){ contact = new Contact(); contact.setName(personName.getText().toString()); contact.setPhone(phone.getText().toString()); sqLiteDB.create(contact); Toast.makeText(this, "Inserted!", Toast.LENGTH_SHORT).show(); finish(); }else if(v == btnEdit){ contact.setName(personName.getText().toString()); contact.setPhone(phone.getText().toString()); sqLiteDB.update(contact); Toast.makeText(this, "Edited!", Toast.LENGTH_SHORT).show(); finish(); }else if(v == btnDelete){ sqLiteDB.delete(contact.getId()); Toast.makeText(this, "Deleted!", Toast.LENGTH_SHORT).show(); finish(); } } }
Build dan jalankan, maka akhirnya sebagai berikut :
*Biarkan jomblo berimajinasi :v
*Just kidding (abaikan)
Source code lengkap sanggup dilihat di https://github.com/andronut/Android-SQLite
Jika ada bab yang error, liat aja di source codenya. Karena TS hanya memberikan yang penting-penting saja :D
Sekian dan biar bermanfaat
Happy Coding :)
Comments
Post a Comment