إنشاء طرق عرض التمرير السريع باستخدام علامات التبويب باستخدام ViewPager2

تتيح لك طرق العرض بالتمرير السريع إمكانية التنقل بين الشاشات التابعة، مثل علامات التبويب، باستخدام إيماءة إصبع أفقية أو تمرير سريع. يشار أيضًا إلى نمط التنقل هذا إليه كترحيل أفقي. يعلّمك هذا الموضوع كيفية إنشاء تصميم علامة تبويب. مع طرق عرض التمرير السريع للتبديل بين علامات التبويب، إلى جانب كيفية عرض عنوان بدلاً من علامات التبويب.

تنفيذ طرق عرض التمرير السريع

يمكنك إنشاء طرق عرض التمرير السريع باستخدام التطبيق المصغّر ViewPager2. لاستخدام 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:

KotlinJava
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()
       
}
   
}
}
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 طريقة لعرض علامات التبويب أفقيًا. وعند استخدامها مع ViewPager2، يمكن أن توفر TabLayout واجهة مألوفة للتنقل بين الصفحات في العرض السريع.

الشكل 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، وإرفاقه على النحو التالي:

KotlinJava
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()
   
}
   
...
}
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، يُرجى الاطّلاع على المراجع الإضافية التالية.

نماذج

الفيديوهات