สร้างรายการแบบไดนามิกด้วย RecyclerView เป็นส่วนหนึ่งของ Android Jetpack
RecyclerView ช่วยให้คุณแสดงชุดข้อมูลขนาดใหญ่ได้อย่างมีประสิทธิภาพ คุณระบุข้อมูลและกำหนดลักษณะที่แต่ละรายการมี และไลบรารี RecyclerView จะสร้างองค์ประกอบแบบไดนามิกเมื่อจำเป็น
ตามชื่อที่บอกไว้ RecyclerView จะรีไซเคิลองค์ประกอบแต่ละรายการเหล่านั้น เมื่อรายการเลื่อนออกไปนอกหน้าจอ RecyclerView จะไม่ทำลายมุมมองของรายการนั้น แต่ RecyclerView จะใช้มุมมองนั้นซ้ำสำหรับรายการใหม่ที่เลื่อนบนหน้าจอแทน RecyclerView ช่วยปรับปรุงประสิทธิภาพและการตอบสนองของแอป รวมถึงลดการใช้พลังงาน
เสมอคลาสหลัก
คลาสหลายคลาสทำงานร่วมกันเพื่อสร้างรายการแบบไดนามิก
RecyclerView
คือViewGroup
ที่มีมุมมองซึ่งสอดคล้องกับข้อมูลของคุณRecyclerView
เป็นมุมมองหนึ่งๆ คุณจึงเพิ่มRecyclerView
ลงในเลย์เอาต์ได้เช่นเดียวกับการเพิ่มองค์ประกอบ UI อื่นๆแต่ละองค์ประกอบในรายการจะกำหนดโดยออบเจ็กต์ ViewHolder เมื่อสร้างตัวยึดตำแหน่งวิวแล้ว จะไม่มีข้อมูลใดๆ เชื่อมโยงอยู่ หลังจากสร้างตัวยึดตำแหน่งแล้ว
RecyclerView
จะเชื่อมโยงตัวยึดตำแหน่งนั้นกับข้อมูล คุณกำหนดตัวยึดตำแหน่งโฆษณาได้โดยขยายRecyclerView.ViewHolder
RecyclerView
จะขอมุมมองและเชื่อมโยงมุมมองกับข้อมูลโดยเรียกใช้เมธอดในอะแดปเตอร์ คุณกำหนดอะแดปเตอร์โดยการขยายRecyclerView.Adapter
เครื่องมือจัดการเลย์เอาต์จะจัดเรียงองค์ประกอบแต่ละรายการในรายการ คุณจะใช้ตัวจัดการเลย์เอาต์รายการใดรายการหนึ่งจากคลัง RecyclerView หรือจะกำหนดเองก็ได้ เครื่องมือจัดการเลย์เอาต์ทั้งหมดจะอิงตามคลาส抽象ของ
LayoutManager
คุณสามารถดูว่าชิ้นส่วนทั้งหมดทำงานร่วมกันได้อย่างไรในแอปตัวอย่าง RecyclerView (Kotlin) หรือแอปตัวอย่าง RecyclerView (Java)
ขั้นตอนในการใช้งาน RecyclerView
หากต้องการใช้ RecyclerView คุณต้องทำสิ่งต่อไปนี้ ซึ่งอธิบายไว้อย่างละเอียดในส่วนต่อไปนี้
เลือกลักษณะของรายการหรือตารางกริด โดยปกติแล้ว คุณจะใช้เครื่องมือจัดการเลย์เอาต์มาตรฐานของไลบรารี RecyclerView ได้
ออกแบบลักษณะและลักษณะการทํางานขององค์ประกอบแต่ละรายการในรายการ ขยายคลาส
ViewHolder
ตามการออกแบบนี้ViewHolder
เวอร์ชันของคุณมีฟังก์ชันการทำงานทั้งหมดสำหรับรายการในลิสต์ ตัวยึดตำแหน่งมุมมองของคุณคือView
ที่ใช้ห่อหุ้มRecyclerView
และRecyclerView
จะจัดการมุมมองนั้นกําหนด
Adapter
ที่เชื่อมโยงข้อมูลของคุณกับมุมมองViewHolder
นอกจากนี้ยังมีตัวเลือกการปรับแต่งขั้นสูงที่ช่วยให้คุณปรับแต่ง RecyclerView ให้ตรงกับความต้องการได้
วางแผนเลย์เอาต์
รายการใน RecyclerView จะจัดเรียงตามคลาส LayoutManager
ไลบรารี RecyclerView มีตัวจัดการเลย์เอาต์ 3 รายการ ซึ่งจัดการสถานการณ์เลย์เอาต์ที่พบบ่อยที่สุด ดังนี้
LinearLayoutManager
จัดเรียงรายการในลิสต์มิติข้อมูลเดียวGridLayoutManager
จัดเรียงรายการในตารางกริด 2 มิติ โดยทำดังนี้- หากตารางกริดจัดเรียงในแนวตั้ง
GridLayoutManager
จะพยายามทำให้องค์ประกอบทั้งหมดในแต่ละแถวมีความกว้างและความสูงเท่ากัน แต่แถวต่างๆ อาจมีความสูงต่างกัน - หากจัดตารางกริดในแนวนอน
GridLayoutManager
จะพยายามทำให้องค์ประกอบทั้งหมดในแต่ละคอลัมน์มีความกว้างและความสูงเท่ากัน แต่คอลัมน์ต่างๆ อาจมีความกว้างต่างกัน
- หากตารางกริดจัดเรียงในแนวตั้ง
StaggeredGridLayoutManager
คล้ายกับGridLayoutManager
แต่ไม่จำเป็นต้องกำหนดให้รายการในแถวมีความสูงเท่ากัน (สำหรับตารางกริดแนวตั้ง) หรือรายการในคอลัมน์เดียวกันมีความกว้างเท่ากัน (สำหรับตารางกริดแนวนอน) ผลที่ได้คือรายการในแถวหรือคอลัมน์อาจมีการเลื่อนออกจากกัน
นอกจากนี้ คุณยังต้องออกแบบเลย์เอาต์ของรายการแต่ละรายการด้วย คุณต้องใช้เลย์เอาต์นี้เมื่อออกแบบตัวยึดตำแหน่งโฆษณาตามที่อธิบายไว้ในส่วนถัดไป
ใช้อะแดปเตอร์และตัวยึดมุมมอง
เมื่อกำหนดเลย์เอาต์แล้ว คุณจะต้องติดตั้งใช้งาน Adapter
และ
ViewHolder
คลาสทั้ง 2 คลาสนี้ทํางานร่วมกันเพื่อกําหนดวิธีแสดงข้อมูล ViewHolder
เป็น Wrapper ของ View
ที่มีเลย์เอาต์สำหรับแต่ละรายการในลิสต์ Adapter
จะสร้างออบเจ็กต์ ViewHolder
ตามที่จำเป็น รวมถึงตั้งค่าข้อมูลสําหรับมุมมองเหล่านั้นด้วย กระบวนการเชื่อมโยงมุมมองกับข้อมูลเรียกว่าการเชื่อมโยง
เมื่อกำหนดอะแดปเตอร์ คุณจะลบล้างเมธอดหลัก 3 รายการต่อไปนี้
onCreateViewHolder()
:RecyclerView
จะเรียกใช้เมธอดนี้ทุกครั้งที่จำเป็นต้องสร้างViewHolder
ใหม่ เมธอดจะสร้างและเริ่มต้นViewHolder
และView
ที่เชื่อมโยง แต่ไม่กรอกเนื้อหาของมุมมอง เนื่องจากViewHolder
ยังไม่ได้เชื่อมโยงกับข้อมูลใดๆonBindViewHolder()
:RecyclerView
เรียกใช้เมธอดนี้เพื่อเชื่อมโยงViewHolder
กับข้อมูล วิธีการจะดึงข้อมูลที่เหมาะสมและใช้ข้อมูลนั้นในการกรอกเลย์เอาต์ของวิวโฮลเดอร์ เช่น หากRecyclerView
แสดงรายการชื่อ วิธีการอาจค้นหาชื่อที่เหมาะสมในรายการและป้อนลงในวิดเจ็ตTextView
ของโฮลเดอร์มุมมองgetItemCount()
:RecyclerView
เรียกใช้เมธอดนี้เพื่อรับขนาดของชุดข้อมูล เช่น ในสมุดที่อยู่ ฟิลด์นี้อาจเป็นจํานวนที่อยู่ทั้งหมด RecyclerView ใช้ข้อมูลนี้เพื่อระบุว่าไม่มีรายการใดที่จะแสดงได้อีก
ต่อไปนี้คือตัวอย่างทั่วไปของอแดปเตอร์แบบง่ายที่มี ViewHolder
ที่ฝังอยู่ซึ่งแสดงรายการข้อมูล ในกรณีนี้ RecyclerView จะแสดงรายการองค์ประกอบข้อความแบบง่าย ระบบจะส่งอาร์เรย์สตริงที่มีข้อความสำหรับองค์ประกอบ ViewHolder
ไปยังอะแดปเตอร์
Kotlin
class CustomAdapter(private val dataSet: Array<String>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() { /** * Provide a reference to the type of views that you are using * (custom ViewHolder) */ class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val textView: TextView init { // Define click listener for the ViewHolder's View textView = view.findViewById(R.id.textView) } } // Create new views (invoked by the layout manager) override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder { // Create a new view, which defines the UI of the list item val view = LayoutInflater.from(viewGroup.context) .inflate(R.layout.text_row_item, viewGroup, false) return ViewHolder(view) } // Replace the contents of a view (invoked by the layout manager) override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { // Get element from your dataset at this position and replace the // contents of the view with that element viewHolder.textView.text = dataSet[position] } // Return the size of your dataset (invoked by the layout manager) override fun getItemCount() = dataSet.size }
Java
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> { private String[] localDataSet; /** * Provide a reference to the type of views that you are using * (custom ViewHolder) */ public static class ViewHolder extends RecyclerView.ViewHolder { private final TextView textView; public ViewHolder(View view) { super(view); // Define click listener for the ViewHolder's View textView = (TextView) view.findViewById(R.id.textView); } public TextView getTextView() { return textView; } } /** * Initialize the dataset of the Adapter * * @param dataSet String[] containing the data to populate views to be used * by RecyclerView */ public CustomAdapter(String[] dataSet) { localDataSet = dataSet; } // Create new views (invoked by the layout manager) @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { // Create a new view, which defines the UI of the list item View view = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.text_row_item, viewGroup, false); return new ViewHolder(view); } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(ViewHolder viewHolder, final int position) { // Get element from your dataset at this position and replace the // contents of the view with that element viewHolder.getTextView().setText(localDataSet[position]); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return localDataSet.length; } }
เค้าโครงของรายการมุมมองแต่ละรายการจะกำหนดไว้ในไฟล์เลย์เอาต์ XML ตามปกติ
ในกรณีนี้ แอปจะมีไฟล์ text_row_item.xml
ดังนี้
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:gravity="center_vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/element_text"/>
</FrameLayout>
ขั้นตอนถัดไป
ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้ RecyclerView
Kotlin
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val dataset = arrayOf("January", "February", "March") val customAdapter = CustomAdapter(dataset) val recyclerView: RecyclerView = findViewById(R.id.recycler_view) recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = customAdapter } }
Java
RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.layoutManager = new LinearLayoutManager(this) recyclerView.setAdapter(customAdapter);
นอกจากนี้ ไลบรารียังมีวิธีต่างๆ ในการปรับแต่งการใช้งานด้วย ดูข้อมูลเพิ่มเติมได้ที่การปรับแต่ง RecyclerView ขั้นสูง
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการทดสอบใน Android ได้ที่แหล่งข้อมูลต่อไปนี้