Melanjutkan artikel bagian 1 yang sebelumnya merupakan bagian pembuatan layout untuk membuat aplikasi sederhana mengkombinasikan Java dan Kotlin. nah, pada bagian ini kita fokus pada bagian kode.
Pertama buat package models,
letakkan didalam package com.dekikurnia.belajarkotlin
. Kemudian, buat class Java dengan nama Item.
pada class ini kita buat 3 buah variabel yaitu id
, title
dan description.
variabel id
kita gunakan sebagai kunci utama (primary key). Berikut kodenya :
Item.java :
package com.dekikurnia.belajarkotlin.models; import io.realm.RealmObject; import io.realm.annotations.PrimaryKey; public class Item extends RealmObject { @PrimaryKey private String id; private String title; private String description; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
Setelah membuat model, selanjutnya adalah membuat adapter untuk menyiapkan layout dan mengatur bagaimana item akan ditampilkan di RecyclerView. Buat class Java dengan nama ItemAdapter didalam package com.dekikurnia.belajarkotlin
ItemAdapter.java :
package com.dekikurnia.belajarkotlin; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.dekikurnia.belajarkotlin.models.Item; import butterknife.Bind; import butterknife.ButterKnife; import io.realm.RealmBasedRecyclerViewAdapter; import io.realm.RealmResults; import io.realm.RealmViewHolder; public class ItemAdapter extends RealmBasedRecyclerViewAdapter<Item, ItemAdapter.ViewHolder> { private ItemClickListener clickListener; public ItemAdapter(Context context, RealmResults<Item> realmResults, boolean automaticUpdate, boolean animateResults, ItemClickListener clickListener) { super(context, realmResults, automaticUpdate, animateResults); this.clickListener = clickListener; } @Override public ViewHolder onCreateRealmViewHolder(ViewGroup viewGroup, int i) { View v = inflater.inflate(R.layout.crud_item, viewGroup, false); return new ViewHolder(v, clickListener); } @Override public void onBindRealmViewHolder(ViewHolder viewHolder, int i) { final Item item = realmResults.get(i); viewHolder.ItemTitle.setText(item.getTitle()); } class ViewHolder extends RealmViewHolder implements View.OnClickListener { @Bind(R.id.crud_item_title) public TextView ItemTitle; private ItemClickListener clickListener; public ViewHolder(View itemView, ItemClickListener clickListener) { super(itemView); this.clickListener = clickListener; ButterKnife.bind(this, itemView); itemView.setOnClickListener(this); } @Override public void onClick(View v) { if(clickListener != null) { clickListener.onItemClick(v, realmResults.get(getAdapterPosition())); } } } public interface ItemClickListener { void onItemClick(View caller, Item task); } }
Setelah membuat kode untuk adapter, selanjutnya ada membuat kode untuk fragment. Fragment ini mengimplementasikan method ItemAdapter.ItemClickListener
kemudian implement all abstract method tadi.
Setelah itu akan muncul method onItemClick.
Pada method onItemClick
inilah, item yang tampil ketika diklik akan memanggil class EditFragment sekaligus menyembunyikan FloatingActionButton.
ItemFragment.java :
package com.dekikurnia.belajarkotlin; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.dekikurnia.belajarkotlin.models.Item; import butterknife.Bind; import butterknife.ButterKnife; import co.moonmonkeylabs.realmrecyclerview.RealmRecyclerView; import io.realm.Realm; import io.realm.RealmResults; public class ItemFragment extends Fragment implements ItemAdapter.ItemClickListener { @Bind(R.id.crud_recycler_view) protected RealmRecyclerView rv; private Realm realm; public static ItemFragment newInstance() { return new ItemFragment(); } public ItemFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_crud, container, false); ButterKnife.bind(this, v); return v; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); realm = Realm.getDefaultInstance(); } @Override public void onResume() { super.onResume(); RealmResults<Item> todos = realm.where(Item.class).findAll(); ItemAdapter adapter = new ItemAdapter(getActivity(), todos, true, true, this); rv.setAdapter(adapter); } @Override public void onDestroy() { super.onDestroy(); realm.close(); } @Override public void onItemClick(View caller, Item task) { ((MainActivity)getActivity()).hideFab(); EditFragment editFragment = EditFragment.Companion.newInstance(task.getId()); getActivity().getSupportFragmentManager() .beginTransaction() .replace(R.id.content_main, editFragment, editFragment.getClass().getSimpleName()) .addToBackStack(editFragment.getClass().getSimpleName()) .commit(); } }
Kemudian kita buat file Kotlin dengan nama EditFragment. class ini merupakan logic untuk mengubah beberapa variabel. Misalnya, ketika akan menambahkan item maka button akan bernama simpan. Tapi, jika item sudah tersimpan dan kita klik maka button akan berubah menjadi ubah. Pada class ini juga Anko digunakan pada bagian method :
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { return UI { verticalLayout { padding = dip(30) var title = editText { id = R.id.crud_title hintResource = R.string.title_hint } var desc = editText { id = R.id.crud_desc hintResource = R.string.description_hint } button { id = R.id.crud_add textResource = R.string.add_item onClick { view -> createItemFrom(title, desc) } } } }.view }
Pada kode diatas, kita membuat LinearLayout dengan dua buah form input menggunakan editText dan satu Button. Kemudian pada method override fun onActivityCreated(savedInstanceState: Bundle?)
, ketika item diklik maka akan mencari data berdasarkan id
sebagai primary key dan button simpan akan berubah menjadi button ubah
override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) if(arguments != null && arguments.containsKey(Item_ID_KEY)) { val ItemId = arguments.getString(Item_ID_KEY) item = realm.where(Item::class.java).equalTo("id", ItemId).findFirst() val todoTitle = find<EditText>(R.id.crud_title) todoTitle.setText(item?.title) val todoDesc = find<EditText>(R.id.crud_desc) todoDesc.setText(item?.description) val add = find<Button>(R.id.crud_add) add.setText(R.string.save) } }
Kode lengkap dari EditFragment sebagai berikut :
EditFragment.kt
package com.dekikurnia.belajarkotlin import android.os.Bundle import android.support.v4.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button import android.widget.EditText import com.dekikurnia.belajarkotlin.models.Item import io.realm.Realm import org.jetbrains.anko.* import org.jetbrains.anko.support.v4.UI import org.jetbrains.anko.support.v4.find import java.util.* class EditFragment : Fragment() { val Item_ID_KEY: String = "item_id_key" val realm: Realm = Realm.getDefaultInstance() var item: Item? = null companion object { fun newInstance(id: String): EditFragment { var args: Bundle = Bundle() args.putString("item_id_key", id) var editFragment: EditFragment = newInstance() editFragment.arguments = args return editFragment } fun newInstance(): EditFragment { return EditFragment() } } override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { return UI { verticalLayout { padding = dip(30) var title = editText { id = R.id.crud_title hintResource = R.string.title_hint } var desc = editText { id = R.id.crud_desc hintResource = R.string.description_hint } button { id = R.id.crud_add textResource = R.string.add_item onClick { view -> createItemFrom(title, desc) } } } }.view } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) if(arguments != null && arguments.containsKey(Item_ID_KEY)) { val ItemId = arguments.getString(Item_ID_KEY) item = realm.where(Item::class.java).equalTo("id", ItemId).findFirst() val itemTitle = find<EditText>(R.id.crud_title) itemTitle.setText(item?.title) val itemDesc = find<EditText>(R.id.crud_desc) itemDesc.setText(item?.description) val add = find<Button>(R.id.crud_add) add.setText(R.string.save) } } override fun onDestroy() { super.onDestroy() realm.close() } private fun createItemFrom(title: EditText, desc: EditText) { realm.beginTransaction() var t = item?: realm.createObject(Item::class.java) t.id = item?.id?: UUID.randomUUID().toString() t.title = title.text.toString() t.description = desc.text.toString() realm.commitTransaction() activity.supportFragmentManager.popBackStack(); } }
Selesai membuat kode untuk EditFragment, mari kita ubah MainActivity. Pada bagian kode ini logicnya adalah saat FloatingActionButton diklik maka akan memanggil ItemFragment untuk menambah item dan saat memanggil ItemFragment otomatis FloatingActionButton akan menghilang pada bagian method hideFab().
Berikut kode lengkapnya :
MainActivity.java
package com.dekikurnia.belajarkotlin; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.v4.app.FragmentManager; import android.support.v7.app.AppCompatActivity; import android.view.View; public class MainActivity extends AppCompatActivity { FloatingActionButton fab; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { EditFragment editFragment = EditFragment.Companion.newInstance(); getSupportFragmentManager() .beginTransaction() .replace(R.id.content_main, editFragment, editFragment.getClass().getSimpleName()) .addToBackStack(editFragment.getClass().getSimpleName()) .commit(); hideFab(); } }); ItemFragment fragment = ItemFragment.newInstance(); getSupportFragmentManager() .beginTransaction() .replace(R.id.content_main, fragment, fragment.getClass().getSimpleName()) .commit(); getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { int backStackCount = getSupportFragmentManager().getBackStackEntryCount(); if(backStackCount == 0) { fab.setVisibility(View.VISIBLE); } } }); } public void hideFab() { fab.setVisibility(View.GONE); } }
Kemudian buat class baru dengan nama KotlinMix. berikut kodenya :
package com.dekikurnia.belajarkotlin; import android.app.Application; import io.realm.Realm; import io.realm.RealmConfiguration; public class KotlinMix extends Application { @Override public void onCreate() { super.onCreate(); RealmConfiguration config = new RealmConfiguration.Builder(this) .name("kotlinmix.realm") .build(); Realm.setDefaultConfiguration(config); Realm.deleteRealm(config); } }
Terakhir, rubah AndroidManifest.xml menjadi seperti ini :
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest package="com.dekikurnia.belajarkotlin" xmlns:android="http://schemas.android.com/apk/res/android"> <application android:name=".KotlinMix" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
Kode untuk logic aplikasi sudah selesai, silahkan run aplikasi. Mudah-mudahan tidak ada yang error :D, bagi yang kesulitan silahkan tinggalkan di kolom komentar