ใช้ 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