Le visualizzazioni a scorrimento ti consentono di spostarti tra le schermate gemelle, ad esempio le schede, con un gesto orizzontale del dito (scorrimento). Questo pattern di navigazione è definito anche paging orizzontale. Questo documento mostra come creare un layout delle schede con visualizzazioni a scorrimento per passare da una scheda all'altra, oltre a mostrare una barra dei titoli al posto delle schede.
Implementare le visualizzazioni a scorrimento
Puoi creare visualizzazioni a scorrimento utilizzando il
widget ViewPager
di AndroidX. Per utilizzare ViewPager
e le schede, aggiungi dipendenze in Viewpager
e nei componenti Material nel progetto.
Per configurare il layout con ViewPager
, aggiungi l'elemento <ViewPager>
al
layout XML. Ad esempio, se ogni pagina nella visualizzazione a scorrimento deve consumare l'intero layout, il layout sarà simile al seguente:
<androidx.viewpager.widget.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Per inserire visualizzazioni secondarie che rappresentano ogni pagina, collega questo layout a un elemento PagerAdapter
. Puoi scegliere tra due tipi di adattatori integrati:
FragmentPagerAdapter
: utilizza questa opzione per spostarti tra un numero ridotto e fisso di schermate di pari livello.FragmentStatePagerAdapter
: utilizza questa opzione quando ti sposti su un numero sconosciuto di pagine.FragmentStatePagerAdapter
ottimizza l'utilizzo della memoria distruggendo i frammenti man mano che l'utente esce.
Ecco un esempio di come utilizzare FragmentStatePagerAdapter
per scorrere una raccolta di Fragment
oggetti:
Kotlin
class CollectionDemoFragment : Fragment() { // When requested, this adapter returns a DemoObjectFragment, representing // an object in the collection. private lateinit var demoCollectionPagerAdapter: DemoCollectionPagerAdapter private lateinit var viewPager: ViewPager 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?) { demoCollectionPagerAdapter = DemoCollectionPagerAdapter(childFragmentManager) viewPager = view.findViewById(R.id.pager) viewPager.adapter = demoCollectionPagerAdapter } } // Since this is an object collection, use a FragmentStatePagerAdapter, not a // FragmentPagerAdapter. class DemoCollectionPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { override fun getCount(): Int = 100 override fun getItem(i: Int): Fragment { val fragment = DemoObjectFragment() fragment.arguments = Bundle().apply { // Our object is just an integer :-P putInt(ARG_OBJECT, i + 1) } return fragment } override fun getPageTitle(position: Int): CharSequence { return "OBJECT ${(position + 1)}" } } private const val ARG_OBJECT = "object" // Instances of this class are fragments representing a single object in your // 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. DemoCollectionPagerAdapter demoCollectionPagerAdapter; ViewPager 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) { demoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getChildFragmentManager()); viewPager = view.findViewById(R.id.pager); viewPager.setAdapter(demoCollectionPagerAdapter); } } // Since this is an object collection, use a FragmentStatePagerAdapter, not a // FragmentPagerAdapter. public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter { public DemoCollectionPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int i) { Fragment fragment = new DemoObjectFragment(); Bundle args = new Bundle(); // Our object is just an integer. args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1); fragment.setArguments(args); return fragment; } @Override public int getCount() { return 100; } @Override public CharSequence getPageTitle(int position) { return "OBJECT " + (position + 1); } } // Instances of this class are fragments representing a single object in your // collection. public class DemoObjectFragment extends Fragment { public static final String ARG_OBJECT = "object"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, 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))); } }
La seguente sezione mostra come aggiungere schede per facilitare la navigazione tra le pagine.
Aggiungere schede utilizzando TabLayout
Un elemento TabLayout
consente di visualizzare
le schede in orizzontale. Se utilizzato con un ViewPager
, un TabLayout
offre un'interfaccia familiare per la navigazione tra le pagine in una visualizzazione a scorrimento.
TabLayout
con quattro
schede.Per includere TabLayout
in un elemento ViewPager
, aggiungi un elemento <TabLayout>
all'interno
dell'elemento <ViewPager>
, come mostrato nell'esempio seguente:
<androidx.viewpager.widget.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.viewpager.widget.ViewPager>
Utilizza setupWithViewPager()
per collegare TabLayout
a ViewPager
, come mostrato nell'esempio seguente.
Le singole schede in TabLayout
vengono completate automaticamente con i titoli delle pagine dell'elemento PagerAdapter
.
Kotlin
class CollectionDemoFragment : Fragment() { ... override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val tabLayout = view.findViewById(R.id.tab_layout) tabLayout.setupWithViewPager(viewPager) } ... } class DemoCollectionPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { override fun getCount(): Int = 4 override fun getPageTitle(position: Int): CharSequence { return "OBJECT ${(position + 1)}" } ... }
Java
public class CollectionDemoFragment extends Fragment { ... @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { TabLayout tabLayout = view.findViewById(R.id.tab_layout); tabLayout.setupWithViewPager(viewPager); } ... } public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter { ... @Override public int getCount() { return 4; } @Override public CharSequence getPageTitle(int position) { return "OBJECT " + (position + 1); } ... }
Per ulteriori indicazioni sulla progettazione dei layout delle schede, consulta la documentazione di Material Design per le schede.