Although there are two ways to implement Android ViewPager class, but in this tutorial I am only going to discuss Android FragmentStatePagerAdapter class with an example. Since the main purpose/advantage of Android FragmentStatePagerAdapter class is to it consume less memory as compared to its counterpart, I used this to solve my problem. Android FragmentStatePagerAdapter class consumes less memory, because it destroys fragments, as soon as they are not visible to user, keeping only saved state of that fragment. And savedInstanceState is all, what I needed in my app to restore the filled out data by user.
But there may exist a situation where you would like to store the entire fragment in memory, if that’s the case have look at my complete series on PagerAdapters used to implement ViewPager class:
- Android FragmentStatePagerAdapter
- Android FragmentPagerAdapter
- Android FragmentPagerAdapter vs FragmentStatePagerAdapter
Now since the Fragments were introduced in android API 11, earlier versions of android are not capable of running fragments and swipes, unless a support library is used in app. Therefore I built this app with Android support library v4, package name android.support.v4
. As a result all versions will run following Android FragmentStatePagerAdapter Example.
Android FragmentStatePagerAdapter Example
To get started, first thing to do is, to create a layout for ViewPager and Android FragmentStatePagerAdapter class. Now while creating a layout please keep in mind to use android.support.v4.view.ViewPager as we would like our app to be compatible with older versions of android. Have a look at fragment_pager.xml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<LinearLayout xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"match_parent"
android
:
gravity
=
"center_horizontal"
android
:
orientation
=
"vertical"
android
:
padding
=
"4dip"
>
<android.support.v4.view.ViewPager
android
:
id
=
"@+id/pager"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"0px"
android
:
layout_weight
=
"1"
>
</android.support.v4.view.ViewPager>
<LinearLayout
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"wrap_content"
android
:
layout_weight
=
"0"
android
:
gravity
=
"center"
android
:
measureWithLargestChild
=
"true"
android
:
orientation
=
"horizontal"
>
<Button
android
:
id
=
"@+id/first"
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
text
=
"First"
>
</Button>
<Button
android
:
id
=
"@+id/last"
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
text
=
"Last"
>
</Button>
</LinearLayout>
</LinearLayout>
|
The layout above is the main layout where all the fragments would be inflated and displayed. To display sliding views, now we need to declare a main class where Android FragmentStatePagerAdapter class would be declared. The class defined below is MainActivity.java.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
package
com
.
truiton
.
fragmentstatepageradapter
;
import
android
.
os
.
Bundle
;
import
android
.
support
.
v4
.
app
.
Fragment
;
import
android
.
support
.
v4
.
app
.
FragmentActivity
;
import
android
.
support
.
v4
.
app
.
FragmentManager
;
import
android
.
support
.
v4
.
app
.
FragmentStatePagerAdapter
;
import
android
.
support
.
v4
.
view
.
ViewPager
;
import
android
.
view
.
Menu
;
import
android
.
view
.
View
;
import
android
.
view
.
View
.
OnClickListener
;
import
android
.
widget
.
Button
;
public
class
MainActivity
extends
FragmentActivity
{
static
final
int
ITEMS
=
10
;
MyAdapter
mAdapter
;
ViewPager
mPager
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
)
;
setContentView
(
R
.
layout
.
fragment_pager
)
;
mAdapter
=
new
MyAdapter
(
getSupportFragmentManager
(
)
)
;
mPager
=
(
ViewPager
)
findViewById
(
R
.
id
.
pager
)
;
mPager
.
setAdapter
(
mAdapter
)
;
Button
button
=
(
Button
)
findViewById
(
R
.
id
.
first
)
;
button
.
setOnClickListener
(
new
OnClickListener
(
)
{
public
void
onClick
(
View
v
)
{
mPager
.
setCurrentItem
(
0
)
;
}
}
)
;
button
=
(
Button
)
findViewById
(
R
.
id
.
last
)
;
button
.
setOnClickListener
(
new
OnClickListener
(
)
{
public
void
onClick
(
View
v
)
{
mPager
.
setCurrentItem
(
ITEMS
-
1
)
;
}
}
)
;
}
public
static
class
MyAdapter
extends
FragmentStatePagerAdapter
{
public
MyAdapter
(
FragmentManager
fragmentManager
)
{
super
(
fragmentManager
)
;
}
@Override
public
int
getCount
(
)
{
return
ITEMS
;
}
@Override
public
Fragment
getItem
(
int
position
)
{
switch
(
position
)
{
case
0
:
// Fragment # 0 - This will show image
return
ImageFragment
.
init
(
position
)
;
case
1
:
// Fragment # 1 - This will show image
return
ImageFragment
.
init
(
position
)
;
default
:
// Fragment # 2-9 - Will show list
return
ArrayListFragment
.
init
(
position
)
;
}
}
}
@Override
public
boolean
onCreateOptionsMenu
(
Menu
menu
)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater
(
)
.
inflate
(
R
.
menu
.
main
,
menu
)
;
return
true
;
}
}
|
In the class above I defined my own FragmentStatePagerAdapter by the name of MyAdapter class. In this adapter the main method is getItem. The getItem method in FragmentStatePagerAdapter calls each fragment when user swipes though them. In this MyAdapter class we are calling two Fragments, ImageFragment and ArrayListFragment. lets have a look at ImageFragment class first.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
package
com
.
truiton
.
fragmentstatepageradapter
;
import
android
.
os
.
Bundle
;
import
android
.
support
.
v4
.
app
.
Fragment
;
import
android
.
view
.
LayoutInflater
;
import
android
.
view
.
View
;
import
android
.
view
.
ViewGroup
;
import
android
.
widget
.
TextView
;
public
class
ImageFragment
extends
Fragment
{
int
fragVal
;
static
ImageFragment
init
(
int
val
)
{
ImageFragment
truitonFrag
=
new
ImageFragment
(
)
;
// Supply val input as an argument.
Bundle
args
=
new
Bundle
(
)
;
args
.
putInt
(
"val"
,
val
)
;
truitonFrag
.
setArguments
(
args
)
;
return
truitonFrag
;
}
@Override
public
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
)
;
fragVal
=
getArguments
(
)
!=
null
?
getArguments
(
)
.
getInt
(
"val"
)
:
1
;
}
@Override
public
View
onCreateView
(
LayoutInflater
inflater
,
ViewGroup
container
,
Bundle
savedInstanceState
)
{
View
layoutView
=
inflater
.
inflate
(
R
.
layout
.
fragment_image
,
container
,
false
)
;
return
layoutView
;
}
}
|
Here in the class above I have defined a static method by the name of init. This method takes the position as argument val from inherited/extended Android FragmentStatePagerAdapter class and further its used in onCreate and onCreateView method of this Fragment accordingly. ImageFragment uses fragment_image layout, so lets have a look at fragment_image.xml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<RelativeLayout xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"match_parent"
>
<TextView
android
:
id
=
"@+id/text"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"wrap_content"
android
:
gravity
=
"center_vertical|center_horizontal"
android
:
text
=
"@string/hello_world"
android
:
textAppearance
=
"?android:attr/textAppearanceMedium"
/>
<ImageView
android
:
id
=
"@+id/imageView1"
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
layout_below
=
"@+id/text"
android
:
layout_centerHorizontal
=
"true"
android
:
layout_marginTop
=
"36dp"
android
:
src
=
"@drawable/truiton"
/>
</RelativeLayout>
|
Next lets have a look at the ArrayListFragment.java.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
package
com
.
truiton
.
fragmentstatepageradapter
;
import
android
.
os
.
Bundle
;
import
android
.
support
.
v4
.
app
.
ListFragment
;
import
android
.
util
.
Log
;
import
android
.
view
.
LayoutInflater
;
import
android
.
view
.
View
;
import
android
.
view
.
ViewGroup
;
import
android
.
widget
.
ArrayAdapter
;
import
android
.
widget
.
ListView
;
import
android
.
widget
.
TextView
;
public
class
ArrayListFragment
extends
ListFragment
{
int
fragNum
;
String
arr
[
]
=
{
"This is"
,
"a Truiton"
,
"Demo"
,
"App"
,
"For"
,
"Showing"
,
"FragmentStatePagerAdapter"
,
"and ViewPager"
,
"Implementation"
}
;
static
ArrayListFragment
init
(
int
val
)
{
ArrayListFragment
truitonList
=
new
ArrayListFragment
(
)
;
// Supply val input as an argument.
Bundle
args
=
new
Bundle
(
)
;
args
.
putInt
(
"val"
,
val
)
;
truitonList
.
setArguments
(
args
)
;
return
truitonList
;
}
/**
* Retrieving this instance's number from its arguments.
*/
@
Override
public
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
)
;
fragNum
=
getArguments
(
)
!=
null
?
getArguments
(
)
.
getInt
(
"val"
)
:
1
;
}
/**
* The Fragment's UI is a simple text view showing its instance number and
* an associated list.
*/
@
Override
public
View
onCreateView
(
LayoutInflater
inflater
,
ViewGroup
container
,
Bundle
savedInstanceState
)
{
View
layoutView
=
inflater
.
inflate
(
R
.
layout
.
fragment_pager_list
,
container
,
false
)
;
(
(
TextView
)
tv
)
.
setText
(
"Truiton Fragment #"
+
fragNum
)
;
return
layoutView
;
}
@
Override
public
void
onActivityCreated
(
Bundle
savedInstanceState
)
{
super
.
onActivityCreated
(
savedInstanceState
)
;
setListAdapter
(
new
ArrayAdapter
<
String
>
(
getActivity
(
)
,
android
.
R
.
layout
.
simple_list_item_1
,
arr
)
)
;
}
@
Override
public
void
onListItemClick
(
ListView
l
,
View
v
,
int
position
,
long
id
)
{
Log
.
i
(
"Truiton FragmentList"
,
"Item clicked: "
+
id
)
;
}
}
|
The functioning of this ListFragment is also same as of ImageFragment, it has an init method which takes argument from FragmentStatePagerAdapter, the only difference is that it displays a list. Have a look at its layout fragment_pager_list.xml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
LinearLayout
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"match_parent"
android
:
background
=
"@android:drawable/gallery_thumb"
android
:
orientation
=
"vertical"
>
<
TextView
android
:
id
=
"@+id/text"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"wrap_content"
android
:
gravity
=
"center_vertical|center_horizontal"
android
:
text
=
"@string/hello_world"
android
:
textAppearance
=
"?android:attr/textAppearanceMedium"
/
>
<
FrameLayout
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"0dip"
android
:
layout_weight
=
"1"
>
<
ListView
android
:
id
=
"@android:id/list"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"match_parent"
android
:
drawSelectorOnTop
=
"false"
/
>
<
/
FrameLayout
>
<
/
LinearLayout
>
|
As of now we have our Android FragmentStatePagerAdapter and ViewPager setup and working, so your project should look something like this.
With this I can conclude this tutorial on Android FragmentStatePagerAdapter and ViewPager. In this tutorial I created an app which had the functionality to display 10 sliding fragments, or swipe views. Also I defined two types of fragments, an ImageFragment and ListFragment, which were used according to the required position in FragmentStatePagerAdapter.
As I mentioned earlier Android FragmentStatePagerAdapter destroys fragments as soon as, they are not visible to user. If you are developing an app which has less number of fragments and you want to keep them in memory, have look at my tutorial on Android FragmentPagerAdapter. If this helped you please like and share this with your friends on Google+ and Facebook. Also like our Facebook page for updates.
http://www.truiton.com/2013/05/android-fragmentstatepageradapter-example/