How cool is it to have an app which has swipe views, it makes app interactive and fun to use, right? So being a mobile app consultant at Truiton I was working on an app where segmented forms were to be filled by user. I thought why not use swipe tabs and sliding views. I searched and found this can be implemented by Android ViewPager class, which is used in conjunction with Android FragmentPagerAdapter class or Android FragmentStatePagerAdapter class. Since any sort of software development requires precision and accuracy in work my purpose was solved by the later one. Still I decided to write a tutorial about Android FragmentPagerAdapter Example.
There are two ways to implement Android ViewPager class, but this tutorial only focuses on Android FragmentPagerAdapter with an example. Now since both adapters have different ways of working, you might want to read about the other one too, have a look at my series on PagerAdapters :
- Android FragmentStatePagerAdapter
- Android FragmentPagerAdapter
- Android FragmentPagerAdapter vs FragmentStatePagerAdapter
In my previous tutorial I mentioned a case, if we wish to keep the fragment in the memory. Here steps in Android FragmentPagerAdapter, the main advantage of using Android FragmentPagerAdapter is that, it keeps the fragment in memory. This definitely increases the memory usage, therefore it is advised to use Android FragmentPagerAdapter only when there are less number of fragments. If you app has non changing fragments like, fragments with images or static text it might work even better. But using Android FragmentPagerAdapter for large number of fragments would result choppy and laggy UX.
Android FragmentPagerAdapter Example
Lets start with the main activity, this activity is where the Android FragmentPagerAdapter class is declared. Have a look at 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
.
fragmentpageradapter
;
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
.
FragmentPagerAdapter
;
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
FragmentPagerAdapter
{
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
TruitonListFragment
.
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 above class one can see that MainActivity extends FragmentActivity and in this class, both MyAdapter and ViewPager class are instantiated. If you look closely you would find that MyAdapter class extends Android FragmentPagerAdapter class. Lets have a look at the extended Android FragmentPagerAdapter class, here exists a method by the name of getItem. This getItem method is the one which calls all the fragments which are to be displayed according to the position. MainActivity.java is displayed by layout 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
39
|
<?
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>
|
Above is the main layout where all fragments would be displayed. Have a look at android.support.v4.view.ViewPager tag, since this tag is used here, this app would run on android devices lower than API version 11 too. Next lets have a look at ImageFragment.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
|
package
com
.
truiton
.
fragmentpageradapter
;
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
;
}
}
|
In the above class a static method by the name of init is declared. This init method is called in the extended Android FragmentPagerAdapter class with position of the fragment as argument. This argument is later on used in onCreate and onCreateView method of this ImageFragment. The layout file for this class is 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>
|
Now have a look at the second type of fragment used in Android FragmentPagerAdapter Example, TruitonListFragment.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
.
fragmentpageradapter
;
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
TruitonListFragment
extends
ListFragment
{
int
fragNum
;
String
arr
[
]
=
{
"This is"
,
"a Truiton"
,
"Demo"
,
"App"
,
"For"
,
"Showing"
,
"FragmentPagerAdapter"
,
"and ViewPager"
,
"Implementation"
}
;
static
TruitonListFragment
init
(
int
val
)
{
TruitonListFragment
truitonList
=
new
TruitonListFragment
(
)
;
// 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
)
;
}
}
|
In the above class, the only difference is, that ListFragment is used, rest is same as in ImageFragment. It has a static init method which is called from extended Android FragmentPagerAdapter. It uses 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
>
|
After defining all the classes and layouts your app should look like screenshots below
In this tutorial I defined a class which extended FragmentActivity, and instantiated extended version of Android FragmentPagerAdapter and ViewPager. This whole Android FragmentPagerAdapter example is made with support library, hence this would run on all android devices. Again to sum up, I would say that use Android FragmentPagerAdapter only when you have low amount of fragments that you want to keep in memory. Otherwise it will create a memory overhead and affect your app’s performance. This would work even better with non changing fragments. If you still have concerns on which PagerAdapter to use, have a look at Android FragmentPagerAdapter vs FragmentStatePagerAdapter. Hope this helped you out, if it did 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-fragmentpageradapter-example/