Viewpager android example with Download[updated]

ViewPager android widget is found in the support library and it allows the user to swipe left or right to see an entirely new screen. It also has the ability to dynamically add and remove pages (or tabs) at any time.

Today we’re implementing a ViewPager by using Views and FragmentPagerAdapter.Based on the selected item, I am updating the content of the screen.

Let’s getting started into the coding part.

1. Add recyclerview and cardview dependencies into your app build.gradle file.

implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'

2. Add viewpager into your activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/white"
    android:fitsSystemWindows="true">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:clipToPadding="false"
        android:overScrollMode="never"
        android:paddingBottom="30dp"
        android:paddingEnd="@dimen/card_padding"
        android:paddingLeft="@dimen/card_padding"
        android:paddingRight="@dimen/card_padding"
        android:paddingStart="@dimen/card_padding"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"/>

The most important thing here is the attribute clipToPadding in the ViewPager. When this is false, the ViewPager won’t cut off the views that we want to show partially and the current item will still be centered.

3. Design viewpager adapter design.
card_view.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cardView"
    app:cardUseCompatPadding="true"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:layout_gravity="center"
    app:cardCornerRadius="10dp">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/img_background"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <TextView
            android:id="@+id/title"
            style="@style/TextAppearance.AppCompat.Title"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:text="Card title"
            android:gravity="center"
            android:textAllCaps="true"
            android:background="@color/white"
            android:textColor="@color/grey_dark"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

    </android.support.constraint.ConstraintLayout>

</android.support.v7.widget.CardView>

cardview design

viewpager cardview

4. Here come the transformer for the viewpager transform animations.
Transformer.java

public class Transformer implements ViewPager.OnPageChangeListener, ViewPager.PageTransformer {

    private ViewPager viewPager;
    private CardAdapter cardAdapter;
    private float lastOffset;
    private boolean scalingEnabled;

    Transformer(ViewPager viewPager, CardAdapter adapter) {
        this.viewPager = viewPager;
        viewPager.addOnPageChangeListener(this);
        cardAdapter = adapter;
    }

    public void enableScaling(boolean enable) {
        if (scalingEnabled && !enable) {
            // shrink main card
            CardView currentCard = cardAdapter.getCardViewAt(viewPager.getCurrentItem());
            if (currentCard != null) {
                currentCard.animate().scaleY(1);
                currentCard.animate().scaleX(1);
            }
        }else if(!scalingEnabled && enable){
            // grow main card
            CardView currentCard = cardAdapter.getCardViewAt(viewPager.getCurrentItem());
            if (currentCard != null) {
                //enlarge the current item
                currentCard.animate().scaleY(1.1f);
                currentCard.animate().scaleX(1.1f);
            }
        }
        scalingEnabled = enable;
    }

    @Override
    public void transformPage(View page, float position) {

    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        int realCurrentPosition;
        int nextPosition;
        float realOffset;
        boolean goingLeft = lastOffset > positionOffset;

        // If we're going backwards, onPageScrolled receives the last position
        // instead of the current one
        if (goingLeft) {
            realCurrentPosition = position + 1;
            nextPosition = position;
            realOffset = 1 - positionOffset;
        } else {
            nextPosition = position + 1;
            realCurrentPosition = position;
            realOffset = positionOffset;
        }

        // Avoid crash on overscroll
        if (nextPosition > cardAdapter.getCount() - 1
                || realCurrentPosition > cardAdapter.getCount() - 1) {
            return;
        }

        CardView currentCard = cardAdapter.getCardViewAt(realCurrentPosition);

        // This might be null if a fragment is being used
        // and the views weren't created yet
        if (currentCard != null) {
            if (scalingEnabled) {
                currentCard.setScaleX((float) (1 + 0.1 * (1 - realOffset)));
                currentCard.setScaleY((float) (1 + 0.1 * (1 - realOffset)));
            }
            currentCard.setCardElevation((CardAdapter.BASE_ELEVATION + CardAdapter.BASE_ELEVATION
                    * (CardAdapter.MAX_ELEVATION_FACTOR - 1) * (1 - realOffset)));
        }

        CardView nextCard = cardAdapter.getCardViewAt(nextPosition);

        // We might be scrolling fast enough so that the next (or previous) card
        // was already destroyed or a fragment might not have been created yet
        if (nextCard != null) {
            if (scalingEnabled) {
                nextCard.setScaleX((float) (1 + 0.1 * (realOffset)));
                nextCard.setScaleY((float) (1 + 0.1 * (realOffset)));
            }
            nextCard.setCardElevation((CardAdapter.BASE_ELEVATION + CardAdapter.BASE_ELEVATION
                    * (CardAdapter.MAX_ELEVATION_FACTOR - 1) * (realOffset)));
        }

        lastOffset = positionOffset;
    }

    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}

5. your data model

Place.java

public class Place implements Parcelable{

    private String name;
    private int image;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }

    public Place(String name, int desc) {
        this.name = name;
        this.image = desc;
    }

    protected Place(Parcel in) {
        name = in.readString();
        image = in.readInt();
    }

    public static final Creator<Place> CREATOR = new Creator<Place>() {
        @Override
        public Place createFromParcel(Parcel in) {
            return new Place(in);
        }

        @Override
        public Place[] newArray(int size) {
            return new Place[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(image);
    }
}

6. Create Fragment for your view, and set the image and text into cardview.

CardFragment.java

public class CardFragment extends Fragment {

    private CardView cardView;

    public static Fragment getInstance(Place place) {
        CardFragment f = new CardFragment();
        Bundle args = new Bundle();
        args.putParcelable("place", place);
        f.setArguments(args);
        return f;
    }

    @SuppressLint("DefaultLocale")
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.card_view, container, false);

        cardView = (CardView) view.findViewById(R.id.cardView);
        cardView.setMaxCardElevation(cardView.getCardElevation() * CardAdapter.MAX_ELEVATION_FACTOR);

        TextView title = (TextView) view.findViewById(R.id.title);
        //Button button = (Button)view.findViewById(R.id.button);
        ImageView image = view.findViewById(R.id.img_background);
        Place place = getArguments().getParcelable("place");
        title.setText(place.getName());
        image.setBackgroundResource(place.getImage());

        return view;
    }

    public CardView getCardView() {
        return cardView;
    }
}

7. Create adapter for the cardview.

CardFragmentPagerAdapter.java

public class CardFragmentPagerAdapter extends FragmentStatePagerAdapter implements CardAdapter {

    private List<CardFragment> fragments;
    private List<Place> placeList;

    public CardFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
        fragments = new ArrayList<>();
        placeList = new ArrayList<>();
    }

    @Override
    public CardView getCardViewAt(int position) {
        return fragments.get(position).getCardView();
    }

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

    @Override
    public Fragment getItem(int position) {
        return CardFragment.getInstance(placeList.get(position));
    }

    public void addCardFragment(CardFragment fragment,Place place) {
        fragments.add(fragment);
        placeList.add(place);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Object fragment = super.instantiateItem(container, position);
        fragments.set(position, (CardFragment) fragment);
        return fragment;
    }

}

CardAdapter.java

public interface CardAdapter {

    int MAX_ELEVATION_FACTOR = 8;

    float BASE_ELEVATION = 4;

    CardView getCardViewAt(int position);

    int getCount();
}

8. In your main activity, create needed fragments and add it in your adapter. In my case I have create cardfragments and added into the cardFragmentPagerAdapter.

TypedArray images = getResources().obtainTypedArray(R.array.images);
        CardFragmentPagerAdapter pagerAdapter = new CardFragmentPagerAdapter(getSupportFragmentManager());
        for (int i = 0; i < getResources().getStringArray(R.array.place).length; i++) {
            pagerAdapter.addCardFragment(new CardFragment(),new Place(getResources().getStringArray(R.array.place)[i],
                    images.getResourceId(i,-1)));
        }
        images.recycle();
        viewPager.setAdapter(pagerAdapter);

Then, Add viewpager view and viewpager adapter into transformer. Also, set off page screen limit.

Transformer transformer = new Transformer(viewPager, pagerAdapter);
        transformer.enableScaling(true);
        viewPager.setPageTransformer(false, transformer);
        viewPager.setOffscreenPageLimit(3);

here is my final main_activity MainActivity.java

public class MainActivity extends AppCompatActivity {

    private TextSwitcher title;
    private TextSwitcher desc;

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

        title = findViewById(R.id.title);
        title.setFactory(titleFactory);
        desc = findViewById(R.id.desc);
        desc.setFactory(descFactory);
        title.setInAnimation(this, R.anim.slide_down);
        desc.setInAnimation(this, R.anim.slide_down);

        ViewPager viewPager = findViewById(R.id.viewPager);

        TypedArray images = getResources().obtainTypedArray(R.array.images);
        CardFragmentPagerAdapter pagerAdapter = new CardFragmentPagerAdapter(getSupportFragmentManager());
        for (int i = 0; i < getResources().getStringArray(R.array.place).length; i++) {
            pagerAdapter.addCardFragment(new CardFragment(),new Place(getResources().getStringArray(R.array.place)[i],
                    images.getResourceId(i,-1)));
        }
        images.recycle();
        Transformer transformer = new Transformer(viewPager, pagerAdapter);
        transformer.enableScaling(true);
        viewPager.setAdapter(pagerAdapter);
        viewPager.setPageTransformer(false, transformer);
        viewPager.setOffscreenPageLimit(3);

        title.setText(getResources().getStringArray(R.array.name)[0]);
        desc.setText(getResources().getStringArray(R.array.desc)[0]);

        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                title.setText(getResources().getStringArray(R.array.name)[position]);
                desc.setText(getResources().getStringArray(R.array.desc)[position]);
                }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

    }

    ViewSwitcher.ViewFactory titleFactory = new ViewSwitcher.ViewFactory() {
        @Override
        public View makeView() {
            TextView textView = new TextView(getApplicationContext());
            textView.setTextSize(20);
            textView.setGravity(Gravity.LEFT);
            textView.setTypeface(null, Typeface.BOLD);
            return textView;
        }
    };

    ViewSwitcher.ViewFactory descFactory = new ViewSwitcher.ViewFactory() {
        @Override
        public View makeView() {
            TextView textView = new TextView(getApplicationContext());
            textView.setTextSize(15);
            return textView;
        }
    };

}

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Top
%d bloggers like this: