لیست های پویا را با RecyclerView بخشی از Android Jetpack ایجاد کنید.
RecyclerView نمایش کارآمد مجموعه های بزرگ داده را آسان می کند. شما داده ها را تهیه می کنید و نحوه ظاهر هر آیتم را تعریف می کنید، و کتابخانه RecyclerView به صورت پویا عناصر را در صورت نیاز ایجاد می کند.
همانطور که از نام آن پیداست، RecyclerView آن عناصر را بازیافت می کند . هنگامی که یک مورد از صفحه خارج می شود، RecyclerView نمای آن را از بین نمی برد. در عوض، RecyclerView از نما برای موارد جدیدی که روی صفحه اسکرول شده اند، استفاده مجدد می کند. RecyclerView عملکرد و پاسخگویی برنامه شما را بهبود می بخشد و مصرف انرژی را کاهش می دهد.
کلاس های کلیدی
چندین کلاس با هم کار می کنند تا لیست پویا شما را بسازند.
RecyclerViewViewGroupاست که حاوی نماهای مربوط به داده های شما است. این خود یک نما است، بنابراینRecyclerViewبه شیوهای که هر عنصر رابط کاربری دیگری را اضافه میکنید به طرحبندی خود اضافه میکنید.هر عنصر جداگانه در لیست توسط یک شی نگهدارنده view تعریف می شود. هنگامی که نگهدارنده view ایجاد می شود، هیچ داده ای مرتبط با آن ندارد. پس از ایجاد view holder،
RecyclerViewآن را به داده های خود متصل می کند . شما دارنده view را با گسترشRecyclerView.ViewHolderتعریف می کنید.RecyclerViewنماها را درخواست میکند و نماها را با فراخوانی روشها در آداپتور به دادههای آنها متصل میکند. شما آداپتور را با گسترشRecyclerView.Adapterتعریف می کنید.مدیر چیدمان عناصر فردی را در لیست شما مرتب می کند. میتوانید از یکی از مدیران طرحبندی ارائه شده توسط کتابخانه RecyclerView استفاده کنید، یا میتوانید خودتان را تعریف کنید. مدیران Layout همگی بر اساس کلاس انتزاعی
LayoutManagerکتابخانه هستند.
در برنامه نمونه RecyclerView (Kotlin) یا RecyclerView نمونه (جاوا) میتوانید ببینید که چگونه همه قطعات با هم قرار میگیرند.
مراحل پیاده سازی RecyclerView شما
اگر می خواهید از RecyclerView استفاده کنید، چند کار وجود دارد که باید انجام دهید. در بخش های بعدی به تفصیل توضیح داده شده اند.
تصمیم بگیرید که فهرست یا شبکه چگونه به نظر می رسد. معمولاً میتوانید از یکی از مدیران طرحبندی استاندارد کتابخانه RecyclerView استفاده کنید.
نحوه ظاهر و رفتار هر عنصر در لیست را طراحی کنید. بر اساس این طراحی، کلاس
ViewHolderرا گسترش دهید. نسخهViewHolderشما تمام عملکردها را برای موارد لیست شما فراهم می کند. دارنده نمای شما یک بسته بندی در اطراف یکViewاست و آن نما توسطRecyclerViewمدیریت می شود.Adapterرا تعریف کنید که داده های شما را با نماهایViewHolderمرتبط می کند.
همچنین گزینه های سفارشی سازی پیشرفته ای وجود دارد که به شما امکان می دهد RecyclerView خود را مطابق با نیازهای دقیق خود تنظیم کنید.
چیدمان خود را برنامه ریزی کنید
موارد موجود در RecyclerView شما توسط یک کلاس LayoutManager مرتب شده اند. کتابخانه RecyclerView سه مدیر طرحبندی را ارائه میکند که رایجترین موقعیتهای چیدمان را مدیریت میکنند:
-
LinearLayoutManagerموارد را در یک لیست تک بعدی مرتب می کند. -
GridLayoutManagerموارد را در یک شبکه دو بعدی مرتب می کند:- اگر شبکه به صورت عمودی مرتب شده باشد،
GridLayoutManagerسعی می کند تمام عناصر هر سطر دارای عرض و ارتفاع یکسان باشند، اما ردیف های مختلف می توانند ارتفاع های متفاوتی داشته باشند. - اگر گرید به صورت افقی چیده شده باشد،
GridLayoutManagerسعی می کند تمام عناصر هر ستون دارای عرض و ارتفاع یکسان باشند، اما ستون های مختلف می توانند عرض های متفاوتی داشته باشند.
- اگر شبکه به صورت عمودی مرتب شده باشد،
-
StaggeredGridLayoutManagerشبیهGridLayoutManagerاست، اما نیازی به این ندارد که موارد در یک ردیف دارای ارتفاع یکسان (برای شبکههای عمودی) یا موارد در همان ستون دارای عرض یکسان (برای شبکههای افقی) باشند. نتیجه این است که اقلام در یک سطر یا ستون می توانند در نهایت نسبت به یکدیگر افست شوند.
همچنین باید چیدمان تک تک آیتم ها را طراحی کنید. همانطور که در بخش بعدی توضیح داده شد، هنگام طراحی نگهدارنده view به این طرح نیاز دارید.
آداپتور و ویو نگهدارنده خود را پیاده سازی کنید
هنگامی که طرح خود را تعیین کردید، باید Adapter و ViewHolder خود را پیاده سازی کنید. این دو کلاس با هم کار می کنند تا نحوه نمایش داده های شما را مشخص کنند. ViewHolder یک بسته بندی در اطراف یک View است که حاوی طرح بندی برای یک آیتم جداگانه در لیست است. Adapter در صورت نیاز اشیاء ViewHolder را ایجاد می کند و همچنین داده ها را برای آن نماها تنظیم می کند. فرآیند مرتبط کردن نماها با دادههای آنها، الزام آور نامیده میشود.
هنگامی که آداپتور خود را تعریف می کنید، سه روش کلیدی را نادیده می گیرید:
onCreateViewHolder():RecyclerViewهر زمان که نیاز به ایجادViewHolderجدید داشته باشد این متد را فراخوانی می کند. این روشViewHolderوViewمربوط به آن را ایجاد و مقداردهی اولیه می کند، اما محتویات view را پر نمی کند—ViewHolderهنوز به داده های خاصی متصل نشده است.onBindViewHolder():RecyclerViewاین متد را برای مرتبط ساختنViewHolderبا داده ها فراخوانی می کند. این روش دادههای مناسب را واکشی میکند و از دادهها برای پر کردن طرحبندی دارنده view استفاده میکند. برای مثال، اگرRecyclerViewفهرستی از نامها را نمایش میدهد، این روش ممکن است نام مناسب را در لیست پیدا کند و ویجتTextViewدارنده view را پر کند.getItemCount():RecyclerViewاین متد را برای بدست آوردن اندازه مجموعه داده فراخوانی می کند. برای مثال، در یک برنامه دفترچه آدرس، این ممکن است تعداد کل آدرسها باشد. RecyclerView از این برای تعیین اینکه چه زمانی دیگر آیتم قابل نمایشی وجود ندارد استفاده می کند.
در اینجا یک مثال معمولی از یک آداپتور ساده با ViewHolder تو در تو است که لیستی از داده ها را نمایش می دهد. در این مورد، RecyclerView یک لیست ساده از عناصر متنی را نمایش می دهد. به آداپتور آرایه ای از رشته های حاوی متن برای عناصر ViewHolder ارسال می شود.
کاتلین
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 }
جاوا
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; } }
طرح بندی برای هر آیتم view طبق معمول در یک فایل طرح بندی 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 استفاده کنید.
کاتلین
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 } }
جاوا
RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.layoutManager = new LinearLayoutManager(this) recyclerView.setAdapter(customAdapter);
این کتابخانه همچنین راه های زیادی برای سفارشی سازی پیاده سازی شما ارائه می دهد. برای اطلاعات بیشتر، به سفارشیسازی Advanced RecyclerView مراجعه کنید.
نمایش لبه به لبه را فعال کنید
برای فعال کردن صفحه نمایش لبه به لبه برای RecyclerView این مراحل را دنبال کنید:
- با فراخوانی
enableEdgeToEdge()یک صفحه نمایش لبه به لبه سازگار با عقب تنظیم کنید. - اگر موارد لیست در ابتدا با نوارهای سیستم همپوشانی دارند، در
RecyclerViewاز موارد داخلی استفاده کنید. می توانید این کار را با تنظیمandroid:fitsSystemWindowsرویtrueیا با استفاده ازViewCompat.setOnApplyWindowInsetsListenerانجام دهید. - با تنظیم
android:clipToPaddingرویfalseدرRecyclerView، به موارد فهرست اجازه دهید هنگام پیمایش زیر نوارهای سیستم کشیده شوند.
ویدیوی زیر یک RecyclerView با صفحه نمایش لبه به لبه غیرفعال (چپ) و فعال (راست) نشان می دهد:
نمونه کد درج شده:
کاتلین
ViewCompat.setOnApplyWindowInsetsListener( findViewById(R.id.my_recycler_view) ) { v, insets -> val innerPadding = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() // If using EditText, also add // "or WindowInsetsCompat.Type.ime()" to // maintain focus when opening the IME ) v.setPadding( innerPadding.left, innerPadding.top, innerPadding.right, innerPadding.bottom) insets }
جاوا
ViewCompat.setOnApplyWindowInsetsListener( activity.findViewById(R.id.my_recycler_view), (v, insets) -> { Insets innerPadding = insets.getInsets( WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() // If using EditText, also add // "| WindowInsetsCompat.Type.ime()" to // maintain focus when opening the IME ); v.setPadding( innerPadding.left, innerPadding.top, innerPadding.right, innerPadding.bottom ); return insets; } );
RecyclerView XML:
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="match_parent" />
منابع اضافی
برای اطلاعات بیشتر در مورد تست در اندروید، به منابع زیر مراجعه کنید.
