web-dev-qa-db-fra.com

Android: Comment implémenter viewpager et les vues dans un seul fichier XML

MISE À JOUR: Puis-je utiliser la disposition suivante pour implémenter 3 textviews dans Viewpager:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:orientation="vertical">

    <Android.support.v4.view.ViewPager
    Android:id="@+id/pager"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

       <TextView
          Android:layout_height="wrap_content"
          Android:layout_width="wrap_content"
          Android:text="view 1"/>
       <TextView
          Android:layout_height="wrap_content"
          Android:layout_width="wrap_content"
          Android:text="view 2"/>
       <TextView
          Android:layout_height="wrap_content"
          Android:layout_width="wrap_content"
          Android:text="view 3"/>

    </Android.support.v4.view.ViewPager>
</LinearLayout>

Je souhaite implémenter ViewPager pour ces 3 vues. et je veux avoir viewpager et ces 3 vues dans un seul fichier xml. Chaque page contient chaque textview. J'ai vu des exemples, mais chaque page a été implémentée à l'aide d'un fichier de présentation XML distinct.

Comment puis-je implémenter le viewpager pour ces 3 vues dans un seul fichier XML? Si possible, veuillez me fournir un exemple de code ou un exemple de code.

14
Dileep Perla

Comment puis-je implémenter le viewpager pour ces 3 vues dans un seul fichier XML?.

Désolé, mais ce n'est pas possible.

3
CommonsWare

Vous pouvez utiliser une seule disposition XML imbriquant les vues des enfants.

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical">

    <Android.support.v4.view.ViewPager
        Android:id="@+id/pager"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent">

        <LinearLayout
            Android:id="@+id/page_one"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:orientation="vertical" >
                    <TextView
                    Android:text="PAGE ONE IN"
                    Android:layout_width="match_parent"
                    Android:layout_height="match_parent"
                    Android:textColor="#fff"
                    Android:textSize="24dp"/>
        </LinearLayout>

        <LinearLayout
            Android:id="@+id/page_two"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:orientation="vertical" >
                    <TextView
                    Android:text="PAGE TWO IN"
                    Android:layout_width="match_parent"
                    Android:layout_height="match_parent"
                    Android:textColor="#fff"
                    Android:textSize="24dp"/>
        </LinearLayout>

    </Android.support.v4.view.ViewPager>

</LinearLayout>

MAIS ... vous devez également gérer cela avec un adaptateur. Ici, nous retournons l'ID de la vue trouvée sans gonfler aucune autre mise en page.

    class WizardPagerAdapter extends PagerAdapter {

        public Object instantiateItem(View collection, int position) {

            int resId = 0;
            switch (position) {
            case 0:
                resId = R.id.page_one;
                break;
            case 1:
                resId = R.id.page_two;
                break;
            }
            return findViewById(resId);
        }

        @Override
        public int getCount() {
            return 2;
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == ((View) arg1);
        }
    }



    // Set the ViewPager adapter
    WizardPagerAdapter adapter = new WizardPagerAdapter();
    ViewPager pager = (ViewPager) findViewById(R.id.pager);
    pager.setAdapter(adapter);

Ma question est ... Un gourou ici peut m'apprendre s'il est possible que ViewPager lise les enfants à partir de XML et construise automatiquement les pages sans utiliser instantiateItem ()?

49
jjalonso

c'est impossible. vous pouvez le faire comme ceux-ci

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.view.ViewPager
 xmlns:Android="http://schemas.Android.com/apk/res/Android"
 Android:id="@+id/pager"
 Android:layout_width="match_parent"
 Android:layout_height="match_parent" />

puis créez un fichier xml séparé et procédez comme ceci: pour exemple: je vais utiliser le nom de fichier xml qui est ios_frag.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:gravity="center"
Android:orientation="vertical" >
<TextView
    Android:id="@+id/textView"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:textSize="50sp"/>
 </LinearLayout>
2
user3074678

Juste si quelqu'un fait face au même problème, je l'ai résolu avec un adaptateur qui extrait les pages vues d'un groupe de vues arbitraire que vous lui transmettez.

    package com.packagename;

import Android.support.v4.view.PagerAdapter;
import Android.support.v4.view.ViewPager;
import Android.view.View;
import Android.view.ViewGroup;

import Java.util.ArrayList;
import Java.util.List;

public class ViewGroupPagerAdapter extends PagerAdapter {
    public ViewGroupPagerAdapter(ViewGroup viewGroup) {
        while (viewGroup.getChildCount() > 0) {
            views.add(viewGroup.getChildAt(0));
            viewGroup.removeViewAt(0);
        }
    }

    private List<View> views = new ArrayList<View>();

    @Override
    public Object instantiateItem(ViewGroup parent, int position) {
        View view = views.get(position);
        ViewPager.LayoutParams lp = new ViewPager.LayoutParams();
        lp.width = ViewPager.LayoutParams.FILL_PARENT;
        lp.height = ViewPager.LayoutParams.FILL_PARENT;
        view.setLayoutParams(lp);
        parent.addView(view);
        return view;
    }

    @Override
    public void destroyItem(ViewGroup parent, int position, Object object) {
        View view = (View) object;
        parent.removeView(view);
    }

    @Override
    public int getCount() {
        return views.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }
}

Usage:

ViewPager viewPager=findViewById(...); // Retrieve the view pager
viewPager.setAdapter(new ViewGroupPagerAdapter(findViewById(R.id.id_of_your_view_group_where_you_store_the_pages)));
1
Áron Lőrincz

Vous pouvez sous-classer ViewPager et remplacer onInflate.
De plus, vous aurez un aperçu de la première page de ViewPager dans l’éditeur de mises en page.
Toutes les vues sont conservées en mémoire. Par conséquent, pour des raisons de performances, vous ne devez l’utiliser que sur un petit nombre de pages. 

@Override protected void onFinishInflate() {
    int childCount = getChildCount();
    final List<View> pages = new ArrayList<>(childCount);
    for (int i = 0; i < childCount; i++) {
        View child = getChildAt(i);
        Class<?> clazz = child.getClass();
        if (clazz.getAnnotation(DecorView.class) == null) {
            pages.add(child);
        }
    }
    for (View page : pages) {
        removeView(page);
    }
    setAdapter(new PagerAdapter() {
        @Override public int getCount() {
            return pages.size();
        }

        @Override public Object instantiateItem(ViewGroup container, int position) {
            container.addView(pages.get(position));
            return position;
        }

        @Override public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView(pages.get((Integer)object));
        }

        @Override public boolean isViewFromObject(View view, Object object) {
            return pages.get((Integer)object) == view;
        }
    });
    super.onFinishInflate();
}
1
tango24

ajoutez ceci dans votre fichier de mise en page xml

<Android.support.v4.view.ViewPager 
    Android:id="@+id/view_pager"
    Android:layout_width="fill_parent"
    Android:layout_height="0dp"
    Android:layout_weight="1" />

créez 3 Fragments et ajoutez chaque TextView pour chaque fragment. Créez ensuite un adaptateur sous-classé PagerAdapter

Un bon exemple peut être trouvé ici

1
chip
    viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
    viewPager.setAdapter(new MyPagerAdapter(rootView));
    viewPager.setOffscreenPageLimit(3); //or whatever you like

ça le cache et ça se voit parfaitement.

0
Alp Altunel

Mettre à jour

Cette réponse indiquera une manière optimisée et gérée de définir les pages ViewPager dans la présentation.

Étape 1

Créez d’abord deux pages Layouts XML layout_page_1.xml et layout_page_2.xml.

Étape 2

Incluez maintenant toutes les mises en page dans votre mise en page parent ViewPager

<androidx.viewpager.widget.ViewPager
    Android:id="@+id/viewpager"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <include
        Android:id="@+id/page_one"
        layout="@layout/layout_page_1" />

    <include
        Android:id="@+id/page_two"
        layout="@layout/layout_page_2" />

</androidx.viewpager.widget.ViewPager>

Étape 3

Maintenant, à partir de votre code, configurez l'adaptateur en étapes simples

// find views by id
ViewPager viewPager = findViewById(R.id.viewpager);

CommonPagerAdapter adapter = new CommonPagerAdapter();

// insert page ids
adapter.insertViewId(R.id.page_one);
adapter.insertViewId(R.id.page_two);

// attach adapter to viewpager
viewPager.setAdapter(adapter);

C'est tout! Vous n'avez besoin que d'un adaptateur commun pour tous les ViewPagers.

CommonPagerAdapter.Java class

public class CommonPagerAdapter extends PagerAdapter {
    private List<Integer> pageIds = new ArrayList<>();

    public void insertViewId(@IdRes int pageId) {
        pageIds.add(pageId);
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        return container.findViewById(pageIds.get(position));
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View) object);
    }

    @Override
    public int getCount() {
        return pageIds.size();
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }
}

Note importante

Il vaut mieux utiliser des fragments plutôt que des vues. Vous devez créer des fragments et utiliser FragmentStatePagerAdapter pour gérer la pile, le cycle de vie et les états. Vous pouvez voir @cette réponse pour obtenir le code complet d'utilisation de FragmentStatePagerAdapter.

0
Khemraj