This post is about creating an intro scene for your app using ViewPager and Fragments.

Here is the video in action-

Note: I am using Android Studio 1.4 to prepare this tutorial.

We are going to create the following files inside out project-

Inside package-
IntroActivity.java

FragmentIntro1.java

FragmentIntro2.java

FragmentIntro3.java

Inside res->layout folder-

activity_intro.xml

fragment_intro1.xml

fragment_intro2.xml

fragment_intro3.xml

Inside drawable-

intro_dot_default.xml

intro_dot_selected.xml

I am going to add three .png images for the background viz. slide_intro1.png, slide_intro2.png and slide_intro3.png. You may add your own images inside drawable folder.

Steps 1 – Creating Activity:

First create a new activity. Goto File->New->Activity->Blank Activity

Enter activity name as IntroActivity. Package name as com.pits.introexample

new_activity_wizard

Check “Launcher Activity” and “Use a Fragment”. Click on Finish.

Step 2 – Creating the Resource Files for Displaying Dots:

Create a new xml resource file inside drawable folder. Enter name as intro_dot_default. Replace the content with the following code-

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/colorPrimaryDark" />
    <size
        android:width="15dp"
        android:height="15dp" />
</shape>

Value of colorPrimaryDark is #D32F2F.

Create another xml resource file inside drawable folder. Name it intro_dot_selected. Replace the content with the following code block-

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/white" />
    <size
        android:width="15dp"
        android:height="15dp" />
</shape>

Step 3- Ctrating Fragments:

Goto File->New->Fragment-> Fragment(Blank). Name it FragmentIntro1. Enter layout name as fragment_intro1. Uncheck “Include fragment factory methods?” and “Include interface callback?”. Click Finish.

Replace FragmentIntro1.java with the following code block-

package com.pits.introexample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.pits.introexample.R;
public class FragmentIntro1 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(
                R.layout.fragment_intro1, container, false);
        return rootView;
    }
}

Replace content of fragment_intro1.xml with the following code block-

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary">
    <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/slide_intro1"
        android:scaleType="fitXY"/>
</LinearLayout>

Similarly create another two fragments viz. FragmentIntro2 and FragmentIntro3. Now replace the content with the following code block accordingly-

Replace FragmentIntro2.java with the following code block-

package com.pits.introexample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.pits.introexample.R;
public class FragmentIntro2 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(
                R.layout.fragment_intro2, container, false);
        return rootView;
    }
}

Replace FragmentIntro3.java with the following code block-

package com.pits.introexample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.pits.introexample.R;
public class FragmentIntro3 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(
                R.layout.fragment_intro3, container, false);
        return rootView;
    }
}

Replace content of fragment_intro2.xml with the following code block-

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary">
    <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/slide_intro2"
        android:scaleType="fitXY"/>
</LinearLayout>

Replace content of fragment_intro3.xml with the following code block-

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary">
    <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/slide_intro3"
        android:scaleType="fitXY"/>
</LinearLayout>


Step 4: Modifying Activity Files:

Replace the content of activity_intro.xml with the following code block-

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    android:background="@color/colorPrimary"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity">
    <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/intro_pager"
        android:layout_width="match_parent"
        android:background="@color/colorPrimary"
        android:layout_height="match_parent" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:orientation="horizontal"
        android:paddingBottom="10dp"
        android:paddingLeft="20dp"
        android:paddingRight="20dp">
        <LinearLayout
            android:id="@+id/slidePositionIndicator"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true">
            <ImageView
                android:id="@+id/intro1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:src="@drawable/intro_dot_default"
                android:padding="5dp"
                />
            <ImageView
                android:id="@+id/intro2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:src="@drawable/intro_dot_default"
                android:padding="5dp" />
            <ImageView
                android:id="@+id/intro3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:src="@drawable/intro_dot_default"
                android:padding="5dp" />
        </LinearLayout>
        <TextView
            android:id="@+id/intro_skip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_toRightOf="@+id/slidePositionIndicator"
            android:gravity="end|center_vertical"
            android:padding="5dp"
            android:text="SKIP"
            android:textColor="@color/white"
            android:textSize="18sp" />
    </RelativeLayout>
</FrameLayout>

Now replace content of IntroActivity.java with the following codes-

package com.pits.introexample;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.pits.introexample.FragmentIntro1;
import com.pits.introexample.FragmentIntro2;
import com.pits.introexample.FragmentIntro3;

public class IntroActivity extends AppCompatActivity {
    private static final int TOTAL_PAGES = 3;
    private ViewPager mPager;
    private PagerAdapter mPagerAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intro);
        mPager = (ViewPager) findViewById(R.id.intro_pager);
        mPager.setPageTransformer(true, new DepthPageTransformer());
        mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
        mPager.setAdapter(mPagerAdapter);
        getSupportActionBar().hide();
        final ImageView introIndicator1 = (ImageView) findViewById(R.id.intro1);
        final ImageView introIndicator2 = (ImageView) findViewById(R.id.intro2);
        final ImageView introIndicator3 = (ImageView) findViewById(R.id.intro3);
        final TextView btnIntroSkip = (TextView) findViewById(R.id.intro_skip);
        btnIntroSkip.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //code to skip intro section
            }
        });
        mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }
            @Override
            public void onPageSelected(int position) {
                if (position == 0) {
                    introIndicator1.setImageResource(R.drawable.intro_dot_selected);
                    introIndicator2.setImageResource(R.drawable.intro_dot_default);
                    introIndicator3.setImageResource(R.drawable.intro_dot_default);
                } else if (position == 1) {
                    introIndicator1.setImageResource(R.drawable.intro_dot_default);
                    introIndicator2.setImageResource(R.drawable.intro_dot_selected);
                    introIndicator3.setImageResource(R.drawable.intro_dot_default);
                } else if (position == 2) {
                    introIndicator1.setImageResource(R.drawable.intro_dot_default);
                    introIndicator2.setImageResource(R.drawable.intro_dot_default);
                    introIndicator3.setImageResource(R.drawable.intro_dot_selected);
                }
            }
            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });
    }
    @Override
    public void onBackPressed() {
        if (mPager.getCurrentItem() == 0) {
            super.onBackPressed();
        } else {
            mPager.setCurrentItem(mPager.getCurrentItem() - 1);
        }
    }
  
    private class IntroPagerAdapter extends FragmentStatePagerAdapter {
        public IntroPagerAdapter(FragmentManager fm) {
            super(fm);
        }
        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new FragmentIntro1();
                case 1:
                    return new FragmentIntro2();
                case 2:
                    return new FragmentIntro3();
                default:
                    break;
            }
            return null;
        }
        @Override
        public int getCount() {
            return TOTAL_PAGES;
        }
    }
}