Recycler View and Custom Adaptor

Mila
pie-o
Published in
3 min readApr 6, 2017

Halo! Kali ini saya akan membahas salah satu fitur dari sibujang app yang memerlukan tampilan card yang berulang. Fitur tersebut merupakan fitur yang menampilkan list pencapaian-pencapaian yang diraih oleh sales force. Berikut rancangan wireframe yang kelompok kami telah buat :

Data yang kami miliki pada dasarnya dinamis yang artinya stuktur datanya berubah-ubah, hanya saja pada data pencapaian terdapat tiga attribut data yang pastinya sama yaitu id, tipe dan tanggal. Sisa data merupakan data yang dinamis tergantung akan kebutuhan pengisi. Oleh karena keadaan data yang demikian rupa, kami memutuskan untuk membuat suatu class ‘Achievement’ yang isinya sebagai berikut :

public class Achievement{

private String id;
private String type;
private DateTime date;
ArrayList<String> data;

public Achievement(String id, String type, String date, ArrayList<String> data) {
this.id = id;
this.type = type;
this.date = new DateTime(date);
this.data=data;
}

public String getId() {
return id;
}

public String getType() {
return type;
}

public String getDate() {
String month = date.monthOfYear().getAsText();
int number = date.getDayOfMonth();
String day = date.dayOfWeek().getAsText();
String year = date.year().getAsShortText();
return day+", "+number+" "+month+" "+year;
}

public ArrayList<String> getData() {
return data;
}
}

Kelas achievement kemudian akan diisi oleh data yang bersumber dari API. Setelah membuat kelas objek penyimpanan tentunya kita harus merancang tampilan yang akan dikeluarkan nanti. Untuk tampilan sendiri tentunya kita memerlukan card yang berulang. Pada android untuk mengaplikasikan card kita dapat menggunakan widget CardView dan untuk mengaplikasikan card yang berulang kita menggunakan widget RecyclerView. Pertama-tama kita harus mendefinisikan konten pada sebuah card dan menyimpannya pada suatu xml. Kemudian kita mendefinisikan RecyclerView pada xml yang menjadi ‘main’ tampilan.

Pemanggilan RecyclerView :

<?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"
xmlns:card_view="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.hp.sibujang_app.MainActivity"
android:baselineAligned="false"
>

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
/>


<RelativeLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>

<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:scrollbars="vertical"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
/>



</RelativeLayout>

<android.support.design.widget.BottomNavigationView
android:id="@+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?android:attr/windowBackground"
app:menu="@menu/navigation"
/>



</LinearLayout>

Detail tiap card :

<?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"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<android.support.v7.widget.CardView
android:id="@+id/card_view"
android:layout_width= "match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
app:cardCornerRadius="4dp"
>
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/Achievement_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:text=""
/>
<TextView
android:id="@+id/Achievement_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="30dp"
android:layout_marginBottom="10dp"
android:text=""
android:textSize="@dimen/font_size_large"
/>

</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>

Untuk menampilkan tampilan yang berulang, RecyclerView memerlukan class Adapter. Pada dasarnya class adapter sudah terdefinisi sendiri pada java namun dikarenakan kita ingin menampilkan hal yang cukup berbeda oleh karena itu kita membuat CustomAdapter yang mengextends RecyclerView.Adapter. Pada adapter yang kita miliki, data yang akan ditampilkan disimpan kedalam List of data object achievement yang akan di loop oleh adapter. Berikut kode sumbernya :

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {

private Context context;
private List<Achievement> my_data;


public CustomAdapter(Context context, List<Achievement> my_data) {
this.context = context;
this.my_data = my_data;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card,parent,false);

return new ViewHolder(itemView,this.context,this.my_data);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.achievement_date.setText( my_data.get(position).getDate());
holder.achievement_type.setText(my_data.get(position).getType());


}

@Override
public int getItemCount() {
return my_data.size();
}
public Context getContext(){
return context;
}



public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

public TextView achievement_date;
public TextView achievement_type;
private String achievementTitle;
private Context context;
private List<Achievement> my_data;

public ViewHolder(View itemView, Context context, List<Achievement> my_data) {
super(itemView);
this.my_data=my_data;
this.context=context;
achievement_date = (TextView) itemView.findViewById(R.id.Achievement_date);
achievement_type = (TextView) itemView.findViewById(R.id.Achievement_type);
itemView.setOnClickListener(this);
}

@Override
public void onClick(View v) {
int position= getAdapterPosition();
Achievement objectAchievement = this.my_data.get(position);
achievementTitle=objectAchievement.getType() + "( " + objectAchievement.getDate() + ")";
Intent intent = new Intent(this.context, DetailAchievement.class);
intent.putStringArrayListExtra("achievementAttribute",(ArrayList<String>) objectAchievement.getData());
intent.putExtra("achievementTitle",achievementTitle);
context.startActivity(intent);
}
}

Setelah mendefinisikan CustomAdapter selanjutnya kita dapat memanggil pada bagian main java kita. Tampilan yang kita butuhkan adalah card yang horizontal dan berulang kebawah oleh karena itu kita memerlukan layout manager yang tepat pada RecyclerView untuk menampilkan hal tersebut yaitu linearLayoutManager. Setelah melakukan setlayoutmanager lalu kita bisa melakukan setAdapter. Berikut kode sumbernya :

recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
data_list = new ArrayList<>();

linearLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(linearLayoutManager);

adapter = new CustomAdapter(this,data_list);
recyclerView.setAdapter(adapter);

Usai sudah code RecyclerView with Adapter, dan berikut hasilnya!

--

--