This post is about creating an intro scene for your app using ViewPager and Fragments.
Here is the video in action-
[youtube id=”https://youtu.be/d4nhUy3hm4Q” width=”600″ height=”350″ autoplay=”no” api_params=”&rel=0″ class=””]
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
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; } } }