Membuat Aplikasi Simple Note di Android

By | April 4, 2022
Print Friendly, PDF & Email
2,176 Views

Membuat Aplikasi Simple Note di Android – Pada Aplikasi ini kita akan menggunakan CRUD- adalah singkatan dari Create, Read, update, dan delete yang merupakan istilah dalam operasi query database. Bila kalian menggunakan android, maka class query database sudah ada di built in yaitu menggunakan Sqlite Database dan lebih bagus nya lagi sudah ada mekanisme dasarnya. Oleh hal tersebut akan sangat mudah sekali bila kita melakukan inheritance atas class tersebut. Gambaran awal mengenai Aplikasi CRUD di Android yang kita buat diberikan nama dengan Simple Note.

Desain UI Simple Note

Sesuai dengan namanya yaitu Simple Note yang fokus terhadap fungsionalitas, maka desainya cukup sederhana yaitu sebagai berikut yaitu ada 2 Activity yaitu

  1. TampilData
  2. EditTambahNote

dengan tampilan UI yang sederhana

Struktur Kode Java

Sebelum membuat kode yang panjang, saya akan kasih gambaran umum kode *.java nya terlebih dahulu, Aplikasi CRUD di Android terdiri dari 5 class yaitu

Penjelasan Mengenai Class Setting.java

Digunakan untuk memberikan informasi umum seperti versi database yang digunakan, serta pengaturan mode yaitu EDIT atau TAMBAH DATA BARU karena ketika tampil activity berikut

bisa digunakan untuk

  1. edit note yang sudah ada atau untuk
  2. menambah data baru sehingga hemat penggunaan activitynya

Caranya yaitu dengan membuat memasukan Bundle kedalam Intent misalkan untuk kasih FLAG bahwa Activity tersebut digunakan untuk TAMBAH DATA BARU maka cukup kasih Bundle

Intent intent = new Intent(TampilData.this,EditTambahNote.class);
Bundle bundle = new Bundle();
bundle.putInt(Setting.STATUS,Setting.TAMBAH_DATA_BARU);
intent.putExtras(bundle);
startActivity(intent);
finish();

Bila Activity tersebut untuk EDIT maka gunakan kode berikut (beserta kasih ID recordnya juga)

Intent intent = new Intent(TampilData.this,EditTambahNote.class);
Bundle bundle = new Bundle();
bundle.putInt(Setting.STATUS,Setting.EDIT_DATA_LAMA);
bundle.putInt(Note.clm_id,Integer.valueOf(getId.getText().toString())); //ID record
intent.putExtras(bundle);
startActivity(intent);

 

Berikut kode yang Setting.java

Terdiri dari static final agar tidak perlu buat instance dan tidak diubah nilainya!

public class Setting {
    public static final String STATUS = "status"; //untuk KEY di BUNDLE
    public static final int TAMBAH_DATA_BARU = 1; //untuk VALUE di BUNDLE
    public static final int EDIT_DATA_LAMA = 2; //untuk VALUE di BUNDLE
    public static final int VERSI_DB = 2; //versi database yang digunakan
}

Desain tabel

Desain tabel terdiri dari 4 kolom yaitu

Perhatikan kolom dengan nama _id itu adalah wajib! tidak boleh menggunakan id atau ID  karena itu nama default pada saat kita memanggil class Cursor Adapter yaitu class bawaan SDK android yang digunakan untuk mempermudah kita menampilkan records kedalam List View.

See also  Pengelolaan Versi DB Database Sqlite di Android

Urusan Database kita serahkan pada 2 class yaitu Note.java dan NoteCursorAdapter.java keduanya digunakan untuk

  1. Note.java adalah inheritance  SQLiteOpenHelper yang digunakan untuk mempermudah urusan CRUD mulai create table, insert, update, dan delete
  2. NoteCursorAdapter.java digunakan untuk menampilkan hasil query SELECT * FROM table yang ditampung hasilnya menggunakan component List View istilah lainnya mempopulasikan data.

Berikut kode yang Node.java

Kode Node.java agak panjang yang didalammya sudah ada method2 yang sudah cukup memadai kita membuat aplikasi Simple Note

public class Note extends SQLiteOpenHelper {
    static final String  database_name = "dbnote2";
    static final String table_name = "tbnote";
    static final String clm_id = "_id"; //wajib _id
    static final String clm_tanggal = "tanggal";
    public final static String clm_title = "title";
    public final static String clm_content = "content";

    SQLiteDatabase db;
    public Note(Context context) {
        super(context, database_name, null, Setting.VERSI_DB);
        db = getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        //https://stackoverflow.com/questions/47848445/sqlite-database-error-during-execsql
        db = sqLiteDatabase;
        String query = "CREATE TABLE " + table_name + "(" + clm_id + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + clm_tanggal + " TEXT, " + clm_title + " TEXT, " + clm_content + " TEXT)";
        System.out.println(query);
        db.execSQL(query);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        db.execSQL("DROP TABLE IF EXISTS " + table_name);
    }
    //Get All SQLite Data
    public Cursor allData(){
        Cursor cur = db.rawQuery("SELECT * FROM " + table_name , null);
        return cur;
    }

    //Get 1 Data By ID
    public Cursor oneData(Long id){
        Cursor cur = db.rawQuery("SELECT * FROM " + table_name + " WHERE " + clm_id + "=" + id, null);
        return cur;
    }

    //Insert Data to Database
    public void insertData(ContentValues values){
        db.insert(table_name, null, values);
    }

    //Update Data
    public void updateData(ContentValues values, long id){
        db.update(table_name, values, clm_id + "=" + id, null);
    }

    //Delete Data
    public void deleteData(long id){
        db.delete(table_name, clm_id + "=" + id, null);
    }
}

Sebelum lanjut ke NoteCursorAdapter.java yang bertugas untuk menampilkan record/mempopulasikan data, kita buat terlebih dahulu layout xml untuk menampung record tersebut, agar mudah kita berikan nama layout/record_note.xml yang isinya sebagai berikut

Kode layout/record_note.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/listid"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="id"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    <TextView
        android:id="@+id/listtanggal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:text="tanggal"/>
    <TextView
        android:id="@+id/listtitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:text="title"
        android:textAppearance="?android:attr/textAppearanceMedium" />
    <TextView
        android:id="@+id/listcontent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:text="content"/>
</LinearLayout>

Tampilan render diatas seperti berikut dibuat marginLeft berbeda-beda untuk membedakan antara title dan content

Setelah kita buat layout/record_note.xml diatas, kita lanjutkan NoteCursorAdapter.java

Kode NoteCursorAdapter.java

Bertugas menampilkan record

public class NoteCursorAdapter extends CursorAdapter {
    public NoteCursorAdapter(Context context, Cursor cursor) {
        super(context, cursor, Setting.VERSI_DB);
    }
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View inflater = LayoutInflater.from(context).inflate(R.layout.record_note,parent, false);
        return inflater;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        TextView id = (TextView) view.findViewById(R.id.listid);
        TextView tanggal = (TextView) view.findViewById(R.id.listtanggal);
        TextView title = (TextView) view.findViewById(R.id.listtitle);
        TextView content = (TextView) view.findViewById(R.id.listcontent);
        //get cursor
        String string_id = cursor.getString(cursor.getColumnIndexOrThrow(Note.clm_id));
        String string_tanggal = cursor.getString(cursor.getColumnIndexOrThrow(Note.clm_tanggal));
        String string_title = cursor.getString(cursor.getColumnIndexOrThrow(Note.clm_title));
        String string_content = cursor.getString(cursor.getColumnIndexOrThrow(Note.clm_content));

        id.setText(string_id);
        tanggal.setText(string_tanggal);
        title.setText(string_title);
        content.setText(string_content);

    }
}

Perhatikan method newView yang mengembalikan return berupa View

Setelah kita membuat 3 class diatas dan 1 layout untuk menampung record, sekarang kita buat 2 class yang bertugas untuk menampilkan dan edit/tambah record dalam bentuk activity

See also  Database Inspector Android

Membuat Tampil Data

TampilData.java mempunyai kode yang cukup panjang, didalamnya method loadagain() yang merupakan load record dengan cara memanggil NoteCursorAdapter sebagai argument input pada List View. Didalamnya Activity Tampil Data juga diberikan action listener ketika user klik List View tersebut akan diberikan pilihan untuk Edit / Hapus / Batal

kode layout/activity_tampil_data.xml

Berikut tampilan dari layout/activity_tampil_data.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
    tools:context=".TampilData"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp">
        <Button
            android:id="@+id/back_tambah"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="tulis note"
            android:layout_margin="5dp"/>
        <Button
            android:id="@+id/keluar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="keluar"
            android:layout_margin="5dp"/>
    </LinearLayout>

    <ListView
        android:id="@+id/list_data"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:drawSelectorOnTop="true"
        android:layout_margin="7dp"/>

</LinearLayout>

Component List View akan menampung record

Kode Activity TampilData.java

Berikut kode nya cukup ringkas koq

public class TampilData extends AppCompatActivity implements AdapterView.OnItemClickListener {

    private Note dbhelper;
    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tampil_data);
        dbhelper = new Note(this);
        listView = (ListView)findViewById(R.id.list_data);
        listView.setOnItemClickListener(this); //biar pas di sentuh ada action listener
        loadagain();
        Button tambah_note_baru = (Button) findViewById(R.id.back_tambah);
        tambah_note_baru.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (v.getId()){
                    case R.id.back_tambah:
                        Intent intent = new Intent(TampilData.this,EditTambahNote.class);
                        Bundle bundle = new Bundle();
                        bundle.putInt(Setting.STATUS,Setting.TAMBAH_DATA_BARU); //kasih flag 
                        intent.putExtras(bundle);                       //bahwa Inten yang dibuat untuk
                        startActivity(intent);                          //TAMBAH DATA BARU
                        finish();
                        break;
                }
            }
        });

        Button keluar = (Button) findViewById(R.id.keluar);
        keluar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (v.getId()){
                    case R.id.keluar:
                        finishAffinity();
                        break;
                }
            }
        });

    }

    private void loadagain(){
        Cursor cursor = dbhelper.allData();
        NoteCursorAdapter customCursorAdapter = new NoteCursorAdapter(this, cursor);
        listView.setAdapter(customCursorAdapter);
    }
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int i, long x) {
        TextView getId = (TextView)view.findViewById(R.id.listid);
        final long id = Long.parseLong(getId.getText().toString());

        final AlertDialog.Builder builder = new AlertDialog.Builder(TampilData.this);
        builder.setTitle("Menu : ");

        String [] opsi = new String[]{"Edit","Hapus","Batal"};
        builder.setItems(opsi,new DialogInterface.OnClickListener(){
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch(which){
                    case 0:
                        Intent intent = new Intent(TampilData.this,EditTambahNote.class);
                        Bundle bundle = new Bundle();
                        bundle.putInt(Setting.STATUS,Setting.EDIT_DATA_LAMA); //kasih flag
                        bundle.putInt(Note.clm_id,Integer.valueOf(getId.getText().toString())); //ID record
                        intent.putExtras(bundle);
                        startActivity(intent);
                        break;
                    case 1:
                        dbhelper.deleteData(id);
                        loadagain();
                        break;
                    case 2:
                        //do nothing
                        break;
                }
            }
        });
        AlertDialog dialog = builder.create();
        dialog.show();

    }
}

Berikut tampilan aplikasi ketika ada record yang sudah tersimpan

Membuat Edit Tambah Note

Sekarang kita buat activity EDIT TAMBAH, seperti yang sudah dijelaskan sebelumnya bahwa activity ini bisa digunakan untuk EDIT dan TAMBAH. Trik yang kita lakukan yaitu menyembunyikan component TextView untuk menampung _id record ketika dalam mode EDIT   android:visibility="gone" , ya mirip-mirip HIDDEN pada TAG HTML

Oiya untuk Tanggal akan dibuat otomatis diambil dari ponsel, agar ada gambaran, kita buat saja

Kode layout/activity_edit_tambah_note.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".EditTambahNote">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/tambah_note"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="3dp"
            android:text="tambah"/>
        <Button
            android:id="@+id/simpan_note"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_margin="3dp"
            android:text="simpan"/>
        <Button
            android:id="@+id/lihat_note"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_margin="3dp"
            android:text="lihat"/>
    </LinearLayout>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <EditText
                android:id="@+id/id_note"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="gone"/>
            <EditText
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:hint="title"/>
            <EditText
                android:id="@+id/content"
                android:layout_width="match_parent"
                android:layout_height="142dp"
                android:hint="content" />
        </LinearLayout>
    </ScrollView>
</LinearLayout>

Berikut hasil render diatas

See also  Handling Files in Code After Android 10

Yuk buat Activity nya

Kode Activity EditTambahNote.java

public class EditTambahNote extends AppCompatActivity {
    int STATUS;
    int ID_NOTE;
    Note dbhelper;
    EditText id_note,title_note,content_note;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_tambah_note);
        
        dbhelper = new Note(this);

        Button tambah_note = (Button) findViewById(R.id.tambah_note);
        Button simpan_note = (Button)findViewById(R.id.simpan_note);
        Button lihat_note = (Button) findViewById(R.id.lihat_note);
        
        id_note = (EditText) findViewById(R.id.id_note);
        title_note = (EditText) findViewById(R.id.title);
        content_note = (EditText) findViewById(R.id.content);

        Bundle bundel  = getIntent().getExtras();
        STATUS = bundel.getInt(Setting.STATUS);
        if(STATUS==Setting.EDIT_DATA_LAMA){ //cek flag nya dulu
            ID_NOTE = (int) bundel.getInt(Note.clm_id);
            Cursor cursor = dbhelper.oneData((long)ID_NOTE);
            cursor.moveToFirst();//untuk memastikan pertama!
            System.out.println("ID NOTE: "+ID_NOTE);
            String string_id = cursor.getString(cursor.getColumnIndexOrThrow(Note.clm_id));
            String string_tanggal = cursor.getString(cursor.getColumnIndexOrThrow(Note.clm_tanggal));
            String string_title = cursor.getString(cursor.getColumnIndexOrThrow(Note.clm_title));
            String string_content = cursor.getString(cursor.getColumnIndexOrThrow(Note.clm_content));

            id_note.setText(String.valueOf(ID_NOTE));
            title_note.setText(string_title);
            content_note.setText(string_content);
            cursor.close();
        }else{
            // tak lakukan apapun
        }

        simpan_note.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                switch (v.getId()){
                    case R.id.simpan_note:
                        if(STATUS==Setting.TAMBAH_DATA_BARU){
                            if(title_note.getText().toString().equals("")){
                                Toast.makeText(EditTambahNote.this, "Tak Jadi Simpan", Toast.LENGTH_SHORT).show();
                                return;
                            }
                            Date currentTime = Calendar.getInstance().getTime();
                            ContentValues values  = new ContentValues();
                            values.put(dbhelper.clm_title,title_note.getText().toString().trim());
                            values.put(dbhelper.clm_content,content_note.getText().toString().trim());
                            values.put(dbhelper.clm_tanggal,currentTime.toString());
                            dbhelper.insertData(values);
                            Toast.makeText(EditTambahNote.this, "1 Note telah tersimpan", Toast.LENGTH_SHORT).show();
                            Intent home = new Intent(EditTambahNote.this,TampilData.class);
                            startActivity(home);
                        }
                        if(STATUS==Setting.EDIT_DATA_LAMA){
                            Date currentTime = Calendar.getInstance().getTime();
                            ContentValues values  = new ContentValues();
                            values.put(dbhelper.clm_id,String.valueOf(ID_NOTE));
                            values.put(dbhelper.clm_title,title_note.getText().toString().trim());
                            values.put(dbhelper.clm_content,content_note.getText().toString().trim());
                            values.put(dbhelper.clm_tanggal,currentTime.toString());
                            dbhelper.updateData(values,ID_NOTE);
                            Toast.makeText(EditTambahNote.this, "Simpan data lama!!", Toast.LENGTH_SHORT).show();
                        }
                        break;
                }
            }
        });

        lihat_note.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                switch (v.getId()){
                    case R.id.lihat_note:
                        Intent home = new Intent(EditTambahNote.this,TampilData.class);
                        startActivity(home);
                }
            }
        });


        tambah_note.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (v.getId()){
                    case R.id.tambah_note:
                        //hapus yang ada
                        id_note.setText("");
                        title_note.setText("");
                        content_note.setText("");
                        STATUS = Setting.TAMBAH_DATA_BARU;
                        break;
                }
            }
        });

    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Membaca file menu dan menambahkan isinya ke action bar jika ada.
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle presses on the action bar items
        switch (item.getItemId()) {
            case R.id.miCompose:
                //action
                return true;
            case R.id.miProfile:
                //action
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

Main Activity

Pada main Activity kita kasih kode berikut untuk memanggil pertama kali berupa tampil record

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //getSupportActionBar().hide();
        Intent home = new Intent(MainActivity.this,TampilData.class);
        startActivity(home);
    }
}

Kesimpulan

Bagaimana menurut kalian? tentu Aplikasi CRUD di Android diatas kurang fiturnya tapi pada dasarnya tutorial diatas sebagai basic saja agar paham dulu mengenai cara membuat Aplikasi CRUD di Android. Aplikasi diatas telah saya gunakan untuk mempermudah buat catatan di ponsel android dan sangat membantu sih. Aplikasi diatas sengaja menyimpan tanggal secara otomatis seharusnya sih ORDER BY tanggal ketika menampilkan record agar lebih urut update tanggal terbaru. Caranya adalah date time diubah kedalam integer (mengingat sqlite tidak punya format penyimpanan date) sehingga ketika formatnya integer akan mudah perintah sql menjadi ORDER BY tanggal.

Bila kalian ingin mengedit database secara langsung, bisa menggunakan database inspector

Download Source Code

Untuk source code saya letakan di https://github.com/mulkan/SimpleNote tapi sudah ada beberapa perubahan

Leave a Reply