132 votes

Implémentation correcte de ViewPager2 dans Android

J'ai appris à connaître ViewPager2 et j'ai essayé de le mettre en œuvre, mais je n'ai pas trouvé d'exemple approprié.

Quelqu'un peut-il me dire comment je peux l'utiliser ?

Je cherche un usage correct, pas un exemple.

7 votes

Voici une explication et un exemple à vérifier : michaelevans.org/blog/2019/02/07/hands-on-with-viewpager2

3 votes

Ceux qui ont donné des votes serrés pour recommend or find a book, tool, software library, tutorial or other off-site resource Veuillez lire attentivement que je ne cherche pas d'exemple.

0 votes

Il existe un échantillon officiel : github.com/googlesamples/Android-viewpager2

265voto

Nilesh Rathod Points 34836

UPDATE 7

Vérifiez : Migrer de ViewPager vers ViewPager2

Vérifiez : Créer des vues glissantes avec des onglets en utilisant ViewPager2

MISE À JOUR 6

Vérifiez ma réponse si vous voulez mettre en œuvre le carrousel en utilisant View Pager2

MISE À JOUR 5

Comment utiliser TabLayout avec ViewPager2

CODE ÉCHANTILLON

Utiliser ci-dessous dependencies

implementation 'com.google.android.material:material:1.1.0-alpha08'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'

CODE ÉCHANTILLON

Mise en page XMl

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

        <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewpager"
            app:layout_anchor="@id/tabs"
            app:layout_anchorGravity="bottom"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
    />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Activité

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import com.google.android.material.tabs.TabLayoutMediator

import com.google.android.material.tabs.TabLayout

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

//        setSupportActionBar(toolbar)
        viewpager.adapter = AppViewPagerAdapter(supportFragmentManager, lifecycle)

        TabLayoutMediator(tabs, viewpager, object : TabLayoutMediator.OnConfigureTabCallback {
            override fun onConfigureTab(tab: TabLayout.Tab, position: Int) {
                // Styling each tab here
                tab.text = "Tab $position"
            }
        }).attach()

    }
}

SORTIE

TabLayout avec ViewPager2

De Docs

ViewPager2

Nouvelles fonctionnalités

  • Prise en charge de la mise en page de droite à gauche (RTL)
  • Soutien à l'orientation verticale
  • notifyDataSetChanged entièrement fonctionnel

Changements d'API

  • FragmentStateAdapter remplace FragmentStatePagerAdapter
  • RecyclerView.Adapter remplace PagerAdapter
  • registerOnPageChangeCallback remplace addPageChangeListener

CODE ÉCHANTILLON

ajouter les dernières dependencies para ViewPager2

implementation 'androidx.viewpager2:viewpager2:1.0.0-alpha01'

mise en page

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

activité

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;

import java.util.ArrayList;

public class MyActivity extends AppCompatActivity {

    ViewPager2 myViewPager2;
    MyAdapter MyAdapter;
    private ArrayList<String> arrayList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        myViewPager2 = findViewById(R.id.view_pager);

        arrayList.add("Item 1");
        arrayList.add("Item 2");
        arrayList.add("Item 3");
        arrayList.add("Item 4");
        arrayList.add("Item 5");

        MyAdapter = new MyAdapter(this, arrayList);

        myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);

        myViewPager2.setAdapter(MyAdapter);
    }
}

MonAdaptateur

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    private Context context;
    private ArrayList<String> arrayList = new ArrayList<>();

    public MyAdapter(Context context, ArrayList<String> arrayList) {
        this.context = context;
        this.arrayList = arrayList;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.tvName.setText(arrayList.get(position));
    }

    @Override
    public int getItemCount() {
        return arrayList.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tvName;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            tvName = itemView.findViewById(R.id.tvName);
        }
    }
}

Nouvelles fonctionnalités

nous devons maintenant utiliser ViewPager2.OnPageChangeCallback() pour obtenir l'événement Swipe de ViewPager2

CODE ÉCHANTILLON

    myViewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            super.onPageScrolled(position, positionOffset, positionOffsetPixels);
        }

        @Override
        public void onPageSelected(int position) {
            super.onPageSelected(position);

            Log.e("Selected_Page", String.valueOf(position));
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            super.onPageScrollStateChanged(state);
        }
    });

nous pouvons définir l'orientation en utilisant myViewPager2.setOrientation()

CODE ÉCHANTILLON

Para HORIZONTAL Orientation utiliser

myViewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);

Para VERTICAL Orientation utiliser

myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);

Nous pouvons utiliser notifyDataSetChanged comme nous l'utilisons dans RecyclerView.Adapter

EXEMPLE DE CODE pour ajouter un nouvel élément

    btnAdd.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            arrayList.add("New ITEM ADDED");
            MyAdapter.notifyDataSetChanged();
        }
    });

SAMPLE CODE pour supprimer un nouvel élément

    btnRemove.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            arrayList.remove(3);
            MyAdapter.notifyItemRemoved(3);
        }
    });

UPDATE

Essayez ceci si vous voulez utiliser Fragment con ViewPager2

Créez d'abord un ViewPagerFragmentAdapter qui étend la classe FragmentStateAdapter

import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager2.adapter.FragmentStateAdapter;

public class ViewPagerFragmentAdapter extends FragmentStateAdapter {

    private ArrayList<Fragment> arrayList = new ArrayList<>();

    public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return arrayList.get(position);
    }

    public void addFragment(Fragment fragment) {
        arrayList.add(fragment);
    }

    @Override
    public int getItemCount() {
        return arrayList.size();
    }
}

Maintenant, utilisez comme ceci dans votre activité

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import neel.com.bottomappbar.R;

public class MainActivity extends AppCompatActivity {

    ViewPager2 myViewPager2;
    ViewPagerFragmentAdapter myAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        myViewPager2 = findViewById(R.id.view_pager);

        myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager());

        // add Fragments in your ViewPagerFragmentAdapter class
        myAdapter.addFragment(new FragmentOne());
        myAdapter.addFragment(new Fragmenttwo());
        myAdapter.addFragment(new FragmentThree());

        // set Orientation in your ViewPager2
        myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);

        myViewPager2.setAdapter(myAdapter);

    }

}

Pour plus d'informations, consultez ce site

MISE À JOUR 2

Version 1.0.0-alpha02

Nouvelles fonctionnalités

  • Possibilité de désactiver la saisie par l'utilisateur ( setUserInputEnabled , isUserInputEnabled )

Changements d'API

  • ViewPager2 classe finale

Correction de bogues

  • FragmentStateAdapter corrections de stabilité

EXEMPLE DE CODE pour désactiver le swiping dans le viewpager2

myViewPager2.setUserInputEnabled(false);// SAMPLE CODE to disable swiping in viewpager2

myViewPager2.setUserInputEnabled(true);//SAMPLE CODE to enable swiping in viewpager2

MISE À JOUR 3

Version 1.0.0-alpha03

Nouvelles fonctionnalités

  • Possibilité de faire défiler ViewPager2 de manière programmatique : fakeDragBy(offsetPx) .

Changements d'API

  • FragmentStateAdapter exige désormais un Lifecycle objet. Deux constructeurs utilitaires ajoutés pour l'obtenir de l'hôte FragmentActivity ou le Fragment hôte

CODE ÉCHANTILLON

ViewPagerFragmentAdapter

import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;

public class ViewPagerFragmentAdapter extends FragmentStateAdapter {

    private ArrayList<Fragment> arrayList = new ArrayList<>();

    public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
        super(fragmentManager, lifecycle);
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return arrayList.get(position);
    }

    public void addFragment(Fragment fragment) {
        arrayList.add(fragment);
    }

    @Override
    public int getItemCount() {
        return arrayList.size();
    }
}

Code de l'activité principale

import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import neel.com.bottomappbar.R;

public class MainActivity extends AppCompatActivity {

    ViewPager2 myViewPager2;
    ViewPagerFragmentAdapter myAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        myViewPager2=findViewById(R.id.view_pager);
        myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager(), getLifecycle());

        // add Fragments in your ViewPagerFragmentAdapter class
        myAdapter.addFragment(new FragmentOne());
        myAdapter.addFragment(new Fragmenttwo());
        myAdapter.addFragment(new FragmentThree());

        myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);

        myViewPager2.setAdapter(myAdapter);
    }
}

UPDATE 4

Version 1.0.0-alpha05 Nouvelles fonctionnalités

  • ItemDecorator introduit avec un comportement cohérent avec RecyclerView .
  • MarginPageTransformer introduit pour permettre de créer de l'espace entre les pages (en dehors de l'encart de page).
  • CompositePageTransformer introduit pour permettre de combiner plusieurs PageTransformers

Changements d'API

  • FragmentStateAdapter#getItem a été renommée en FragmentStateAdapter#createFragment - Le nom de la méthode précédente s'est avéré être une source de bogues dans le passé.
  • OFFSCREEN_PAGE_LIMIT_DEFAULT est passée de 0 à -1. Il n'est pas nécessaire de modifier le code client si le OFFSCREEN_PAGE_LIMIT_DEFAULTconstant utilisé.

CODE ÉCHANTILLON

Code d'activité

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.MarginPageTransformer;
import androidx.viewpager2.widget.ViewPager2;
import neel.com.bottomappbar.R;

public class MainActivity extends AppCompatActivity {

    ViewPager2 myViewPager2;
    ViewPagerFragmentAdapter myAdapter;
    private ArrayList<Fragment> arrayList = new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        myViewPager2 = findViewById(R.id.myViewPager2);

        // add Fragments in your ViewPagerFragmentAdapter class
        arrayList.add(new FragmentOne());
        arrayList.add(new Fragmenttwo());
        arrayList.add(new FragmentThree());

        myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager(), getLifecycle());
        // set Orientation in your ViewPager2
        myViewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);

        myViewPager2.setAdapter(myAdapter);

        myViewPager2.setPageTransformer(new MarginPageTransformer(1500));

    }
}

ViewPagerFragmentAdapter

import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;

public class ViewPagerFragmentAdapter extends FragmentStateAdapter {

    private ArrayList<Fragment> arrayList = new ArrayList<>();

    public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
        super(fragmentManager, lifecycle);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        switch (position) {
            case 0:
                return new FragmentOne();
            case 1:
                return new Fragmenttwo();
            case 2:
                return new FragmentThree();

        }
        return null;
    }

    @Override
    public int getItemCount() {
        return 3;
    }
}

29 votes

Il semble que je doive faire un billet de blog :D

1 votes

Génial, je n'ai pas eu le temps de rédiger un billet mais je le ferai certainement.

0 votes

@PratikButani nous avons de nouvelles mises à jour pour ViewPager2 en utilisant Version 1.0.0-alpha02

11voto

user158 Points 592

En fait, il existe maintenant un dépôt d'échantillons officiel pour ViewPager2 (lien ci-dessous).

Le repo contient les échantillons suivants (Citation du readme du repo ci-dessous)

Échantillons

  • ViewPager2 with Views - montre comment configurer un ViewPager2 avec des Views comme pages
  • ViewPager2 with Fragments - montre comment configurer un ViewPager2 avec des fragments comme pages.
  • ViewPager2 avec une collection mutable (Views) - Démonstration de l'utilisation de ViewPager2 avec des Views comme pages et des mutations dans un adaptateur de pages.
  • ViewPager2 avec une collection mutable (Fragments) - démontre l'utilisation de ViewPager2 avec des Fragments comme pages, et des mutations dans un adaptateur de page
  • ViewPager2 avec un TabLayout (Views) - montre comment configurer un ViewPager2 avec des Views comme pages, et le lier à un TabLayout.

Exemple simple de ViewPager2 avec Fragments en Kotlin

activité_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".MainActivity">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/pager2_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

</LinearLayout>

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val viewPager2 = findViewById<ViewPager2>(R.id.pager2_container)

        val fragmentList = arrayListOf(
            FirstFragment.newInstance(),
            SecondFragment.newInstance(),
            ThirdFragment.newInstance()
        )
        viewPager2.adapter = ViewPagerAdapter(this, fragmentList)
   }
}

FirstFragment.kt ( SecondFragment.kt y ThirdFragment.kt ressemble à FirstFragment.kt )

class FirstFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_first, container, false)
    }

    companion object{
        fun newInstance() = FirstFragment()
    }
}

ViewPagerAdapter.kt

class ViewPagerAdapter(fa:FragmentActivity, private val fragments:ArrayList<Fragment>): FragmentStateAdapter(fa) {

    override fun getItemCount(): Int = fragments.size

    override fun createFragment(position: Int): Fragment = fragments[position]

}

Quelques autres ressources utiles :

0 votes

Comment pouvons-nous utiliser ce type d'implémentation avec ViewBinding ?

0 votes

@MaulikDodia rien de spécial n'est nécessaire utilisez comme d'habitude, s'il vous plaît voir les docs : developer.Android.com/topic/libraries/view-binding

0 votes

Je vais en référer au médecin. Merci !

6voto

Sushil Kumar Points 4456

Utilisation de ViewPager2 dans Android

Comme mentionné sur Site du développeur

Changements d'API

FragmentStateAdapter remplace FragmentStatePagerAdapter

RecyclerView.Adapter remplace PagerAdapter

registerOnPageChangeCallback remplace addPageChangeListener

En termes simples, ils font fonctionner l'adaptateur View Pager comme l'adaptateur Recycle View.

Note : - Nous n'avons pas besoin d'utiliser le fragment dans le View Pager 2. Il dépend entièrement de RecyclerView.Adapter inflate layout.

Voici un exemple de dépôt gitHub Lien

Exemple:-

MainActivity.class

public class MainActivity extends AppCompatActivity {

    private ViewPager2 mPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getSupportActionBar().setTitle("View Pager 2");
        mPager = findViewById(R.id.pager);
        mPager.setAdapter(new MyViewPagerAdapter(this));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (R.id.change == item.getItemId()) {
            mPager.setOrientation(mPager.getOrientation() != ViewPager2.ORIENTATION_VERTICAL ? ViewPager2.ORIENTATION_VERTICAL : ViewPager2.ORIENTATION_HORIZONTAL);
        }
        return super.onOptionsItemSelected(item);
    }
}

activité_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.constraint.ConstraintLayout>

MyViewPagerAdapter.class

public class MyViewPagerAdapter extends RecyclerView.Adapter<MyHolder> {

    private Context context;

    public MyViewPagerAdapter(Context context) {
        this.context=context;
    }

    @NonNull
    @Override
    public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new MyHolder(LayoutInflater.from(context).inflate(R.layout.cell_item, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull MyHolder holder, int position) {
      holder.mText.setText("Page "+(position+1));
    }

    @Override
    public int getItemCount() {
        return 10;
    }
}

cell_item.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="Page 1"
        android:textSize="20sp" />

</android.support.constraint.ConstraintLayout>

MonDossier.classe

class MyHolder extends RecyclerView.ViewHolder {

    public TextView mText;

    public MyHolder(@NonNull View itemView) {
        super(itemView);
        mText = itemView.findViewById(R.id.text);
    }
}

sortie :

enter image description here

0 votes

Ne peut-on pas utiliser ViewPager2 avec des fragments ?

0 votes

@ysfcyln oui vous pouvez utiliser Fragment con ViewPager2 veuillez vérifier ma réponse ci-dessus J'ai ajouté un exemple de code pour How use Fragment with ViewPager2

0 votes

Merci, mais le référentiel est supprimé.

6voto

Voici ce que j'ai fait pour implémenter ViewPager2 avec TabLayout avec 3 Fragment full Examble :

La mise en page contient ViewPager2 con TabLayout :

 <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/include3">

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:background="@color/colorPrimary"
            app:tabTextColor="@color/tab_dismiss_color"
            app:tabSelectedTextColor="@color/green"
            android:layout_height="wrap_content" />

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_gravity="bottom"
            android:background="#e4e4e4" />

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    </LinearLayout>

init ViewPager2 et définir le nom des onglets :

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_report);
        ButterKnife.bind(this);
        actionBarTitleId.setText(R.string.reports);

        viewPager.setAdapter(new ViewPagerAdapter(this));

        new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
            switch (position) {
                case 0:
                    tab.setText(R.string.financial_duty_str);
                    break;
                case 1:
                    tab.setText(R.string.financial_unpaid_str);
                    break;
                case 2:
                    tab.setText(R.string.financial_paid_str);
                    break;

            }
        }).attach();

    }

ViewPager2 adaptateur :

public class ViewPagerAdapter extends FragmentStateAdapter {

    public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        switch (position) {
            case 0:
                return new FinancialFragment();
            case 1:
                return new FinancialUnPaidFragment();
            case 2:
                return new FinancialPaidFragment();
            default:
                return null;

        }
    }

    @Override
    public int getItemCount() {
        return 3;
    }

dépendance utilisée :

implementation "androidx.viewpager2:viewpager2:1.0.0"
implementation 'com.google.android.material:material:1.1.0-alpha10'

0 votes

Comment avez-vous résolu le problème du passage d'un onglet à l'autre ? Par exemple, lorsque je choisis 1, 1 et 2 sont chargés. D'une certaine manière, on passe de 1 à 2...

2voto

Thracian Points 1602

Comment l'utiliser expliqué très clairement. Permettez-moi de donner de petits conseils et détails très cruciaux sur ViewPager2, surtout s'il se trouve à l'intérieur d'un fragment, sur la façon d'éviter les fuites de mémoire.

  1. N'utilisez pas le constructeur qui prend le fragment surtout si vous utilisez TabLayout .

    public FragmentStateAdapter(@NonNull Fragment fragment) {
        this(fragment.getChildFragmentManager(), fragment.getLifecycle());
    }

car il y a un risque de fuite de mémoire comme décrit aquí

utilisez plutôt celui qui prend FragmentManager et LifeCycle. Et n'envoyez pas lifeCycle du fragment comme argument, utilisez viewLifeCycleOwner parce que viewLifeCycleOwner représente le cycle de vie du fragment. view .

 class NavigableFragmentStateAdapter(
    fragmentManager: FragmentManager,
    lifecycle: Lifecycle
) : FragmentStateAdapter(fragmentManager, lifecycle) {

}

et définir l'adaptateur avec dans onCreateView

viewPager.adapter =
            NavigableFragmentStateAdapter(childFragmentManager, viewLifecycleOwner.lifecycle)
  1. Si vous utilisez TabLayout lorsque ViewPager2 est à l'intérieur d'un fragment, n'oubliez pas de détacher TabLayout et de définir l'adaptateur de ViewPager2 en tant que

détacher TabLayoutMediator car il provoque des fuites de mémoire lorsqu'il est dans un fragment

https://stackoverflow.com/questions/61779776/leak-canary-detects-memory-leaks-for-tablayout-with-viewpager2

ViewPager2 à l'intérieur d'un fragment fuit après le remplacement du fragment dans lequel il se trouve par Navigation Component naviguer

TabLayoutMediator(tabLayout, viewPager2, tabConfigurationStrategy).detach()     
viewPager2.adapter = null

à l'intérieur de onDestroyView méthode des fragments

  1. Si vous souhaitez utiliser des pages de ViewPager comme navHostFragment avec des composants de navigation pour revenir aux fragments enfants enregistrer FragmentTransactionCallback dans FragmentStateAdapter comme

    private val fragmentTransactionCallback =
        object : FragmentStateAdapter.FragmentTransactionCallback() {
            override fun onFragmentMaxLifecyclePreUpdated(
                fragment: Fragment,
                maxLifecycleState: Lifecycle.State
            ) = if (maxLifecycleState == Lifecycle.State.RESUMED) {
    
                // This fragment is becoming the active Fragment - set it to
                // the primary navigation fragment in the OnPostEventListener
                OnPostEventListener {
                    fragment.parentFragmentManager.commitNow {
                        setPrimaryNavigationFragment(fragment)
                    }
                }
            } else {
                super.onFragmentMaxLifecyclePreUpdated(fragment, maxLifecycleState)
            }
        }
    
    init {
        // Add a FragmentTransactionCallback to handle changing
        // the primary navigation fragment
        registerFragmentTransactionCallback(fragmentTransactionCallback)
    }

Par ailleurs, si vous souhaitez voir quelques exemples d'utilisation de ViewPager2 avec des composants de navigation, des modules de fonctionnalités dynamiques et la combinaison avec BottomNavigationView, vous pouvez consulter les didacticiels suivants dans ce repo github.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X