Blog Tutorial Android Bagi Pemula

Sunday, April 18, 2021

Menambah dan Menghapus (Banyak) Item Pada RecyclerView Secara Dinamis

Karena postingan ini dikerjakan pada malam hari, maka selamat malam kepada sobat Androiders sekalian! Dalam postingan ini kita akan membahas mengenai menambah dan menghapus item pada RecyclerView secara dinamis, karena dinamis memiliki pengertian yang cukup luas, dinamis yang dimaksud pada postingan ini adalah semacam berulang-ulang atau berubah-ubah. Menghapus disini akan di implementasikan  menghapus satu-persatu dan menghapus banyak sekaligus.

Dalam tutorial ini konsepnya adalah sebuah daftar barang, terdiri dari nama barang, jumlah dan deskripsi. Kita juga akan menggunakan SQLite Database untuk penyimpanan data. Kurang lebih seperti aplikasi catatan, shopping list dan sebagainnya yang sejenis.


Delete and adding item to RecyclerView using SQL Database
Gambar 1 : Folder-folder dan file-file project.


Baik, mari kita mulai dengan mempersiapkan sebuah project baru. Dalam tutorial ini package projectnya adalah com.gwnbs.rvadddelete. Kita mulai dari activity_main.xml, isinya sebagai berikut :

activity_main.xml :

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
android:id="@+id/textJudul"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#4E4E4E"
android:gravity="center"
android:includeFontPadding="false"
android:padding="10dp"
android:text="Daftar Sesuatu"
android:textColor="@color/white"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clipToPadding="false"
android:orientation="vertical"
android:padding="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/textJudul" />

<TextView
android:id="@+id/textAddItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_marginBottom="50dp"
android:background="@drawable/background_view"
android:fontFamily="serif"
android:gravity="center_vertical"
android:paddingStart="10dp"
android:paddingTop="5dp"
android:paddingEnd="10dp"
android:paddingBottom="5dp"
android:text="Add"
android:textColor="@color/white"
android:textSize="20sp"
app:drawableStartCompat="@drawable/ic_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />

<TextView
android:id="@+id/textDeleteItems"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginBottom="50dp"
android:background="@drawable/background_view"
android:fontFamily="serif"
android:gravity="center_vertical"
android:visibility="gone"
android:paddingStart="10dp"
android:paddingTop="5dp"
android:paddingEnd="10dp"
android:paddingBottom="5dp"
android:textColor="@color/white"
android:textSize="20sp"
app:drawableStartCompat="@drawable/ic_delete"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />

<TextView
android:id="@+id/textKosong"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:fontFamily="serif"
android:gravity="center"
android:text="Daftar kosong. Klik tombol Add untuk menambah daftar."
android:textColor="@color/black"
android:textSize="20sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>


Sebelumnya, berikut beberapa resource drawable yang kita gunakan dalam tutorial ini, yaitu beberapa background drawable dan icon. Silahkan di copy ke folder drawable jika mengikuti tutorial ini.

background_input.xml :
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/white"/>
<corners android:radius="5dp"/>
</shape>


background_selected.xml :
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#E53935"/>
<corners android:radius="10dp"/>
</shape>


background_view.xml :
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/teal_200">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/teal_700"/>
<stroke android:width="1dp"/>
<corners android:radius="10dp"/>
</shape>
</item>
</ripple>


ic_add.xml :
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="30dp"
android:height="30dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
</vector>


ic_delete.xml :
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#EC3434"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M15,16h4v2h-4zM15,8h7v2h-7zM15,12h6v2h-6zM3,18c0,1.1 0.9,2 2,2h6c1.1,0 2,-0.9 2,-2L13,8L3,8v10zM14,5h-3l-1,-1L6,4L5,5L2,5v2h12z" />
</vector>



Berikutnya kita membuat java class model getter dan setter untuk nama barang, jumlah barang dan deskripsi barang. Didalam class ini kita juga memvariabelkan sebuah boolean dengan akses public yang nantinya akan kita gunakan untuk menandai item pada recyclerview untuk dihapus. Lalu integer id yang akan digunakan nantinya untuk menghapus item dari database. Id ini nilainya ditentukan otomatis oleh database saat kita memasukkan data ke database, jadi kita tidak menentukan nilai untuk id.

Barang.java :
package com.gwnbs.rvadddelete;

public class Barang {

private int id;
private String namaBarang, jumlahBarang, deskripsiBarang;
public boolean isBarangSelected = false;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getNamaBarang() {
return namaBarang;
}

public void setNamaBarang(String namaBarang) {
this.namaBarang = namaBarang;
}

public String getJumlahBarang() {
return jumlahBarang;
}

public void setJumlahBarang(String jumlahBarang) {
this.jumlahBarang = jumlahBarang;
}

public String getDeskripsiBarang() {
return deskripsiBarang;
}

public void setDeskripsiBarang(String deskripsiBarang) {
this.deskripsiBarang = deskripsiBarang;
}
}


Kemudian kita membuat sebuah java interface. Interface ini gunanya supaya kita dapat mengimplementasikan koding pada activity yang mana harusnya ditulis pada class adapter, terutama untuk event listener.

BarangListener.java :
package com.gwnbs.rvadddelete;

import java.util.List;

public interface BarangListener {
void checkBarang(int totalItem, int id);
void selectedBarangs(List<Barang> barangs);
void onSelected(Boolean isSelected);
void onBarangClicked(String message);
}

Pada kode BarangListener diatas, metode checkBarang kita gunakan sebagai pendengar untuk mengirim jumlah item dan id dari item pada daftar dari adapter ke activity, selectedBarangs sebagai pendengar item yang ditandai, onSelected sebagai pendengar apakah sedang ada item yang ditandai atau tidak, lalu onBarangClicked sebagai pendengar saat item di klik.

Selanjutnya  sebuah layout resource file sebagai container/wadah untuk item-item. Selain 3 komponen TextView  untuk nama, jumlah dan deskripsi barang, di dalam layout ini kita juga menyisipkan sebuah ImagView untuk menghapus item secara tunggal.

item_list_container.xml :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:background="@drawable/background_view"
android:gravity="top"
android:orientation="horizontal"
android:padding="10dp">

<LinearLayout
android:id="@+id/layoutDetailBarang"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_weight="1"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imageDelete"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<TextView
android:id="@+id/textNamaBarang"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="serif"
android:includeFontPadding="false"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />

<TextView
android:id="@+id/textDeskripsiBarang"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:alpha="0.7"
android:fontFamily="serif"
android:includeFontPadding="false"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="16sp" />

</LinearLayout>

<TextView
android:id="@+id/textJumlahBarang"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="serif"
android:includeFontPadding="false"
android:textColor="@color/white"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/layoutDetailBarang" />

<ImageView
android:id="@+id/imageDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:padding="3dp"
android:background="@drawable/background_input"
android:contentDescription="@null"
android:src="@drawable/ic_delete"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/textJumlahBarang" />

</androidx.constraintlayout.widget.ConstraintLayout>


Berikutnya kelas Adapter. Selain kelas list Barang.java, interface BarangListener.java juga kita masukkan kedalam konstruktor, supaya dapat diakses melalui activity atau MainActivity.java pada tutorial ini. Sehingga pada setiap metode klik yaitu klik listener untuk ImageView untuk menghapus item secara tunggal, lalu klik listener pada item (klik biasa dan long klik) kita cukup mengisikan variabel BarangListener diikuti metode yang diperlukan seperti yang sudah dibahas sebelumnya diatas.

Metode long klik pada item kita pakai untuk menandai item-item, sedangkan metode klik biasa/pendek pada item hanya untuk menampilkan pesan toast nama barang, namun disini kita membuat kondisi if else yaitu klik pendek akan mengikuti fungsi long klik jika terdapat item yang terpilih. 

ListBarangAdapter.java :
package com.gwnbs.rvadddelete;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public class ListBarangAdapter extends RecyclerView.Adapter<ListBarangAdapter.ListBarangViewHolder> {

private final List<Barang> barangs;
private final BarangListener listener;

public ListBarangAdapter(List<Barang> barangs, BarangListener listener) {
this.barangs = barangs;
this.listener = listener;
}

@NonNull
@Override
public ListBarangViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ListBarangViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list_container, parent, false));
}

@Override
public void onBindViewHolder(@NonNull ListBarangViewHolder holder, int position) {
holder.bindBarang(barangs.get(position));
}

@Override
public int getItemCount() {
return barangs.size();
}

class ListBarangViewHolder extends RecyclerView.ViewHolder {
private final TextView textNamaBarang, textJumlahBarang, textDeskripsiBarang;
private final ImageView imageDelete;

ListBarangViewHolder(@NonNull View itemView) {
super(itemView);
textNamaBarang = itemView.findViewById(R.id.textNamaBarang);
textJumlahBarang = itemView.findViewById(R.id.textJumlahBarang);
textDeskripsiBarang = itemView.findViewById(R.id.textDeskripsiBarang);
imageDelete = itemView.findViewById(R.id.imageDelete);
}

void bindBarang(final Barang barang) {
textNamaBarang.setText(barang.getNamaBarang());
textJumlahBarang.setText(barang.getJumlahBarang());
textDeskripsiBarang.setText(barang.getDeskripsiBarang());
imageDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
barangs.remove(barang);
itemView.animate().translationX(1200).setDuration(500).withEndAction(new Runnable() {
@Override
public void run() {
notifyItemRemoved(getAdapterPosition());
notifyItemRangeChanged(getAdapterPosition(), getItemCount());
listener.checkBarang(barangs.size(), barang.getId());
}
}).start();
}
});

itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (selectedBarangs().size() > 0) {
isSelected(barang, itemView);
} else {
listener.onBarangClicked(barang.getNamaBarang() + " di klik");
}
}
});

itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
isSelected(barang, itemView);
return true;
}
});

if (barang.isBarangSelected) {
itemView.setBackgroundResource(R.drawable.background_selected);
listener.onSelected(true);
} else {
itemView.setBackgroundResource(R.drawable.background_view);
if (selectedBarangs().size() == 0) {
listener.onSelected(false);
}
}
}
}

private void isSelected(Barang barang, View itemView) {
if (!barang.isBarangSelected) {
barang.isBarangSelected = true;
itemView.setBackgroundResource(R.drawable.background_selected);
listener.onSelected(true);
} else {
barang.isBarangSelected = false;
itemView.setBackgroundResource(R.drawable.background_view);
if (selectedBarangs().size() == 0) {
listener.onSelected(false);
}
}
listener.selectedBarangs(selectedBarangs());
}

private List<Barang> selectedBarangs() {
List<Barang> selectedBarangs = new ArrayList<>();
for (Barang barang : barangs) {
if (barang.isBarangSelected) {
selectedBarangs.add(barang);
}
}
return selectedBarangs;
}
}



Selanjutnya kita membuat kelas penghubung atau pengatur SQLite Database. Seperti biasaya dalam membuat kelas semacam ini, kita menentukan nama dari database, versinya, lalu membuat tabel dengan kolom-kolom nya.

DatabaseManager.java :
package com.gwnbs.rvadddelete;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;

import androidx.annotation.Nullable;

import java.util.Collections;

public class DatabaseManager {

private final String DB_NAME = "barang.db";
private final int DB_VERSION = 1;
private SQLiteDatabase sqLiteDatabase;
private DatabaseHelper databaseHelper;
private final Context context;

public static final String TABLE_BARANG = "Barang";
public static final String ID_BARANG = "ID";
public static final String NAMA_BARANG = "Nama_barang";
public static final String JUMLAH_BARANG = "Jumlah_barang";
public static final String DESKRIPSI_BARANG = "Deskripsi_barang";

private static final String CREATE_TABLE_BARANG = " create table " + TABLE_BARANG + "(" + ID_BARANG
+ " integer primary key, " + NAMA_BARANG + " TEXT, " + JUMLAH_BARANG + " TEXT, "
+ DESKRIPSI_BARANG + " TEXT);";

public DatabaseManager(Context context) {
this.context = context;
}

public void open() {
databaseHelper = new DatabaseHelper(context);
sqLiteDatabase = databaseHelper.getWritableDatabase();
}

public void close() {
databaseHelper.close();
}

public void tambahBarang(Barang barang) {
ContentValues cv = new ContentValues();
cv.put(NAMA_BARANG, barang.getNamaBarang());
cv.put(JUMLAH_BARANG, barang.getJumlahBarang());
cv.put(DESKRIPSI_BARANG, barang.getDeskripsiBarang());
sqLiteDatabase.insert(TABLE_BARANG, null, cv);
}

public void hapusBarang(int id) {
sqLiteDatabase.delete(TABLE_BARANG, ID_BARANG + "=" + id, null);
}

public Cursor getDaftarFromDatabase() {
String [] columns = new String[]{ID_BARANG, NAMA_BARANG, JUMLAH_BARANG, DESKRIPSI_BARANG};
Cursor c = sqLiteDatabase.query(TABLE_BARANG, columns, null, null,
null, null, null);
if (c !=null) {
c.moveToFirst();
}
return c;
}

class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(@Nullable Context context) {
super(context, DB_NAME, null, DB_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_BARANG);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_BARANG);
}
}

}

Pada kelas DatabaseManager diatas, kita menentukan 4 kolom untuk id barang, nama barang, jumlah barang dan deskripsinya. Saat memasukkan data ke database yaitu metode tambahBarang diatas, kita tidak perlu menentukan id barang karena akan secara otomatis ditentukan oleh database itu sendiri menggunakan digit berurutan mulai dr angka 1.

Untuk menghapus item secara tunggal ataupun banyak sekaligus, kita menggunakan id tersebut. Tambahannya untuk menghapus banyak item, kita perlu menggunakan java loop untuk melipat gandakan metode penghapusan sesuai dengan jumlah item yang dipilih.

Baik, berikutnya kita buat lagi sebuah layout resource file yang akan di inflate menggunakan AlertDialog saat ingin menambahkan item RecyclerView.

dialog_add.xml :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:background="@drawable/background_view"
android:padding="15dp"
app:layout_constraintTop_toTopOf="parent">

<TextView
android:id="@+id/textJudulDialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="5dp"
android:fontFamily="serif"
android:gravity="center_vertical"
android:includeFontPadding="false"
android:text="Tambah Item"
android:textColor="@color/white"
android:textSize="25sp"
android:textStyle="bold"
app:drawableEndCompat="@drawable/ic_add"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<EditText
android:id="@+id/inputNamaBarang"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:alpha="0.8"
android:background="@drawable/background_input"
android:fontFamily="serif"
android:hint="Nama barang"
android:imeOptions="actionNext"
android:importantForAutofill="no"
android:inputType="textCapWords"
android:paddingStart="10dp"
android:paddingTop="5dp"
android:paddingEnd="10dp"
android:paddingBottom="5dp"
android:textColor="@color/black"
android:textSize="18sp"
app:layout_constraintEnd_toStartOf="@+id/inputJumlahBarang"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textJudulDialog" >

<requestFocus/>
</EditText>

<EditText
android:id="@+id/inputJumlahBarang"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:alpha="0.8"
android:background="@drawable/background_input"
android:fontFamily="serif"
android:hint="Jumlah"
android:imeOptions="actionNext"
android:importantForAutofill="no"
android:inputType="number"
android:paddingStart="10dp"
android:paddingTop="5dp"
android:paddingEnd="10dp"
android:paddingBottom="5dp"
android:textColor="@color/black"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/textJudulDialog" />

<EditText
android:id="@+id/inputDeskripsiBarang"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:alpha="0.8"
android:background="@drawable/background_input"
android:fontFamily="serif"
android:gravity="top"
android:hint="Deskripsi barang"
android:imeOptions="actionDone"
android:importantForAutofill="no"
android:inputType="textCapSentences|textMultiLine"
android:minHeight="100dp"
android:paddingStart="10dp"
android:paddingTop="5dp"
android:paddingEnd="10dp"
android:paddingBottom="5dp"
android:textColor="@color/black"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/inputNamaBarang" />

<com.google.android.material.button.MaterialButton
android:id="@+id/buttonAdd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:fontFamily="serif"
android:padding="10dp"
android:text="TAMBAH"
android:backgroundTint="@color/teal_200"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/inputDeskripsiBarang" />

</androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>


Terakhir kita implementasi di MainActivity.java. Supaya lebih simpel dalam penerapan koding yg dikirimkan BarangListener.java melalui adapter, kita implements kelas MainActivity ini dengan kelas BarangListener.java setelah extends AppCompatActivity, lalu kita overriding metode-metode yang ada pada BarangListener.java.

Lalu pada setiap metode override dari BarangListener.java, kita sisipkan koding-koding yang diperlukan. Selengkapnya seperti dibawah ini yang sudah disisipkan java comment pada setiap metode / event.

MainActivity.java :
package com.gwnbs.rvadddelete;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;

import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.database.Cursor;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.material.button.MaterialButton;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements BarangListener {

/*Variabel global supaya dapat diakses dari metode atau kelas mana saja yang masih berada
didalam kelas MainActivity dan tentunya yang bukan static */
private final List<Barang> barangs = new ArrayList<>();
private ListBarangAdapter listBarangAdapter;
private TextView textKosong, textAddItem, textDeleteItems;
private RecyclerView rvList;
private List<Barang> selectedBarangs;
private DatabaseManager manager;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//Inisialisai View menggunakan id
textAddItem = findViewById(R.id.textAddItem);
textKosong = findViewById(R.id.textKosong);
textDeleteItems = findViewById(R.id.textDeleteItems);
rvList = findViewById(R.id.rvList);

manager = new DatabaseManager(getApplicationContext());

listBarangAdapter = new ListBarangAdapter(barangs, this);
rvList.setAdapter(listBarangAdapter);

textAddItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textAddItem.animate().translationX(500).setDuration(300).withEndAction(new Runnable() {
@Override
public void run() {
textAddItem.setVisibility(View.GONE);
dialogTambahItem();
}
}).start();
}
});

//Klik listener menghapus banyak item
textDeleteItems.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
manager.open();
//loop menggandakan jumlah penghapusan data sebanyak jumlah item yangg terpilih.
for (int i = 0; i < selectedBarangs.size(); i++) {
manager.hapusBarang(selectedBarangs.get(i).getId());
}
manager.close();
onSelected(false);
getBarangFromDatabase();
}
});

getBarangFromDatabase();
}

//Memunculkan dialog untuk menambah item.
private void dialogTambahItem() {
AlertDialog.Builder b = new AlertDialog.Builder(this);
View view = LayoutInflater.from(this).inflate(R.layout.dialog_add, null);
final EditText inputNamaBarang = view.findViewById(R.id.inputNamaBarang);
final EditText inputJumlahBarang = view.findViewById(R.id.inputJumlahBarang);
final EditText inputDeskripsiBarang = view.findViewById(R.id.inputDeskripsiBarang);
MaterialButton buttonAdd = view.findViewById(R.id.buttonAdd);
b.setView(view);
final AlertDialog dialogTambah = b.create();
if (dialogTambah.getWindow() !=null) {
dialogTambah.getWindow().setBackgroundDrawable(new ColorDrawable(0));
}

//Klik listener untuk menambahkan data ke database
buttonAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String namaBarang = inputNamaBarang.getText().toString();
String jumlahBarang = inputJumlahBarang.getText().toString();
String deskripsiBarang = inputDeskripsiBarang.getText().toString();

/* Saat nama barang tidak ditentukan alias kosong maka tidak dimasukkan ke database
alias dikembalikan dengan pesan toast */
if (namaBarang.isEmpty()) {
toast("Tulis nama barang");
return;
}

/* Saat jumlah barang tidak ditentukan alias kosong maka tidak dimasukkan ke database
alias dikembalikan dengan pesan toast */
if (jumlahBarang.isEmpty()) {
toast("Jumlahnya berapa?");
return;
}

/* Saat deskripsi barang tidak ditentukan alias kosong maka tidak dimasukkan ke database
alias dikembalikan dengan pesan toast */
if (deskripsiBarang.isEmpty()) {
toast("Deskripsikan barangnya");
return;
}

/*Jika ketiga kondisi diatas dilewati alias tidak ada yang kosong maka data dimasukkan
ke database*/
dialogTambah.dismiss();
manager.open();
Barang barang = new Barang();
barang.setNamaBarang(namaBarang);
barang.setJumlahBarang(jumlahBarang);
barang.setDeskripsiBarang(deskripsiBarang);
manager.tambahBarang(barang);
manager.close();
toast(namaBarang + " dengan jumlah " + jumlahBarang + " ditambahkan ke daftar.");
getBarangFromDatabase();
}
});
dialogTambah.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
textAddItem.setVisibility(View.VISIBLE);
textAddItem.animate().translationX(0).setDuration(300).start();
}
});
dialogTambah.show();
}

//Mendapatkan data dari database
private void getBarangFromDatabase() {
barangs.clear();
rvList.setAdapter(null);
listBarangAdapter = new ListBarangAdapter(barangs, this);
rvList.setAdapter(listBarangAdapter);
manager.open();
Cursor c = manager.getDaftarFromDatabase();
if (c.getCount() > 0) {
int count = barangs.size();
while (!c.isAfterLast()) {
Barang barang = new Barang();
barang.setId(c.getInt(c.getColumnIndexOrThrow(DatabaseManager.ID_BARANG)));
barang.setNamaBarang(c.getString(c.getColumnIndexOrThrow(DatabaseManager.NAMA_BARANG)));
barang.setJumlahBarang(c.getString(c.getColumnIndexOrThrow(DatabaseManager.JUMLAH_BARANG)));
barang.setDeskripsiBarang(c.getString(c.getColumnIndexOrThrow(DatabaseManager.DESKRIPSI_BARANG)));
barangs.add(barang);
c.moveToNext();
}
listBarangAdapter.notifyItemRangeInserted(count, barangs.size());
}
checkDaftarBarang(barangs.size());
manager.close();
}

/*Metode menyembunyikan / menampilkan TextView yang berada di tengah layar.
Jika tidak ada item maka ditampilkan, dan sebaliknya. */
private void checkDaftarBarang(int totalItem) {
if (totalItem > 0) {
textKosong.setVisibility(View.GONE);
} else {
textKosong.setVisibility(View.VISIBLE);
}
}

/*Metode pesan toast sehingga tidak perlu berulang-ulang memanggil kelas Toast
yang juga memperpendek kodingan tentunya.*/
private void toast(String message) {
Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}

//Menghapus item secara tunggal kemudian memeriksa jumlah item yang tersisa.
@Override
public void checkBarang(int totalItem, int id) {
checkDaftarBarang(totalItem);
manager.open();
manager.hapusBarang(id);
manager.close();
}

//Mengetahui berapa jumlah item yang dipilih.
//Menyamakan data list selectedBarangs dengan data list item yang dipilih
/*sehingga nantinya bisa menghapus banyak item menggunakan selectedBarangs melalui java loop
* yang diimplementasikan di dalam onCreate*/
@SuppressLint("SetTextI18n")
@Override
public void selectedBarangs(List<Barang> barangs) {
selectedBarangs = barangs;
textDeleteItems.setText("Hapus " + barangs.size() + " dipilih");
}

/*Saat tidak ada item yang terpilih, boolean ini akan false. Penentuan nilai boolean ini sudah dilakukan
melalui adapter, juga melalui klik listener hapus banyak item yang terdapat didalam onCreate namun
nilainya hanya false.*/
@Override
public void onSelected(Boolean isSelected) {
if (isSelected) {
textDeleteItems.setVisibility(View.VISIBLE);
} else {
textDeleteItems.setVisibility(View.GONE);
}
}

//Menampilkan pesan toast saat item di klik (klik pendek / setOnClickListener)
@Override
public void onBarangClicked(String message) {
toast(message);
}
}


Baik, terimakasih atas waktu dan kunjungannya. Jika ada yang kurang berkenan mohon di maafkan, jika ada yang salah dan ada masalah silahkan diposting melalui kolom komentar.
Share:

0 comments:

Post a Comment

Hubungi Saya

Name

Email *

Message *

Berlangganan Artikel

Terlaris 30 Hari Terakhir