تتيح لك طرق عرض التمرير السريع التنقل بين الشاشات التابعة، مثل علامات التبويب، باستخدام إيماءة إصبع أفقية أو التمرير السريع. ويُشار إلى نمط التنقّل هذا أيضًا باسم التقسيم الأفقي إلى صفحات. يعلمك هذا الموضوع كيفية إنشاء تنسيق علامات التبويب بطرق عرض التمرير للتبديل بين علامات التبويب، إلى جانب كيفية إظهار شريط عناوين بدلاً من علامات التبويب.
تنفيذ طرق عرض التمرير السريع
يمكنك إنشاء طرق عرض التمرير السريع باستخدام التطبيق المصغّر
ViewPager2
في AndroidX.
لاستخدام ViewPager2 وعلامات التبويب، عليك إضافة تبعية إلى
ViewPager2 ومكوّنات المادة
إلى مشروعك.
لإعداد التنسيق باستخدام ViewPager2
، أضِف العنصر <ViewPager2>
إلى تنسيق XML. على سبيل المثال، إذا كانت كل صفحة في عرض التمرير يجب أن تستهلك
التنسيق بأكمله، يجب أن يبدو التخطيط كما يلي:
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
لإدراج طرق العرض الثانوية التي تمثّل كل صفحة، عليك ربط هذا التنسيق بالرمز FragmentStateAdapter
.
وإليك كيفية استخدامها للتمرير سريعًا عبر مجموعة من عناصر Fragment
:
Kotlin
class CollectionDemoFragment : Fragment() { // When requested, this adapter returns a DemoObjectFragment, // representing an object in the collection. private lateinit var demoCollectionAdapter: DemoCollectionAdapter private lateinit var viewPager: ViewPager2 override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.collection_demo, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { demoCollectionAdapter = DemoCollectionAdapter(this) viewPager = view.findViewById(R.id.pager) viewPager.adapter = demoCollectionAdapter } } class DemoCollectionAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) { override fun getItemCount(): Int = 100 override fun createFragment(position: Int): Fragment { // Return a NEW fragment instance in createFragment(int) val fragment = DemoObjectFragment() fragment.arguments = Bundle().apply { // Our object is just an integer :-P putInt(ARG_OBJECT, position + 1) } return fragment } } private const val ARG_OBJECT = "object" // Instances of this class are fragments representing a single // object in our collection. class DemoObjectFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return inflater.inflate(R.layout.fragment_collection_object, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { arguments?.takeIf { it.containsKey(ARG_OBJECT) }?.apply { val textView: TextView = view.findViewById(android.R.id.text1) textView.text = getInt(ARG_OBJECT).toString() } } }
Java
public class CollectionDemoFragment extends Fragment { // When requested, this adapter returns a DemoObjectFragment, // representing an object in the collection. DemoCollectionAdapter demoCollectionAdapter; ViewPager2 viewPager; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.collection_demo, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { demoCollectionAdapter = new DemoCollectionAdapter(this); viewPager = view.findViewById(R.id.pager); viewPager.setAdapter(demoCollectionAdapter); } } public class DemoCollectionAdapter extends FragmentStateAdapter { public DemoCollectionAdapter(Fragment fragment) { super(fragment); } @NonNull @Override public Fragment createFragment(int position) { // Return a NEW fragment instance in createFragment(int) Fragment fragment = new DemoObjectFragment(); Bundle args = new Bundle(); // Our object is just an integer :-P args.putInt(DemoObjectFragment.ARG_OBJECT, position + 1); fragment.setArguments(args); return fragment; } @Override public int getItemCount() { return 100; } } // Instances of this class are fragments representing a single // object in our collection. public class DemoObjectFragment extends Fragment { public static final String ARG_OBJECT = "object"; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_collection_object, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { Bundle args = getArguments(); ((TextView) view.findViewById(android.R.id.text1)) .setText(Integer.toString(args.getInt(ARG_OBJECT))); } }
توضّح الأقسام التالية كيفية إضافة علامات تبويب للمساعدة في تسهيل التنقل بين الصفحات.
إضافة علامات التبويب باستخدام TabLayout
توفّر علامة TabLayout
طريقة
لعرض علامات التبويب أفقيًا. وعند استخدام TabLayout
مع ViewPager2
، يمكن أن يوفّر واجهة مألوفة للتنقل بين الصفحات من خلال التمرير السريع.
الشكل 1: TabLayout
مع أربع علامات تبويب
لتضمين TabLayout
في ViewPager2
، أضِف عنصر <TabLayout>
أعلى العنصر <ViewPager2>
على النحو الموضّح أدناه:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
بعد ذلك، أنشئ TabLayoutMediator
لربط TabLayout
بالسمة ViewPager2
، وأرفقها على النحو التالي:
Kotlin
class CollectionDemoFragment : Fragment() { ... override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val tabLayout = view.findViewById(R.id.tab_layout) TabLayoutMediator(tabLayout, viewPager) { tab, position -> tab.text = "OBJECT ${(position + 1)}" }.attach() } ... }
Java
public class CollectionDemoFragment extends Fragment { ... @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { TabLayout tabLayout = view.findViewById(R.id.tab_layout); new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> tab.setText("OBJECT " + (position + 1)) ).attach(); } ... }
للحصول على إرشادات إضافية حول التصميم لتخطيطات علامات التبويب، اطّلع على مستندات التصميم المتعدد الأبعاد لعلامات التبويب.
مراجع إضافية
لمعرفة المزيد من المعلومات عن ViewPager2
، اطّلِع على المراجع الإضافية التالية.
عيّنات
- نماذج ViewPager2 على GitHub
الفيديوهات الطويلة
- تحويل الصفحة: نقل البيانات إلى ViewPager2 (مؤتمر Android Dev Summit لعام 2019)