Hmm… Cari jodoh? Emang bisa? Hahaha ngarep banget ya pasti. Tapi mari kita coba tutorial kali ini, barang kali berhasil haha. Kali ini, saya akan membagikan cara menggunakan SearchView untuk mencari data dengan query yang kita inputkan. Data yang digunakan adalah data dari file json lokal.
Terima kasih sebelumnya kepada dominictarr untuk file jsonnya. Jika kalian ingin menggunakan beberapa file json, dapat diunduh di https://github.com/dominictarr/random-name.
Ditutorial kali ini, saya menggunakan salah satu file yang telah saya unduh dari link diatas, yaitu first-names.json yang berisi nama depan orang. File tersebut disimpan didalam folder src/main/assets agar dapat digunakan nantinya. Folder assetsnya belum ada? Ya dibuat aja gan 😀
Untuk menampilkan hasil dari query, saya menggunakan recyclerview. Ini butuh 1 library tambahan, silahkan tambahkan dulu diawal, biar kodingnya lancar.
compile 'com.android.support:recyclerview-v7:23.1.1'
Angka 23.1.1 itu bisa dirubah, sesuai support design library anda. Yang terbaru untuk saat ini 23.2.0, tapi kemaren menemukan beberapa masalah yang belum bisa saya pecahkan, jadi saya menggunakan yang versi sebelumnya saja.
Berikut adalah screenshot projekan saya, seperti biasa agar lebih mudah untuk mengikutinya.
Melihat isi file first-names.json
[ "Aaren" , "Aarika" , "Abagael" , "Abagail" , "Abbe" , "Abbey" , "Abbi" , "Abbie" , "Abby" , "Abbye" , "Abigael" , "Abigail" , "Abigale" , "Abra" . . .
Isi dari file json tersebut ternyata berupa array kumpulan nama, itu karena tanda pembuka awal berupa “[“. Bagi yang belum terlalu mengerti tentang JSON ini, bisa pelajari dulu post saya tentang JSON ini. Silahkan buka link berikut : http://www.andevindo.com/urai-data-json/
SearchView
SearchView merupakan salah fitur yang disediakan oleh android yang difungsikan untuk search/mencari sesuatu. Dapat diterapkan untuk mencari data lokal seperti ditutorial kali ini ataupun data yang ada didatabase dan kemudian hasilnya ditampilkan dilist atau recyclerview biasanya.
Beberapa hal yang perlu disiapkan untuk menggunakan SearchView ini:
- Buat sebuah file bernama searchable.xml (bebas namanya) taruh difolder res/xml.
searchable.xml
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_name" android:hint="@string/hint"/>
- Didalam file searchable ini berisi settingan untuk searchview, seperti label, hint dan lain-lain. Semisal untuk label dan hint atau yang membutuhkan inputan berupa string, inputan tersebut tidak boleh hardcode atau dituliskan difile tersebut secara langsung, harus dituliskan didalam file strings.xml yang berada di folder res/values.
strings.xml
<resources> <string name="app_name">MencariJodohSearchView</string> <string name="action_settings">Settings</string> <string name="hint">Cari nama jodohmu...</string> </resources>
- Otak-atik dibagian manifest.
Penjelasan mengenai screenshot diatas:
- launchMode = singleTop
Kenapa memilih singleTop karena SearchView yang diterapkan ditutorial kali ini hanya menggunakan sebuah Activity saja. Ketika button search/go yang ada dikeypad hp ditekan, maka akan memanggil Activity baru. Jika tidak diberi pilihan singleTop, maka akan terbuat activity baru ditask yang sama. Beda halnya jika diset singleTop, jika Activity sudah berada ditask, maka jika dipanggil kembali, tidak akan membuat Activity baru, melainkan memanggil yang lama dan memanggil method onNewIntent() - action.SEARCH
Menandakan bahwa Activity tersebut menerima query search (CMIIW) - meta data searchable
Sebagai settingan untuk SearchView yang berada di Activity tersebut
Layout
Layout yang perlu kita rubah dan kita buat adalah content_main.xml dan recycler_jodoh.xml
content_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="andevindo.com.mencarijodohsearchview.MainActivity" tools:showIn="@layout/activity_main"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
recycler_jodoh.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="16dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:text="Nama : " android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.AppCompat.Body1"/> <TextView android:id="@+id/nama" android:text="Ana" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:text="Status : " android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.AppCompat.Body1"/> <TextView android:id="@+id/status" android:text="Jomblo" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout>
Coding time 😀
JodohModel.class
package andevindo.com.mencarijodohsearchview; /** * Created by -H- on 2/28/2016. */ public class JodohModel { private String mName; private Status mStatus; public enum Status{ Jomblo, Single, Merana, Darurat, Galau, } public String getName() { return mName; } public void setName(String name) { mName = name; } public Status getStatus() { return mStatus; } public void setStatus(Status status) { mStatus = status; } }
Class ini dibuat sebagai model dari objek yang dibutuhkan. Didalamnya terdapat nama dan status yang nantinya akan kita isi dan kita tampilkan direcyclerview
JodohAdapter.class
package andevindo.com.mencarijodohsearchview; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.List; /** * Created by -H- on 2/28/2016. */ public class JodohAdapter extends RecyclerView.Adapter<JodohAdapter.JodohViewHolder> { private List<JodohModel> mList; private Context mContext; public JodohAdapter(Context context) { mContext = context; } public void setData(List<JodohModel> list){ mList = list; notifyDataSetChanged(); } @Override public JodohViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(R.layout.recycler_jodoh, parent, false); return new JodohViewHolder(view); } @Override public void onBindViewHolder(JodohViewHolder holder, int position) { holder.setData(mList.get(position)); } @Override public int getItemCount() { if (mList == null) return 0; else return mList.size(); } class JodohViewHolder extends RecyclerView.ViewHolder { private TextView mName, mStatus; public JodohViewHolder(View itemView) { super(itemView); mName = (TextView)itemView.findViewById(R.id.nama); mStatus = (TextView)itemView.findViewById(R.id.status); } public void setData(JodohModel jodohModel) { mName.setText(jodohModel.getName()); mStatus.setText(jodohModel.getStatus().name()); } } }
Class diatas untuk adapter dari recyclerview. Dengan menggunakan layout dari recycler_jodoh.xml dan data dari List<JodohModel> yang diinputkan pada waktu method setData dipanggil;
Data ditutorial kali ini berada dalam folder assets, oleh karena itu kita perlu memanggilnya untuk dapat digunakan, saya menggunakan method seperti dibawah untuk mendapatkan String yang isinya berupa JSON.
private String loadJSONFromAsset() { String json = null; try { InputStream is = getAssets().open("first-names.json"); int size = is.available(); byte[] buffer = new byte[size]; is.read(buffer); is.close(); json = new String(buffer, "UTF-8"); } catch (IOException ex) { ex.printStackTrace(); return null; } catch (NullPointerException ex){ ex.printStackTrace(); return null; } return json; }
Untuk lengkapnya, seperti dibawah:
MainActivity.class
package andevindo.com.mencarijodohsearchview; import android.app.SearchManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SearchView; import android.support.v7.widget.Toolbar; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Random; public class MainActivity extends AppCompatActivity { private RecyclerView mRecycler; private JodohAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); mRecycler = (RecyclerView) findViewById(R.id.recycler); mRecycler.setLayoutManager(new LinearLayoutManager(getApplicationContext())); mAdapter = new JodohAdapter(this); mRecycler.setAdapter(mAdapter); } //Dipanggil ketika Activity dipanggil kembali, kondisi itu terjadi ketika //menekan search/go pada keypad untuk submit query @Override protected void onNewIntent(Intent intent) { handleIntent(intent); } //Generate data list dari hasil file json yang diambil, //terdapat parameter untuk menyeleksi data yang ditampilkan direcyclerview List<JodohModel> loadData(String query) { List<JodohModel> list = null; try { JSONArray jsonArray = new JSONArray(loadJSONFromAsset()); list = new ArrayList<>(jsonArray.length()); for (int i = 0; i < jsonArray.length(); i++) { if (jsonArray.getString(i).toLowerCase().startsWith(query.toLowerCase())){ JodohModel jodohModel = new JodohModel(); jodohModel.setName(jsonArray.getString(i)); jodohModel.setStatus(JodohModel.Status.values()[new Random().nextInt(5)]); list.add(jodohModel); } } } catch (JSONException e) { e.printStackTrace(); } catch (NullPointerException e){ e.printStackTrace(); } return list; } //Method untuk mendapatkan String dari file JSON private String loadJSONFromAsset() { String json = null; try { InputStream is = getAssets().open("first-names.json"); int size = is.available(); byte[] buffer = new byte[size]; is.read(buffer); is.close(); json = new String(buffer, "UTF-8"); } catch (IOException ex) { ex.printStackTrace(); return null; } catch (NullPointerException ex){ ex.printStackTrace(); return null; } return json; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); //Set SearchView dengan search manager SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); final SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView(); //Jika ingin menggunakan Activity lain untuk menangkap hasil dari query, //rubah getComponentName() dengan nama Activity yang diinginkan searchView.setSearchableInfo( searchManager.getSearchableInfo(getComponentName())); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.search) { return true; } return super.onOptionsItemSelected(item); } //Digunakan untuk merubah data recyclerview ketika terdapat query yang dikirimkan private void handleIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); mAdapter.setData(loadData(query)); Toast.makeText(MainActivity.this, "" + query, Toast.LENGTH_SHORT).show(); } } }
Berikut screenshot hasil dari tutorial kali ini: