web-dev-qa-db-fra.com

Android ViewPager avec les points du bas

Je souhaite ajouter 3 points en bas à mon ViewPager, comme ceci.

3 bottom dots3 bottom dots3 bottom dots

J'utilise FragmentActivity et la bibliothèque de support ViewPager.

158
Kfir Guy

Pas besoin de beaucoup de code.

Vous pouvez faire tout cela sans trop coder en utilisant seulement viewpager avec tablayout.

Votre mise en page principale:

<RelativeLayout
   xmlns:Android="http://schemas.Android.com/apk/res/Android"
   xmlns:app="http://schemas.Android.com/apk/res-auto"
   Android:layout_width="match_parent"
   Android:layout_height="wrap_content">

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

   </Android.support.v4.view.ViewPager>
   <Android.support.design.widget.TabLayout
       Android:id="@+id/tabDots"
       Android:layout_alignParentBottom="true"
       Android:layout_width="match_parent"
       Android:layout_height="wrap_content"
       app:tabBackground="@drawable/tab_selector"
       app:tabGravity="center"
       app:tabIndicatorHeight="0dp"/>
</RelativeLayout>

Branchez votre inactivité ou fragment d’éléments de l’UI comme suit:

Code Java:

mImageViewPager = (ViewPager) findViewById(R.id.pager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabDots);
tabLayout.setupWithViewPager(mImageViewPager, true);

Ça y est, vous êtes prêt à partir.

Vous devrez créer le fichier de ressources XML suivant dans le dossier pouvant être dessiné .

tab_indicator_selected.xml

<?xml version="1.0" encoding="utf-8"?>
<shape
    Android:innerRadius="0dp"
    Android:shape="oval"
    Android:thickness="4dp"
    Android:useLevel="false"
    xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <solid Android:color="@color/colorAccent"/>
</shape>

tab_indicator_default.xml

<?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:innerRadius="0dp"
            Android:shape="oval"
            Android:thickness="2dp"
            Android:useLevel="false">
            <solid Android:color="@Android:color/darker_gray"/>
    </shape>

tab_selector.xml

 <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item Android:drawable="@drawable/tab_indicator_selected"
          Android:state_selected="true"/>

    <item Android:drawable="@drawable/tab_indicator_default"/>
</selector>

Se sentir aussi paresseux que je suis? Eh bien, tout le code ci-dessus est converti en une bibliothèque! Utilisation Ajoutez ce qui suit dans votre titre: implementation 'com.chabbal:slidingdotsplash:1.0.2' Ajoutez ce qui suit à votre mise en page Activité ou Fragment.

<com.chabbal.slidingdotsplash.SlidingSplashView
        Android:id="@+id/splash"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:imageResources="@array/img_id_arr"/>

Créez un tableau entier dans strings.xml par ex.

<integer-array name="img_id_arr">
   <item>@drawable/img1</item>
   <item>@drawable/img2</item>
   <item>@drawable/img3</item>
   <item>@drawable/img4</item>
</integer-array>

Fait! Extra pour écouter les changements de page, utilisez addOnPageChangeListener(listener); Github lien .

314
Juni
viewPager.addOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {

                switch (position) {
    case 0:
        img_page1.setImageResource(R.drawable.dot_selected);
        img_page2.setImageResource(R.drawable.dot);
        img_page3.setImageResource(R.drawable.dot);
        img_page4.setImageResource(R.drawable.dot);
        break;

    case 1:
        img_page1.setImageResource(R.drawable.dot);
        img_page2.setImageResource(R.drawable.dot_selected);
        img_page3.setImageResource(R.drawable.dot);
        img_page4.setImageResource(R.drawable.dot);
        break;

    case 2:
        img_page1.setImageResource(R.drawable.dot);
        img_page2.setImageResource(R.drawable.dot);
        img_page3.setImageResource(R.drawable.dot_selected);
        img_page4.setImageResource(R.drawable.dot);
        break;

    case 3:
        img_page1.setImageResource(R.drawable.dot);
        img_page2.setImageResource(R.drawable.dot);
        img_page3.setImageResource(R.drawable.dot);
        img_page4.setImageResource(R.drawable.dot_selected);
        break;

    default:
        break;
    }


            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {

            }

            @Override
            public void onPageScrollStateChanged(int arg0) {

            }
        });
37
kapil thadani

Ma solution artisanale:

Dans la mise en page:

<LinearLayout
        Android:orientation="horizontal"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:id="@+id/dots"
        />

Et dans l'activité

private final static int NUM_PAGES = 5;
private ViewPager mViewPager;
private List<ImageView> dots;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...
    addDots();
}

public void addDots() {
    dots = new ArrayList<>();
    LinearLayout dotsLayout = (LinearLayout)findViewById(R.id.dots);

    for(int i = 0; i < NUM_PAGES; i++) {
        ImageView dot = new ImageView(this);
        dot.setImageDrawable(getResources().getDrawable(R.drawable.pager_dot_not_selected));

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );
        dotsLayout.addView(dot, params);

        dots.add(dot);
    }

    mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {
            selectDot(position);
        }

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

public void selectDot(int idx) {
    Resources res = getResources();
    for(int i = 0; i < NUM_PAGES; i++) {
        int drawableId = (i==idx)?(R.drawable.pager_dot_selected):(R.drawable.pager_dot_not_selected);
        Drawable drawable = res.getDrawable(drawableId);
        dots.get(i).setImageDrawable(drawable);
    }
}
35

J'ai créé une bibliothèque pour répondre à la nécessité d'un indicateur de page dans ViewPager. Ma bibliothèque contient une vue appelée DotIndicator. Pour utiliser ma bibliothèque, ajoutez compile 'com.matthew-tamlin:sliding-intro-screen:3.2.0' à votre fichier de construction Gradle.

La vue peut être ajoutée à votre mise en page en ajoutant les éléments suivants:

    <com.matthewtamlin.sliding_intro_screen_library.indicators.DotIndicator
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            app:numberOfDots=YOUR_INT_HERE
            app:selectedDotIndex=YOUR_INT_HERE/>

Le code ci-dessus reproduit parfaitement la fonctionnalité des points sur l'écran d'accueil de Google Launcher. Toutefois, si vous souhaitez le personnaliser davantage, vous pouvez ajouter les attributs suivants:

  • app:unselectedDotDiameter et app:selectedDotDiameter pour régler les diamètres des points
  • app:unselectedDotColor et app:selectedDotColor pour définir les couleurs des points
  • app:spacingBetweenDots pour changer la distance entre les points
  • app:dotTransitionDuration pour régler l'heure de l'animation du changement de petit à grand (et de retour)

De plus, la vue peut être créée par programme en utilisant:

DotIndicator indicator = new DotIndicator(context);

Il existe des méthodes pour modifier les propriétés, similaires aux attributs. Pour mettre à jour l'indicateur afin d'afficher une page différente comme sélectionnée, il suffit d'appeler la méthode indicator.setSelectedItem(int, true) de l'intérieur ViewPager.OnPageChangeListener.onPageSelected(int).

Voici un exemple d'utilisation:

enter image description here

Si cela vous intéresse, la bibliothèque a été conçue pour créer des écrans d’introduction similaires à celui présenté dans le gif ci-dessus.

Source Github disponible ici: https://github.com/MatthewTamlin/SlidingIntroScreen

29
Helios

ViewPagerIndicator n'a pas été mis à jour depuis 2012 et a reçu plusieurs bogues qui n'ont jamais été corrigés.

J'ai finalement trouvé une alternative avec cette bibliothèque de lumières qui affiche de jolis points pour le viewpager, voici le lien:

https://github.com/ongakuer/CircleIndicator

Facile à mettre en œuvre!

14
Yoann Hercouet

J'ai pensé poster une solution plus simple pour le problème ci-dessus et les numéros d'indicateurs peuvent être changés de manière dynamique en ne changeant qu'une valeur de variable dotCounts=x ce que j'ai fait ainsi.

1) Créez un fichier XML dans un dossier pouvant être dessiné pour l’indicateur de la page sélectionnée nommé "item_selected".

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shape="oval" Android:useLevel="true"
    Android:dither="true">
    <size Android:height="8dp" Android:width="8dp"/>
    <solid Android:color="@color/image_item_selected_for_dots"/>
</shape>

2) Créez un fichier XML supplémentaire pour l'indicateur non sélectionné nommé "item_unselected"

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shape="oval" Android:useLevel="true"
    Android:dither="true">

    <size Android:height="8dp" Android:width="8dp"/>

    <solid Android:color="@color/image_item_unselected_for_dots"/>
</shape>

3) Ajoutez maintenant cette partie du code à l’endroit où vous souhaitez afficher les indicateurs pour ex sous viewPager dans votre fichier XML Layout.

 <RelativeLayout
        Android:id="@+id/viewPagerIndicator"
        Android:layout_width="match_parent"
        Android:layout_below="@+id/banner_pager"
        Android:layout_height="wrap_content"
        Android:gravity="center">

        <LinearLayout
            Android:id="@+id/viewPagerCountDots"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:layout_centerHorizontal="true"
            Android:gravity="center"
            Android:orientation="horizontal" />
        </RelativeLayout>

4) Ajoutez cette fonction au-dessus de votre fichier de fichier d’activité où votre mise en page est gonflée ou le fichier xml ci-dessus est lié à

private int dotsCount=5;    //No of tabs or images
private ImageView[] dots;
LinearLayout linearLayout;

private void drawPageSelectionIndicators(int mPosition){
    if(linearLayout!=null) {
        linearLayout.removeAllViews();
    }
    linearLayout=(LinearLayout)findViewById(R.id.viewPagerCountDots);
    dots = new ImageView[dotsCount];
    for (int i = 0; i < dotsCount; i++) {
        dots[i] = new ImageView(context);
        if(i==mPosition)
            dots[i].setImageDrawable(getResources().getDrawable(R.drawable.item_selected));
        else
            dots[i].setImageDrawable(getResources().getDrawable(R.drawable.item_unselected));

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );

        params.setMargins(4, 0, 4, 0);
        linearLayout.addView(dots[i], params);
    }
}

5) Enfin, dans votre méthode onCreate, ajoutez le code suivant pour référencer votre mise en page et gérer les positions des pages.

drawPageSelectionIndicators(0);
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        drawPageSelectionIndicators(position);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }
});
14
Lokanath

Vous pouvez essayer la bibliothèque de Jake Wharton - https://github.com/JakeWharton/Android-ViewPagerIndicator

13
Joel Fernandes

Voici ma solution proposée.

  • Comme nous n’avons besoin que de montrer quelques images dans les visionneuses, nous avons évité l’utilisation encombrante de fragments.
    • Implémenter les indicateurs de page de vue (les points du bas sans aucune bibliothèque ou plugin supplémentaire)
    • Sur le toucher des indicateurs de page d'affichage (les points) également la navigation de page est en cours.
    • N’oubliez pas d’ajouter vos propres images dans les ressources.
    • N'hésitez pas à commenter et à l'améliorer.

A) Voici mon activité_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    Android:paddingLeft="@dimen/activity_horizontal_margin"
    Android:paddingRight="@dimen/activity_horizontal_margin"
    Android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="schneider.carouseladventure.MainActivity">

    <Android.support.v4.view.ViewPager xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:id="@+id/viewpager"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content" />

    <RelativeLayout
        Android:id="@+id/viewPagerIndicator"
        Android:layout_width="match_parent"
        Android:layout_height="55dp"
        Android:layout_alignParentBottom="true"
        Android:layout_marginTop="5dp"
        Android:gravity="center">

        <LinearLayout
            Android:id="@+id/viewPagerCountDots"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:layout_centerHorizontal="true"
            Android:gravity="center"
            Android:orientation="horizontal" />

    </RelativeLayout>


</RelativeLayout>

B) pager_item.xml

<?xml version="1.0" encoding="utf-8"?>

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

    <ImageView
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:id="@+id/imageView" />
</LinearLayout>

C) MainActivity.Java

import Android.support.v4.view.ViewPager;
import Android.support.v7.app.AppCompatActivity;
import Android.os.Bundle;
import Android.util.Log;
import Android.view.LayoutInflater;
import Android.view.MotionEvent;
import Android.view.View;
import Android.widget.ImageButton;
import Android.widget.ImageView;
import Android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener, View.OnClickListener {

    int[] mResources = {R.drawable.nature1, R.drawable.nature2, R.drawable.nature3, R.drawable.nature4,
            R.drawable.nature5, R.drawable.nature6
    };

    ViewPager mViewPager;
    private CustomPagerAdapter mAdapter;
    private LinearLayout pager_indicator;
    private int dotsCount;
    private ImageView[] dots;


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

        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        pager_indicator = (LinearLayout) findViewById(R.id.viewPagerCountDots);
        mAdapter = new CustomPagerAdapter(this, mResources);
        mViewPager.setAdapter(mAdapter);
        mViewPager.setCurrentItem(0);
        mViewPager.setOnPageChangeListener(this);

        setPageViewIndicator();

    }

    private void setPageViewIndicator() {

        Log.d("###setPageViewIndicator", " : called");
        dotsCount = mAdapter.getCount();
        dots = new ImageView[dotsCount];

        for (int i = 0; i < dotsCount; i++) {
            dots[i] = new ImageView(this);
            dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselecteditem_dot));

            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT
            );

            params.setMargins(4, 0, 4, 0);

            final int presentPosition = i;
            dots[presentPosition].setOnTouchListener(new View.OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    mViewPager.setCurrentItem(presentPosition);
                    return true;
                }

            });


            pager_indicator.addView(dots[i], params);
        }

        dots[0].setImageDrawable(getResources().getDrawable(R.drawable.selecteditem_dot));
    }

    @Override
    public void onClick(View v) {

    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {

        Log.d("###onPageSelected, pos ", String.valueOf(position));
        for (int i = 0; i < dotsCount; i++) {
            dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselecteditem_dot));
        }

        dots[position].setImageDrawable(getResources().getDrawable(R.drawable.selecteditem_dot));

        if (position + 1 == dotsCount) {

        } else {

        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}

D) CustomPagerAdapter.Java

 import Android.content.Context;
    import Android.support.v4.view.PagerAdapter;
    import Android.view.LayoutInflater;
    import Android.view.View;
    import Android.view.ViewGroup;
    import Android.widget.ImageView;
    import Android.widget.LinearLayout;

    public class CustomPagerAdapter extends PagerAdapter {
        private Context mContext;
        LayoutInflater mLayoutInflater;
        private int[] mResources;

        public CustomPagerAdapter(Context context, int[] resources) {
            mContext = context;
            mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            mResources = resources;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {

            View itemView = mLayoutInflater.inflate(R.layout.pager_item,container,false);
            ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView);
            imageView.setImageResource(mResources[position]);
           /* LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(950, 950);
            imageView.setLayoutParams(layoutParams);*/
            container.addView(itemView);
            return itemView;
        }

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

        @Override
        public int getCount() {
            return mResources.length;
        }

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

E) selecteditem_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shape="oval" Android:useLevel="true"
    Android:dither="true">

    <size Android:height="12dip" Android:width="12dip"/>

    <solid Android:color="#7e7e7e"/>
</shape>

F) nonselecteditem_dot.xml

 <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:shape="oval" Android:useLevel="true"
        Android:dither="true">        
        <size Android:height="12dip" Android:width="12dip"/>        
        <solid Android:color="#d3d3d3"/>
    </shape>

first image

enter image description here

9
Ajit

Si quelqu'un veut construire une viewPager avec des vignettes comme indicateurs, cette bibliothèque peut être une option: ThumbIndicator pour viewPager qui fonctionne également avec des liens d'image en tant que ressources

0
Mahdi Moqadasi

Voici comment j'ai fait cela, un peu similaire aux solutions ci-dessus. Assurez-vous simplement que vous appelez la méthode loadDots ()après le téléchargement de toutes les images.

    private int dotsCount;
    private TextView dotsTextView[];

    private void setupAdapter() {
        adapter = new SomeAdapter(getContext(), images);
        viewPager.setAdapter(adapter);
        viewPager.setCurrentItem(0);
        viewPager.addOnPageChangeListener(viewPagerPageChangeListener);
    }

    private final ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

        @Override
        public void onPageSelected(int position) {
            for (int i = 0; i < dotsCount; i++)
                dotsTextView[i].setTextColor(Color.GRAY);

            dotsTextView[position].setTextColor(Color.WHITE);
        }

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

    protected void loadDots() {
        dotsCount = adapter.getCount();
        dotsTextView = new TextView[dotsCount];
        for (int i = 0; i < dotsCount; i++) {
            dotsTextView[i] = new TextView(getContext());
            dotsTextView[i].setText(R.string.dot);
            dotsTextView[i].setTextSize(45);
            dotsTextView[i].setTypeface(null, Typeface.BOLD);
            dotsTextView[i].setTextColor(Android.graphics.Color.GRAY);
            mDotsLayout.addView(dotsTextView[i]);
        }
        dotsTextView[0].setTextColor(Color.WHITE);
    }

XML

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content">

    <Android.support.v4.view.ViewPager
        Android:id="@+id/viewPager"
        Android:layout_width="match_parent"
        Android:layout_height="180dp"
        Android:background="#00000000"/>


    <ImageView
        xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:id="@+id/introImageView"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"/>

    <LinearLayout
        Android:id="@+id/image_count"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="#00000000"
        Android:gravity="center|bottom"
        Android:orientation="horizontal"/>
</FrameLayout>
0
r3dm4n