สร้างรายการแบบไดนามิกด้วย RecyclerView   เป็นส่วนหนึ่งของ Android Jetpack

ลองใช้วิธีเขียน
Jetpack Compose เป็นชุดเครื่องมือ UI ที่แนะนำสำหรับ Android ดูวิธีทำงานกับเลย์เอาต์ในเครื่องมือเขียน

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 คุณต้องทำสิ่งต่อไปนี้ ซึ่งอธิบายไว้อย่างละเอียดในส่วนต่อไปนี้

  1. เลือกลักษณะของรายการหรือตารางกริด โดยปกติแล้ว คุณจะใช้เครื่องมือจัดการเลย์เอาต์มาตรฐานของไลบรารี RecyclerView ได้

  2. ออกแบบลักษณะและลักษณะการทํางานขององค์ประกอบแต่ละรายการในรายการ ขยายคลาส ViewHolder ตามการออกแบบนี้ ViewHolder เวอร์ชันของคุณมีฟังก์ชันการทำงานทั้งหมดสำหรับรายการในลิสต์ ตัวยึดตำแหน่งมุมมองของคุณคือ View ที่ใช้ห่อหุ้ม RecyclerView และ RecyclerView จะจัดการมุมมองนั้น

  3. กําหนด 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 ได้ที่แหล่งข้อมูลต่อไปนี้

ตัวอย่างแอป