在项目中,我们常常需要实现界面滑动切换的效果。例如,微信界面的左右滑动切换效果。那这种效果是怎么实现的?今天我就带大家简单了解ViewPager,并通过实例来实现该效果。
一. ViewPager 官方API
首先我们来看一下ViewPager官方给出的解释,如图:
具体意思如下:
Layout 管理器允许用户可以在页面上,左右滑动来翻动页面。你可以考虑实现PagerAdapter接口来显示该效果。
ViewPager很多时候会结合Fragment一块使用,这种方法使得管理每个页面的生命周期变得很方便。其中,有一些adapter的具体实现,可以适合于这种ViewPager结合Fragment使用的情况。这些adapter包括:FragmentPagerAdapter,和 FragmentStatePagerAdapter。
而本文就是通过ViewPager结合Fragment利用FragmentpagerAdapter适配器来实现左右滑动的效果。
二.效果如下:
三.代码实现:
1.xml布局文件
1>主布局activity_main.xml
1
2
3
4
5
6
7
8
|
<span style=
"font-family:Microsoft"
><linearlayout android:layout_height=
"match_parent"
android:layout_width=
"match_parent"
android:orientation=
"vertical"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
>
<include layout=
"@layout/activity_main_top_tab"
>
</android.support.v4.view.viewpager>
</include></linearlayout></span>
|
2>顶部导航activity_main_top_tab.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
|
<span style=
"font-family:Microsoft"
><linearlayout android:layout_height=
"wrap_content"
android:layout_width=
"match_parent"
android:orientation=
"vertical"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
>
<linearlayout android:baselinealigned=
"false"
android:id=
"@+id/id_switch_tab_ll"
android:layout_height=
"wrap_content"
android:layout_width=
"match_parent"
android:orientation=
"horizontal"
>
<linearlayout android:background=
"@drawable/guide_round_selector"
android:gravity=
"center"
android:id=
"@+id/id_tab_chat_ll"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:layout_width=
"match_parent"
android:orientation=
"horizontal"
android:padding=
"10dip"
>
<textview android:gravity=
"center"
android:id=
"@+id/id_chat_tv"
android:layout_height=
"wrap_content"
android:layout_width=
"wrap_content"
android:text=
"聊天"
android:textcolor=
"#0000FF"
android:textsize=
"15dip"
>
</textview></linearlayout>
<linearlayout android:background=
"@drawable/guide_round_selector"
android:clickable=
"true"
android:gravity=
"center"
android:id=
"@+id/id_tab_friend_ll"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:layout_width=
"match_parent"
android:orientation=
"horizontal"
android:padding=
"10dip"
android:saveenabled=
"false"
>
<textview android:gravity=
"center"
android:id=
"@+id/id_friend_tv"
android:layout_height=
"wrap_content"
android:layout_width=
"wrap_content"
android:text=
"好友"
android:textcolor=
"#000000"
android:textsize=
"15dip"
>
</textview></linearlayout>
<linearlayout android:background=
"@drawable/guide_round_selector"
android:focusable=
"false"
android:gravity=
"center"
android:id=
"@+id/id_tab_contacts_ll"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:layout_width=
"match_parent"
android:orientation=
"horizontal"
android:padding=
"10dip"
>
<textview android:gravity=
"center"
android:id=
"@+id/id_contacts_tv"
android:layout_height=
"wrap_content"
android:layout_width=
"wrap_content"
android:text=
"通讯录"
android:textcolor=
"#000000"
android:textsize=
"15dip"
>
</textview></linearlayout>
</linearlayout>
<imageview android:background=
"@drawable/tab_selected_pressed_holo"
android:contentdescription=
"tab"
android:id=
"@+id/id_tab_line_iv"
android:layout_height=
"wrap_content"
android:layout_width=
"200dp"
>
</imageview>
<view android:background=
"#000000"
android:layout_height=
"1dp"
android:layout_width=
"match_parent"
>
</view></linearlayout></span>
|
3>Fragment显示布局activity_tab_chat.xml,activity_tab_contacts.xml,activity_tab_friend.xml(只给出一个,其他类似)
1
2
3
4
5
|
<span style=
"font-family:Microsoft"
><linearlayout android:layout_height=
"match_parent"
android:layout_width=
"match_parent"
android:orientation=
"vertical"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
>
<textview android:gravity=
"center"
android:layout_height=
"match_parent"
android:layout_width=
"match_parent"
android:text=
"聊天界面"
android:textcolor=
"#FF0000"
android:textsize=
"20sp"
></textview>
</linearlayout></span>
|
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
<span style=
"font-family:Microsoft"
>
package
com.example.viewpagerdemo;
import
java.util.ArrayList;
import
java.util.List;
import
android.graphics.Color;
import
android.os.Bundle;
import
android.support.v4.app.Fragment;
import
android.support.v4.app.FragmentActivity;
import
android.support.v4.view.ViewPager;
import
android.support.v4.view.ViewPager.OnPageChangeListener;
import
android.util.DisplayMetrics;
import
android.util.Log;
import
android.widget.ImageView;
import
android.widget.LinearLayout;
import
android.widget.TextView;
public
class
MainActivity
extends
FragmentActivity {
private
List<fragment> mFragmentList =
new
ArrayList<fragment>();
private
FragmentAdapter mFragmentAdapter;
private
ViewPager mPageVp;
/**
* Tab显示内容TextView
*/
private
TextView mTabChatTv, mTabContactsTv, mTabFriendTv;
/**
* Tab的那个引导线
*/
private
ImageView mTabLineIv;
/**
* Fragment
*/
private
ChatFragment mChatFg;
private
FriendFragment mFriendFg;
private
ContactsFragment mContactsFg;
/**
* ViewPager的当前选中页
*/
private
int
currentIndex;
/**
* 屏幕的宽度
*/
private
int
screenWidth;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findById();
init();
initTabLineWidth();
}
private
void
findById() {
mTabContactsTv = (TextView)
this
.findViewById(R.id.id_contacts_tv);
mTabChatTv = (TextView)
this
.findViewById(R.id.id_chat_tv);
mTabFriendTv = (TextView)
this
.findViewById(R.id.id_friend_tv);
mTabLineIv = (ImageView)
this
.findViewById(R.id.id_tab_line_iv);
mPageVp = (ViewPager)
this
.findViewById(R.id.id_page_vp);
}
private
void
init() {
mFriendFg =
new
FriendFragment();
mContactsFg =
new
ContactsFragment();
mChatFg =
new
ChatFragment();
mFragmentList.add(mChatFg);
mFragmentList.add(mFriendFg);
mFragmentList.add(mContactsFg);
mFragmentAdapter =
new
FragmentAdapter(
this
.getSupportFragmentManager(), mFragmentList);
mPageVp.setAdapter(mFragmentAdapter);
mPageVp.setCurrentItem(
0
);
mPageVp.setOnPageChangeListener(
new
OnPageChangeListener() {
/**
* state滑动中的状态 有三种状态(0,1,2) 1:正在滑动 2:滑动完毕 0:什么都没做。
*/
@Override
public
void
onPageScrollStateChanged(
int
state) {
}
/**
* position :当前页面,及你点击滑动的页面 offset:当前页面偏移的百分比
* offsetPixels:当前页面偏移的像素位置
*/
@Override
public
void
onPageScrolled(
int
position,
float
offset,
int
offsetPixels) {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mTabLineIv
.getLayoutParams();
Log.e(offset:, offset + );
/**
* 利用currentIndex(当前所在页面)和position(下一个页面)以及offset来
* 设置mTabLineIv的左边距 滑动场景:
* 记3个页面,
* 从左到右分别为0,1,2
* 0->1; 1->2; 2->1; 1->0
*/
if
(currentIndex ==
0
&& position ==
0
)
// 0->1
{
lp.leftMargin = (
int
) (offset * (screenWidth *
1.0
/
3
) + currentIndex
* (screenWidth /
3
));
}
else
if
(currentIndex ==
1
&& position ==
0
)
// 1->0
{
lp.leftMargin = (
int
) (-(
1
- offset)
* (screenWidth *
1.0
/
3
) + currentIndex
* (screenWidth /
3
));
}
else
if
(currentIndex ==
1
&& position ==
1
)
// 1->2
{
lp.leftMargin = (
int
) (offset * (screenWidth *
1.0
/
3
) + currentIndex
* (screenWidth /
3
));
}
else
if
(currentIndex ==
2
&& position ==
1
)
// 2->1
{
lp.leftMargin = (
int
) (-(
1
- offset)
* (screenWidth *
1.0
/
3
) + currentIndex
* (screenWidth /
3
));
}
mTabLineIv.setLayoutParams(lp);
}
@Override
public
void
onPageSelected(
int
position) {
resetTextView();
switch
(position) {
case
0
:
mTabChatTv.setTextColor(Color.BLUE);
break
;
case
1
:
mTabFriendTv.setTextColor(Color.BLUE);
break
;
case
2
:
mTabContactsTv.setTextColor(Color.BLUE);
break
;
}
currentIndex = position;
}
});
}
/**
* 设置滑动条的宽度为屏幕的1/3(根据Tab的个数而定)
*/
private
void
initTabLineWidth() {
DisplayMetrics dpMetrics =
new
DisplayMetrics();
getWindow().getWindowManager().getDefaultDisplay()
.getMetrics(dpMetrics);
screenWidth = dpMetrics.widthPixels;
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mTabLineIv
.getLayoutParams();
lp.width = screenWidth /
3
;
mTabLineIv.setLayoutParams(lp);
}
/**
* 重置颜色
*/
private
void
resetTextView() {
mTabChatTv.setTextColor(Color.BLACK);
mTabFriendTv.setTextColor(Color.BLACK);
mTabContactsTv.setTextColor(Color.BLACK);
}
}
</fragment></fragment></span>
|
注意:
1.MainActivity继承于FragmentActivity;
2.初始化导航条的宽度:initTabLineWidth(),由于本例给出的是3个界面切换,固长度为整个屏幕宽度的1/3;
3.监听事件OnPageChangeListener的onPageScrolled方法主要捕捉滑动事件;
其中给出了3个参数所表示的意义。根据滑动的4中变化(左-中-右-中-左),给出导航条距离左边的边距,显示导航条滑动的效果。
5>Fragment适配器FragmentAdapter,继承于FragmentPagerAdapter
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
|
<span style=
"font-family:Microsoft"
>
package
com.example.viewpagerdemo;
import
java.util.ArrayList;
import
java.util.List;
import
android.support.v4.app.Fragment;
import
android.support.v4.app.FragmentManager;
import
android.support.v4.app.FragmentPagerAdapter;
public
class
FragmentAdapter
extends
FragmentPagerAdapter {
List<fragment> fragmentList =
new
ArrayList<fragment>();
public
FragmentAdapter(FragmentManager fm,List<fragment> fragmentList) {
super
(fm);
this
.fragmentList = fragmentList;
}
@Override
public
Fragment getItem(
int
position) {
return
fragmentList.get(position);
}
@Override
public
int
getCount() {
return
fragmentList.size();
}
}
</fragment></fragment></fragment></span>
|
6>Fragment显示函数ChatFragment.java,ContactsFragment.java,FriendFragment.java(只给出一个,其他类似)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<span style=
"font-family:Microsoft"
>
package
com.example.viewpagerdemo;
import
android.os.Bundle;
import
android.support.v4.app.Fragment;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.view.ViewGroup;
public
class
ChatFragment
extends
Fragment {
@Override
public
View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
super
.onCreateView(inflater, container, savedInstanceState);
View chatView = inflater.inflate(R.layout.activity_tab_chat, container,
false
);
return
chatView;
}
@Override
public
void
onActivityCreated(Bundle savedInstanceState){
super
.onActivityCreated(savedInstanceState);
}
}
</span>
|