ใช้ RecyclerView แสดงรายการแบบ list ทำให้สามารถแสดงรายการจำนวนมากๆได้
- ใช้งาน RecyclerView
- ปรับแต่งเส้นคั่นด้วยไลบรารี่ RecyclerView-FlexibleDivider
- วาดตัวอักษรด้วยไลบรารี่ TextDrawable

ไฟล์ที่เกี่ยวข้อง
- build.gradle (Module: app)
- activity_main.xml
- MainActivity.java
- values/colors.xml
- drawable/item_state.xml
- layout/custom_layout.xml
- CustomItem.java
- CustomHolder.java
- CustomAdapter.java
1.ใช้งาน RecyclerView
build.gradle (Module: app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.0"
defaultConfig {
applicationId "com.phaisarn.myapplication"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
วาง RecyclerView ใน activity_main.xml
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java
package com.phaisarn.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ArrayList<CustomItem> items = new ArrayList<>();
items.add(new CustomItem("แมว", "Cat"));
items.add(new CustomItem("สุนัข", "Dog"));
items.add(new CustomItem("หนู", "Rat"));
items.add(new CustomItem("สิงโต", "Lion"));
items.add(new CustomItem("เสือ", "Tiger"));
items.add(new CustomItem("หมี", "Bear"));
items.add(new CustomItem("ไก่", "Chicken"));
items.add(new CustomItem("นก", "Bird"));
items.add(new CustomItem("ลิง", "Monkey"));
items.add(new CustomItem("ช้าง", "Elephant"));
items.add(new CustomItem("ยีราฟ", "Giraffe"));
items.add(new CustomItem("เป็ด", "Duck"));
items.add(new CustomItem("หมู", "Pig"));
items.add(new CustomItem("จิงโจ้", "Kangaroo"));
items.add(new CustomItem("ผีเสื้อ", "Butterfly"));
CustomAdapter adapter = new CustomAdapter(this, items);
RecyclerView rcv = findViewById(R.id.recyclerView);
rcv.setAdapter(adapter);
rcv.setLayoutManager(new LinearLayoutManager(this));
adapter.setOnClickListener(new CustomAdapter.OnItemClickListener() {
@Override
public void onItemClick(View item, int position) {
String str = items.get(position).text1 + " - " + items.get(position).text2;
Toast.makeText(getBaseContext(), str, Toast.LENGTH_SHORT).show();
}
});
}
}
กำหนด state ของรายการปกติ และรายการที่ถูกกด ให้แสดงสีต่างกัน
values/colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
<color name="item_active">#ffffc5</color>
<color name="item_normal">#ffffff</color>
</resources>
drawable/item_state.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:exitFadeDuration="500">
<item android:drawable="@color/item_active" android:state_pressed="true" />
<item android:drawable="@color/item_normal" />
</selector>
กำหนด layout ของแต่ละรายการใน RecyclerView
layout/custom_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="3dp"
android:background="@drawable/item_state"
android:orientation="horizontal"
android:padding="5dp">
<TextView
android:id="@+id/textView1"
android:layout_columnWeight="1"
android:layout_gravity="center_vertical"
android:layout_margin="10dp"
android:text="สัตว์"
android:textColor="#007"
android:textSize="20sp" />
<TextView
android:id="@+id/textView2"
android:layout_gravity="center_vertical"
android:layout_margin="10dp"
android:text="Animal"
android:textColor="#aaa"
android:textSize="18sp" />
</GridLayout>
CustomItem.java
package com.phaisarn.myapplication;
public class CustomItem {
public String text1;
public String text2;
public CustomItem(String text1, String text2) {
this.text1 = text1;
this.text2 = text2;
}
}
CustomHolder.java
package com.phaisarn.myapplication;
import android.view.View;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
public class CustomHolder extends RecyclerView.ViewHolder {
public TextView textView1;
public TextView textView2;
public CustomHolder(View view) {
super(view);
textView1 = view.findViewById(R.id.textView1);
textView2 = view.findViewById(R.id.textView2);
}
}
CustomAdapter.java
package com.phaisarn.myapplication;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class CustomAdapter extends RecyclerView.Adapter<CustomHolder> {
private Context mContext;
private List<CustomItem> mItems;
public CustomAdapter(Context context, List<CustomItem> items) { //กำหนดเป็น ArrayList เหมือนเดิมก็ได้
mContext = context;
mItems = items;
}
public interface OnItemClickListener {
void onItemClick(View item, int position);
}
private OnItemClickListener mListener;
public void setOnClickListener(OnItemClickListener listener) {
mListener = listener;
}
@Override
public int getItemCount() {
return mItems.size();
}
@Override
public CustomHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
final View view = inflater.inflate(R.layout.custom_layout, parent, false);
final CustomHolder viewHolder = new CustomHolder(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mListener != null) {
// int pos = viewHolder.getAdapterPosition();
// String str = viewHolder.textView1.getText().toString();
// str += " : " + viewHolder.textView2.getText().toString();
// if(pos != RecyclerView.NO_POSITION) {
// Toast.makeText(mContext, str, Toast.LENGTH_SHORT).show();
// }
int pos = viewHolder.getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
mListener.onItemClick(view, pos);
}
}
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(CustomHolder viewHolder, int position) {
CustomItem item = mItems.get(position);
viewHolder.textView1.setText(item.text1);
viewHolder.textView2.setText(item.text2);
}
}
บรรทัดที่ 56 ทำให้เกิดอีเวนต์ onItemClick()
แต่ถ้าต้องการจะทำงานในนี้เลยเช่น Toast จากในนี้ ให้ uncomment บรรทัดที่ 47-52 และ comment บรรทัดที่ 54-57 (และแก้ส่วนอื่นๆที่เกี่ยวช้อง)
2.ปรับแต่งเส้นคั่นด้วยไลบรารี่ RecyclerView-FlexibleDivider
Android library providing simple way to control divider items (ItemDecoration) of RecyclerView

build.gradle (Module: app)
...
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'com.yqritc:recyclerview-flexibledivider:1.4.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
MainActivity.java
package com.phaisarn.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ArrayList<CustomItem> items = new ArrayList<>();
items.add(new CustomItem("แมว", "Cat"));
items.add(new CustomItem("สุนัข", "Dog"));
items.add(new CustomItem("หนู", "Rat"));
items.add(new CustomItem("สิงโต", "Lion"));
items.add(new CustomItem("เสือ", "Tiger"));
items.add(new CustomItem("หมี", "Bear"));
items.add(new CustomItem("ไก่", "Chicken"));
items.add(new CustomItem("นก", "Bird"));
items.add(new CustomItem("ลิง", "Monkey"));
items.add(new CustomItem("ช้าง", "Elephant"));
items.add(new CustomItem("ยีราฟ", "Giraffe"));
items.add(new CustomItem("เป็ด", "Duck"));
items.add(new CustomItem("หมู", "Pig"));
items.add(new CustomItem("จิงโจ้", "Kangaroo"));
items.add(new CustomItem("ผีเสื้อ", "Butterfly"));
CustomAdapter adapter = new CustomAdapter(this, items);
RecyclerView rcv = findViewById(R.id.recyclerView);
rcv.setAdapter(adapter);
rcv.setLayoutManager(new LinearLayoutManager(this));
rcv.addItemDecoration(
new HorizontalDividerItemDecoration.Builder(this)
.color(Color.LTGRAY)
.size(4)
.margin(30, 30) //left, right
.build());
adapter.setOnClickListener(new CustomAdapter.OnItemClickListener() {
@Override
public void onItemClick(View item, int position) {
String str = items.get(position).text1 + " - " + items.get(position).text2;
Toast.makeText(getBaseContext(), str, Toast.LENGTH_SHORT).show();
}
});
}
}
บรรทัดที่ 48 กำหนดสีเส้นคั่น
บรรทัดที่ 49 กำหนดขนาดเส้นคั่น
บรรทัดที่ 50 กำหนด margin ด้านซ้ายและขวาของเส้นคั่น
3.วาดตัวอักษรด้วยไลบรารี่ TextDrawable
TextDrawable This light-weight library provides images with letter/text like the Gmail app. It extends the Drawable class thus can be used with existing/custom/network ImageView classes. Also included is a fluent interface for creating drawables and a customizable ColorGenerator.
นำตัวอักษรตัวแรกของข้อความภาษาไทยมาวาดเป็นภาพ

build.gradle (Module: app)
...
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'com.yqritc:recyclerview-flexibledivider:1.4.0'
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
MainActivity.java
package com.phaisarn.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
import java.util.ArrayList;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ArrayList<CustomItem> items = new ArrayList<>();
int i = R.mipmap.ic_launcher;
items.addAll(Arrays.asList(
new CustomItem(i, "แมว", "Cat"),
new CustomItem(i, "สุนัข", "Dog"),
new CustomItem(i, "หนู", "Rat"),
new CustomItem(i, "สิงโต", "Lion"),
new CustomItem(i, "เสือ", "Tiger"),
new CustomItem(i, "หมี", "Bear"),
new CustomItem(i, "ไก่", "Chicken"),
new CustomItem(i, "นก", "Bird"),
new CustomItem(i, "ลิง", "Monkey"),
new CustomItem(i, "ช้าง", "Elephant"),
new CustomItem(i, "ยีราฟ", "Giraffe"),
new CustomItem(i, "เป็ด", "Duck"),
new CustomItem(i, "หมู", "Pig"),
new CustomItem(i, "จิงโจ้", "Kangaroo"),
new CustomItem(i, "ผีเสื้อ", "Butterfly")
));
CustomAdapter adapter = new CustomAdapter(this, items);
RecyclerView rcv = findViewById(R.id.recyclerView);
rcv.setAdapter(adapter);
rcv.setLayoutManager(new LinearLayoutManager(this));
rcv.addItemDecoration(
new HorizontalDividerItemDecoration.Builder(this)
.color(Color.LTGRAY)
.size(4)
.margin(200, 0) //left, right
.build());
adapter.setOnClickListener(new CustomAdapter.OnItemClickListener() {
@Override
public void onItemClick(View item, int position) {
String str = items.get(position).text1 + " - " + items.get(position).text2;
Toast.makeText(getBaseContext(), str, Toast.LENGTH_SHORT).show();
}
});
}
}
layout/custom_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:columnCount="2">
<ImageView
android:id="@+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_rowSpan="3"
android:layout_marginRight="15dp"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/textView1"
android:layout_columnWeight="1"
android:layout_marginBottom="5dp"
android:textColor="#00b"
android:textSize="20sp" />
<TextView
android:id="@+id/textView2"
android:layout_columnWeight="1"
android:layout_marginBottom="5dp"
android:textColor="#050"
android:textSize="18sp" />
</GridLayout>
CustomItem.java
package com.phaisarn.myapplication;
public class CustomItem {
public int imgId;
public String text1;
public String text2;
public CustomItem(int imgId, String text1, String text2) {
this.imgId = imgId;
this.text1 = text1;
this.text2 = text2;
}
}
CustomHolder.java
package com.phaisarn.myapplication;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
public class CustomHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public TextView textView1;
public TextView textView2;
public CustomHolder(View view) {
super(view);
imageView = view.findViewById(R.id.imageView);
textView1 = view.findViewById(R.id.textView1);
textView2 = view.findViewById(R.id.textView2);
}
}
CustomAdapter.java
package com.phaisarn.myapplication;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
import java.util.List;
public class CustomAdapter extends RecyclerView.Adapter<CustomHolder> {
private Context mContext;
private List<CustomItem> mItems;
public CustomAdapter(Context context, List<CustomItem> items) { //กำหนดเป็น ArrayList เหมือนเดิมก็ได้
mContext = context;
mItems = items;
}
public interface OnItemClickListener {
void onItemClick(View item, int position);
}
private OnItemClickListener mListener;
public void setOnClickListener(OnItemClickListener listener) {
mListener = listener;
}
@Override
public int getItemCount() {
return mItems.size();
}
@Override
public CustomHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
final View view = inflater.inflate(R.layout.custom_layout, parent, false);
final CustomHolder viewHolder = new CustomHolder(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mListener != null) {
// int pos = viewHolder.getAdapterPosition();
// String str = viewHolder.textView1.getText().toString();
// str += " : " + viewHolder.textView2.getText().toString();
// if(pos != RecyclerView.NO_POSITION) {
// Toast.makeText(mContext, str, Toast.LENGTH_SHORT).show();
// }
int pos = viewHolder.getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
mListener.onItemClick(view, pos);
}
}
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(CustomHolder viewHolder, int position) {
CustomItem item = mItems.get(position);
String letter = String.valueOf(item.text1.charAt(0));
ColorGenerator generator = ColorGenerator.MATERIAL;
TextDrawable drawable = TextDrawable.builder()
.buildRound(letter, generator.getRandomColor());
//.buildRect(letter, generator.getRandomColor())
//.buildRoundRect(letter, generator.getRandomColor(), 50);
viewHolder.imageView.setImageDrawable(drawable);
viewHolder.textView1.setText(item.text1);
viewHolder.textView2.setText(item.text2);
}
}
Link