Android app sliding intro example/ using AndroidX Viewpager2 and TabLayout

By | June 19, 2020

In this tutorial we are going to create intro sliding which will show major features of the app where user can swipe through few slides before getting into app.

we are using AndroidX support Library , ViewPager2 and 3 different fragment & 3 different xml for layouts. And TabLayout for dots navigation.

To demonstrate, I am creating a simple app that contains 3 intro slides with next and skip navigation. The user can navigate through each slide using swipe gesture.

STEP 1: CREATING PROJECT

-Let’s start with creating new project in android studio with package name com.example.manualSliding and class name MainActivity.java and its layout name is activity_main.xml.

STEP 2: ADDING DEPENDENCIES

-open file Gradle Scripts/build.gradle(Module: app)

-under dependencies{ } add this:

dependencies {
   
    //this is for ViewPager
    implementation "androidx.viewpager2:viewpager2:1.0.0"
    
    //this is for TabLayout
    implementation 'com.google.android.material:material:1.2.0-alpha01'


}

-under compileOptions{} add this:

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

STEP 3: EDIT app/res/values/colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#0698bc</color>
<color name="colorPrimaryDark">#067d9b</color>
<color name="colorAccent">#FF4081</color>
<color name="white">#FFFFFF</color>
<color name="bg1">#0385a3</color>
<color name="bg2">#03a373</color>
<color name="bg3">#b704c4</color>

</resources>

STEP 4: EDIT app/res/values/styles.xml :we using this theme because TabLayout component works in this theme.

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

</resources>

STEP 5: CREATE 3 LAYOUT file tab_selector.xml, selected_dot.xml, default_dot.xml where TabLayout uses tab_selector for drawing dots and tab_selector select between default_dot.xml and selected_dot.xml.

-under app/res/drawable/tab_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector
    android:layout_height="8dp"
    android:layout_width="8dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/selected_dot"
        android:state_selected="true"/>
    <item android:drawable="@drawable/default_dot"/>
</selector>

-under app/res/drawable/default_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="8dp"
android:layout_width="8dp">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="8dp"
android:useLevel="false">
<solid android:color="@android:color/darker_gray"/>
</shape>
</item>
</layer-list>

-under app/res/drawable/selected_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="8dp"
android:layout_width="8dp">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="8dp"
android:useLevel="false">
<solid android:color="@android:color/white"/>
</shape>
</item>
</layer-list>

STEP 6: CREATING LAYOUT OF 3 INTRO SLIDES

– Each slides has 3 TextView and 1 ImageView.

-create new xml layout file under app/res/layout frg1.xml and add the below code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="10"
android:background="#0385a3"
android:orientation="vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_weight="3"
android:gravity="center"
android:paddingLeft="32dp"
android:paddingRight="29dp"
android:text="Welcome to AppIntro"
android:textColor="#ffffff"
android:textSize="27sp"
android:textStyle="bold" />

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="5"
android:gravity="center"
android:orientation="vertical">

//image link from drawable folder

<ImageView
android:layout_width="140dp"
android:layout_height="180dp"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:src="@drawable/appintro" />
</LinearLayout>

<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_weight="3"
android:gravity="center"
android:paddingLeft="64dp"
android:paddingRight="64dp"
android:text="Amazing android app with cool features."
android:textColor="#ffffff"
android:textSize="16sp" />

<TextView
android:background="#0385a3"
android:layout_width="fill_parent"
android:layout_height="62dp" />
</LinearLayout>

-create new xml layout file under app/res/layout frg2.xml and add the below code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="10"
android:background="#03a373"
android:orientation="vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_weight="3"
android:gravity="center"
android:paddingLeft="32dp"
android:paddingRight="29dp"
android:text="Mobile Recharge"
android:textColor="#ffffff"
android:textSize="27sp"
android:textStyle="bold" />

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="5"
android:gravity="center"
android:orientation="vertical">

<ImageView
android:layout_width="140dp"
android:layout_height="180dp"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:src="@drawable/mobile" />
</LinearLayout>

<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_weight="3"
android:gravity="center"
android:paddingLeft="64dp"
android:paddingRight="64dp"
android:text="Best recharge offers and 10% cashback on first recharge"
android:textColor="#ffffff"
android:textSize="16sp" />

<TextView
android:layout_width="fill_parent"
android:layout_height="62dp" />
</LinearLayout>

-create new xml layout file under app/res/layout frg3.xml and add the below code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="10"
android:background="#b704c4"
android:orientation="vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_weight="3"
android:gravity="center"
android:paddingLeft="32dp"
android:paddingRight="29dp"
android:text="Movie Tickets"
android:textColor="#ffffff"
android:textSize="27sp"
android:textStyle="bold" />

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="5"
android:gravity="center"
android:orientation="vertical">

<ImageView
android:layout_width="140dp"
android:layout_height="180dp"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:src="@drawable/movie" />
</LinearLayout>

<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_weight="3"
android:gravity="center"
android:paddingLeft="64dp"
android:paddingRight="64dp"
android:text="Book Movie tickets for your family and friends"
android:textColor="#ffffff"
android:textSize="16sp" />

<TextView
android:layout_width="fill_parent"
android:layout_height="62dp" />
</LinearLayout>

STEP 7: Create FRAGMENT CLASS for each slide layout:

-create new java class under app/java/com.example.manualSliding/FirstFragment.java

package com.example.manualsliding;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.fragment.app.Fragment;

public class FirstFragment extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frg1, container, false);
/*
TextView tv = (TextView) v.findViewById(R.id.tvFragFifth);
tv.setText(getArguments().getString("msg"));

*/
return v;
}

public static FirstFragment newInstance(String text) {

FirstFragment f = new FirstFragment();
Bundle b = new Bundle();
b.putString("msg", text);
f.setArguments(b);
return f;
}
}

– create new java class under app/java/com.example.manualSliding/SecondFragment.java

package com.example.manualsliding;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.fragment.app.Fragment;

public class SecondFragment extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frg2, container, false);
return v;
}

public static SecondFragment newInstance(String text) {
SecondFragment f = new SecondFragment();
Bundle b = new Bundle();
b.putString("msg", text);
f.setArguments(b);
return f;
}
}

-create new java class under app/java/com.example.manualSliding/ThirdFragment.java

package com.example.manualsliding;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.fragment.app.Fragment;

public class ThirdFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.frg3, container, false);
        return v;
    }

    public static ThirdFragment newInstance(String text) {
        ThirdFragment  f = new ThirdFragment();
        Bundle b = new Bundle();
        b.putString("msg", text);
        f.setArguments(b);
        return f;
    }
}

STEP 8: app/java/com.example.manualSliding/MainActivity.java

package com.example.manualsliding;

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;


public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

}

STEP 9: app/res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".WelcomeActivity">

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="60dp"
android:layout_marginLeft="60dp"
android:layout_marginTop="44dp"
android:text="Welcome to Home"
android:textSize="35dp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

STEP 10: CREATE class PrefManager.java under package app/java/com.example.manualSliding/ and do the below changes. isFirstTimeLaunch() returns true if the app is launched for the first time.

package com.example.manualsliding;

import android.content.Context;
import android.content.SharedPreferences;

public class PrefManager {
SharedPreferences pref;
SharedPreferences.Editor editor;
Context _context;

// shared pref mode
int PRIVATE_MODE = 0;

// Shared preferences file name
private static final String PREF_NAME = "tutorialface-welcome";

private static final String IS_FIRST_TIME_LAUNCH = "IsFirstTimeLaunch";

public PrefManager(Context context) {
this._context = context;
pref = _context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
editor = pref.edit();
}

public void setFirstTimeLaunch(boolean isFirstTime) {
editor.putBoolean(IS_FIRST_TIME_LAUNCH, isFirstTime);
editor.commit();
}

public boolean isFirstTimeLaunch() {
return pref.getBoolean(IS_FIRST_TIME_LAUNCH, true);
}

}

STEP:11: CREATE new Activity named app/java/com.example.manualSliding/WelcomeActivity.java

-we use this activity for our introduction slideshow.

STEP 12: EDIT app/res/layout/activity_welcome.xml file for our sliding layout.

-Here we are using a Viewpager2 for fragments layout.

TabLayout for displaying navigation dots.

Button SKIP and Button NEXT.

-The final code of app/res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:id="@+id/outer_linear_layout"
    tools:context=".MainActivity">

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

    <LinearLayout
        android:id="@+id/bottom_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="@color/colorPrimary">

        <Button
            style="?android:attr/borderlessButtonStyle"
            android:id="@+id/button_skip"
            android:layout_width="60dp"
            android:layout_height="match_parent"
            android:padding="0dp"
            android:text="SKIP"
            android:textSize="12sp" />

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tab_layout"
            style="@style/Widget.MaterialComponents.TabLayout.Colored"
            android:layout_width="290dp"
            android:layout_height="wrap_content"
            app:tabBackground="@drawable/tab_selector"
            app:tabGravity="center"
            app:tabIndicatorHeight="0dp"></com.google.android.material.tabs.TabLayout>

        <Button
            android:id="@+id/button_next"
            style="?android:attr/borderlessButtonStyle"
            android:layout_width="60dp"
            android:layout_height="match_parent"
            android:padding="0dp"
            android:text="NEXT"
            android:textSize="12sp" />
    </LinearLayout>
</LinearLayout>

STEP 13: Open Welcome_Activity.java and modify the code as below. Here I have taken care of few things

-Check for the fist time app launch using prefManager.isFirstTimeLaunch() method. If it returns true, MainActivity will be launched skipping the intro activity.


– Created a PageAdapter for the ViewPager2 and inflated all the layouts we created earlier.

-Inflated an TabLayout and create navigation dots using TabLayoutMediator

-Added Onclick event listener to Skip and Next buttons. so you can add definitions you desire.

-Here is the complete code of app/java/com.example.manualSliding/WelcomeActivity.java

package com.example.manualsliding;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager.widget.ViewPager;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;


public class WelcomeActivity extends AppCompatActivity {
    private PrefManager prefManager;
    public Button btnSKIP, btnNEXT;
    private static final int NUM_PAGES = 3;
    //The pager widget, which handles animation and allows swiping horizontally to access previous and next wizard steps.
    public static ViewPager2 viewPager;
    // The pager adapter, which provides the pages to the view pager widget.
    private FragmentStateAdapter pagerAdapter;
    public TabLayout tabLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Checking for first time launch - before calling setContentView()
        prefManager = new PrefManager(this);
        if (!prefManager.isFirstTimeLaunch()) {
            launchHomeScreen();
            finish();
        }
        setContentView(R.layout.activity_welcome);
    
        btnSKIP = (Button) findViewById(R.id.button_skip);
        btnSKIP = (Button) findViewById(R.id.button_next);

        viewPager = findViewById(R.id.mypager);
        pagerAdapter = new MyPagerAdapter(this);
        viewPager.setAdapter(pagerAdapter);
        tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        // new TabLayoutMediator(tabLayout, viewPager,(tab, position) -> tab.setText(titles[position])).attach();

        new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
        }).attach();
        Button btnSkip, btnNext;
        btnSkip = (Button) findViewById(R.id.button_skip);
        btnNext = (Button) findViewById(R.id.button_next);
        btnSkip.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                launchHomeScreen();

            }
        });
        btnNext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // checking for last page
                // if last page home screen will be launched
                int current = (viewPager.getCurrentItem() + 1);
                if (current < NUM_PAGES) {
                    // move to next screen
                    viewPager.setCurrentItem(current);
                } else {
                    launchHomeScreen();
                }
            }


        });
    }

    private void launchHomeScreen() {
        prefManager.setFirstTimeLaunch(false);
        startActivity(new Intent(WelcomeActivity.this, MainActivity.class));
        finish();
    }

    @Override
    public void onBackPressed() {
        if (viewPager.getCurrentItem() == 0) {
            // If the user is currently looking at the first step, allow the system to handle the
            // Back button. This calls finish() on this activity and pops the back stack.d
            super.onBackPressed();
        } else {
            // Otherwise, select the previous step.
            viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);
        }
    }

    public class MyPagerAdapter extends FragmentStateAdapter {

        public MyPagerAdapter(FragmentActivity fa) {
            super(fa);
        }


        @Override
        public Fragment createFragment(int pos) {
            switch (pos) {
                case 0: {
                    return FirstFragment.newInstance("fragment 1");

                }
                case 1: {

                    return SecondFragment.newInstance("fragment 2");
                }
                case 2: {

                    return ThirdFragment.newInstance("fragment 3");
                }
                default:
                    return FirstFragment.newInstance("fragment 1, Default");
            }
        }

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

    }

}

170 total views, 2 views today

(Visited 28 times, 1 visits today)