轉載自:http://www.2cto.com/kf/201411/353975.html
札記(5)中介紹了Fragment構建簡單的底部導航欄,在結尾的時候說要在下一節中,結合Viewpager
實現進入軟件時的引導界面,說到ViewPager,很多朋友都用過,不過只知道粘貼複製,連一些基本的
東西都不知道,那是不行的,在本節中就先講下ViewPager的一些基本概念吧!
答:如圖,就是在v4.view包下,另外,ViewPager也是3.0(api 11)後Google推出的,對於低版本的
可以自行導入v4包來解決低版本兼容的問題!
答:ViewPager就是一個頁面切換的組件而已,我們可以往裏面填多個view,然後
我們左右滑動切換不同的view而已,和ListView一樣,我們也需要一個Adapter(適配器),將要顯示
的View和我們的ViewPager進行綁定,而ViewPager有特定的Adapter——PagerAdapter!
另外,Google官方是建議我們使用Fragment來填充ViewPager的,這樣可以更加方便的生成
每個Page以及管理每個Page的生命週期!當然也給我們提供了兩個不同的Adapter!分別是:
FragmentPageAdapter和FragmentStatePagerAdapter,前者適用於頁面較少的情況,後者
適用於頁面較多的情況,,對於兩個Adapter的區別會在後面進行講解!
答:ViewPager和Listview這些組件其實都是類似的,只是前者單位是Page(頁面),後者是Item(項)
而PagerAdapter也是特別的!
先說下簡單的兩個吧:
getCount( ):獲得viewpager中有多少個view
destroyItem( ):移除一個給定位置的頁面。適配器有責任從容器中刪除這個視圖。這是爲了確保
在finishUpdate(viewGroup)返回時視圖能夠被移除。
而另外兩個就涉及到一個key的概念了:
instantiateItem( ):①將給定位置的view添加到ViewGroup(容器)中,創建並顯示出來
②返回一個代表新增頁面的Object(key),通常都是直接返回view本身就可以了,
當然你也可以自定義自己的key,但是key和每個view要一一對應的關係
isViewFromObject( ):判斷instantiateItem(ViewGroup, int)函數所返回來的Key與一個頁面視圖是否是
代表的同一個視圖(即它倆是否是對應的,對應的表示同一個View),通常我們直接寫
return view == object;就可以了,至於爲什麼要這樣講起來比較複雜,後面有機會進行了解吧
貌似是ViewPager中有個存儲view狀態信息的ArrayList,根據View取出對應信息的吧!
Fragment的簡單用法:添加三個View到ViewPager,然後滑動
效果圖如下:
step 1:定義三個佈局,等下用來填充ViewPager的,例子比較簡單,直接用不同TextView與背景顏色來區分
view2,view3只需要copy一下,然後改下顏色與文字就可以了
view1.xml
1
2
3
4
|
<!--?xml version=
1.0
encoding=utf-
8
?-->
<linearlayout android:background=
"#FF6666"
android:gravity=
"center"
android:layout_height=
"match_parent"
android:layout_width=
"match_parent"
android:orientation=
"vertical"
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<textview android:layout_height=
"wrap_content"
android:layout_width=
"wrap_content"
android:text=
"第一個Page"
>
</textview></linearlayout>
|
step 2:主界面佈局文件的編寫,一個TextView + ViewPager,注意ViewPager的標籤:
是這樣的:android.support.v4.view.ViewPager
activity_main.xml:
1
2
3
4
5
6
7
|
<linearlayout android:id=
"@+id/LinearLayout1"
android:layout_height=
"match_parent"
android:layout_width=
"match_parent"
android:orientation=
"vertical"
tools:context=
".MainActivity"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
>
<textview android:background=
"#FCBC12/"
android:gravity=
"center"
android:layout_height=
"40dp"
android:layout_width=
"match_parent"
android:text=
"簡單的ViewPager使用"
>
</android.support.v4.view.viewpager></textview></linearlayout>
|
getCount( ),isViewFormObject( ),instantiateItem( ),destoryItem( ),同時還要定義一個View的
集合,用來放viewpager中的view
MyPagerAdapter.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
|
package
com.jay.example.viewpagerdemo1;
import
java.util.ArrayList;
import
android.support.v4.view.PagerAdapter;
import
android.view.View;
import
android.view.ViewGroup;
public
class
MyPageAdapter
extends
PagerAdapter {
private
ArrayList<view> viewLists;
public
MyPageAdapter() {}
public
MyPageAdapter(ArrayList<view> viewLists)
{
super
();
this
.viewLists = viewLists;
}
@Override
public
int
getCount() {
return
viewLists.size();
}
@Override
public
boolean
isViewFromObject(View view, Object object) {
return
view == object;
}
@Override
public
Object instantiateItem(ViewGroup container,
int
position) {
container.addView(viewLists.get(position));
return
viewLists.get(position);
}
@Override
public
void
destroyItem(ViewGroup container,
int
position, Object object) {
container.removeView(viewLists.get(position));
}
}
</view></view>
|
step 4:最後就是MainActivity了,也很簡單,實例化ViewPager對象以及View集合,然後通過LayoutInflater動態
加載三個view,通過add方法添加到View集合中,接着把View集合作爲參數傳遞給MyPagerAdapter對象,
最後 調用setAdapter(mAdapter);就可以了
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
|
package
com.jay.example.viewpagerdemo1;
import
java.util.ArrayList;
import
android.os.Bundle;
import
android.app.Activity;
import
android.support.v4.view.ViewPager;
import
android.view.LayoutInflater;
import
android.view.View;
public
class
MainActivity
extends
Activity {
//定義相關變量
private
View v1,v2,v3;
private
ViewPager vPager;
private
ArrayList<view> aList;
private
MyPageAdapter mAdapter;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vPager = (ViewPager) findViewById(R.id.viewpager);
//動態加載三個View
LayoutInflater li = getLayoutInflater();
v1 = li.inflate(R.layout.view1,
null
);
v2 = li.inflate(R.layout.view2,
null
);
v3 = li.inflate(R.layout.view3,
null
);
aList =
new
ArrayList<view>();
aList.add(v1);
aList.add(v2);
aList.add(v3);
mAdapter =
new
MyPageAdapter(aList);
vPager.setAdapter(mAdapter);
}
}
</view></view>
|
代碼還是比較簡單的,自己看看應該能明白的~
就是跟隨着ViewPager滑動而滑動的標題咯,這兩個是官方提供的,一個是普通文字,一個是帶有下劃線,以及可以
點擊文字可切換頁面,當然官方的肯定是滿足不了我們的,不過還是得學習下哈,關於自定義標題等下再講
先看下兩個的效果:
效果如圖所示,
PagerTitleStrip只是一個普通的標題,會跟隨Page切換進行切換,
而PagerTabStrip不僅有標題,還有下劃線,另外點擊標題也可以進行頁面的切換,和TabHost有點相似
代碼的話3個view就直接複用上面demo1的東西,然後修改一下佈局文件和MainActivity就可以了:
①PagerTitleStrip的代碼:
activity_main.xml:
1
2
3
4
5
6
7
8
9
10
11
12
|
<linearlayout android:id=
"@+id/LinearLayout1"
android:layout_height=
"match_parent"
android:layout_width=
"match_parent"
android:orientation=
"vertical"
android:paddingbottom=
"@dimen/activity_vertical_margin"
tools:context=
".MainActivity"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
>
<textview android:background=
"#CCFF99"
android:gravity=
"center"
android:layout_height=
"35dp"
android:layout_width=
"match_parent"
android:text=
"PagerTitleStrip效果演示"
>
</android.support.v4.view.pagertitlestrip></android.support.v4.view.viewpager>
</textview></linearlayout>
|
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
|
package
com.jay.example.viewpagerdemo2;
import
java.util.ArrayList;
import
com.jay.example.viewpagerdemo2.MyPageAdapter;
import
android.os.Bundle;
import
android.app.Activity;
import
android.support.v4.view.ViewPager;
import
android.view.LayoutInflater;
import
android.view.View;
public
class
MainActivity
extends
Activity {
//定義相關變量
private
View v1,v2,v3;
private
ViewPager vPager;
private
ArrayList<view> aList;
private
ArrayList<string> sList;
private
MyPageAdapter mAdapter;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vPager = (ViewPager) findViewById(R.id.viewpager);
LayoutInflater li = getLayoutInflater();
v1 = li.inflate(R.layout.view1,
null
);
v2 = li.inflate(R.layout.view2,
null
);
v3 = li.inflate(R.layout.view3,
null
);
aList =
new
ArrayList<view>();
aList.add(v1);
aList.add(v2);
aList.add(v3);
sList =
new
ArrayList<string>();
sList.add(紅色);
sList.add(藍色);
sList.add(黃色);
mAdapter =
new
MyPageAdapter(aList,sList);
vPager.setAdapter(mAdapter);
}
}
</string></view></string></view>
|
②PagerTabStrip的代碼:
activity_main.xml:
1
2
3
4
5
6
7
8
9
10
11
|
<linearlayout android:id=
"@+id/LinearLayout1"
android:layout_height=
"match_parent"
android:layout_width=
"match_parent"
android:orientation=
"vertical"
android:paddingbottom=
"@dimen/activity_vertical_margin"
tools:context=
".MainActivity"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
>
<textview android:background=
"#C0C080"
android:gravity=
"center"
android:layout_height=
"35dp"
android:layout_width=
"match_parent"
android:text=
"PagerTabStrip效果演示"
>
</android.support.v4.view.pagertabstrip></android.support.v4.view.viewpager>
</textview></linearlayout>
|
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
|
package
com.jay.example.viewpagerdemo3;
import
java.util.ArrayList;
import
com.jay.example.viewpagerdemo2.R;
import
com.jay.example.viewpagerdemo3.MyPageAdapter;
import
android.os.Bundle;
import
android.app.Activity;
import
android.support.v4.view.ViewPager;
import
android.view.LayoutInflater;
import
android.view.View;
public
class
MainActivity
extends
Activity {
//定義相關變量
private
View v1,v2,v3;
private
ViewPager vPager;
private
ArrayList<view> aList;
private
ArrayList<string> sList;
private
MyPageAdapter mAdapter;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vPager = (ViewPager) findViewById(R.id.viewpager);
LayoutInflater li = getLayoutInflater();
v1 = li.inflate(R.layout.view1,
null
);
v2 = li.inflate(R.layout.view2,
null
);
v3 = li.inflate(R.layout.view3,
null
);
aList =
new
ArrayList<view>();
aList.add(v1);
aList.add(v2);
aList.add(v3);
sList =
new
ArrayList<string>();
sList.add(紅色);
sList.add(藍色);
sList.add(黃色);
mAdapter =
new
MyPageAdapter(aList,sList);
vPager.setAdapter(mAdapter);
}
}
</string></view></string></view>
|
ps:兩個的實現代碼都是類似的,這裏就不多說了,而且這兩個東西用的也不多,通常情況下都是按
實際需求自己寫一個的,下面給大家演示一個Viewpager實現Tabhost效果的示例吧!
先來看看效果圖咯,正所謂沒圖你說個XX:
下面就來通過代碼來實現上面的效果:
step 1:先完成我們的主界面佈局,三個並列的TextView + 作爲底部移動條的ImageView+ViewPager
activity_main.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<linearlayout android:id=
"@+id/LinearLayout1"
android:layout_height=
"match_parent"
android:layout_width=
"match_parent"
android:orientation=
"vertical"
tools:context=
".MainActivity"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
>
<linearlayout android:background=
"#FFFFFF"
android:id=
"@+id/linearLayout1"
android:layout_height=
"60dp"
android:layout_width=
"fill_parent"
>
<textview android:gravity=
"center"
android:id=
"@+id/text1"
android:layout_height=
"fill_parent"
android:layout_weight=
"1.0"
android:layout_width=
"fill_parent"
android:text=
"紅色"
>
<textview android:gravity=
"center"
android:id=
"@+id/text2"
android:layout_height=
"fill_parent"
android:layout_weight=
"1.0"
android:layout_width=
"fill_parent"
android:text=
"藍色/"
>
<textview android:gravity=
"center"
android:id=
"@+id/text3"
android:layout_height=
"fill_parent"
android:layout_weight=
"1.0"
android:layout_width=
"fill_parent"
android:text=
"黃色"
>
</textview></textview></textview></linearlayout>
<imageview android:id=
"@+id/cursor"
android:layout_height=
"wrap_content"
android:layout_width=
"fill_parent"
android:scaletype=
"matrix"
android:src=
"@drawable/a"
>
</android.support.v4.view.viewpager></imageview></linearlayout>
|
後續會專門對Android中的動畫進行一個總結!
Step 2:自定義一個PageAdapter的適配器,和前面的是一樣的
MyPageAdapter.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
|
package
com.jay.example.viewpagerdemo4;
import
java.util.List;
import
android.support.v4.view.PagerAdapter;
import
android.support.v4.view.ViewPager;
import
android.view.View;
public
class
MyPagerAdapter
extends
PagerAdapter {
public
List<view> mListViews;
public
MyPagerAdapter(List<view> mListViews) {
this
.mListViews = mListViews;
}
@Override
public
void
destroyItem(View arg0,
int
arg1, Object arg2) {
((ViewPager) arg0).removeView(mListViews.get(arg1));
}
@Override
public
int
getCount() {
return
mListViews.size();
}
@Override
public
Object instantiateItem(View arg0,
int
arg1) {
((ViewPager) arg0).addView(mListViews.get(arg1),
0
);
return
mListViews.get(arg1);
}
@Override
public
boolean
isViewFromObject(View arg0, Object arg1) {
return
arg0 == (arg1);
}
}
</view></view>
|
step 4:主Activity的編寫,要完成的事有:
1)相關組件的初始化
2)定義TextView點擊事件的方法,Pager.setCurrentItem(index);設置當前顯示的頁面
3)定義一個初始化移動條位置的方法,移動條的起始位置offset = (屏幕寬度/3 - 移動條寬度)/2;
然後通過Matrix的相關方法設置ImageView的位置
4)定義ViewPager頁面切換事件,先計算出移動一頁與兩頁的偏移量:
一頁 = offset * 2 + 圖片寬度
兩頁 = 一頁 * 2
然後根據哪頁跳哪頁,通過TranslateAnimation設置跳轉動畫即可
代碼如下:
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
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
|
package
com.jay.example.viewpagerdemo4;
import
java.util.ArrayList;
import
java.util.List;
import
android.os.Bundle;
import
android.support.v4.view.ViewPager;
import
android.support.v4.view.ViewPager.OnPageChangeListener;
import
android.util.DisplayMetrics;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.view.animation.Animation;
import
android.view.animation.TranslateAnimation;
import
android.widget.ImageView;
import
android.widget.TextView;
import
android.app.Activity;
import
android.graphics.BitmapFactory;
import
android.graphics.Matrix;
public
class
MainActivity
extends
Activity {
private
ViewPager mPager;
private
List<view> listViews;
private
ImageView cursor;
private
TextView t1, t2, t3;
private
int
offset =
0
;
//移動條圖片的偏移量
private
int
currIndex =
0
;
//當前頁面的編號
private
int
bmpWidth;
// 移動條圖片的長度
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initCursorPos();
initView();
}
//完成View組件的初始化,並將三個view動態地添加到Adapter對象中
//然後調用setAdapter將view集合與ViewPager綁定,設置進去的頁面
//指向第一個頁面setCurrentItem(0),最後設置onclick和onPageChange監聽器
public
void
initView()
{
mPager = (ViewPager) findViewById(R.id.vPager);
t1 = (TextView) findViewById(R.id.text1);
t2 = (TextView) findViewById(R.id.text2);
t3 = (TextView) findViewById(R.id.text3);
listViews =
new
ArrayList<view>();
LayoutInflater mInflater = getLayoutInflater();
listViews.add(mInflater.inflate(R.layout.view1,
null
));
listViews.add(mInflater.inflate(R.layout.view2,
null
));
listViews.add(mInflater.inflate(R.layout.view3,
null
));
mPager.setAdapter(
new
MyPagerAdapter(listViews));
mPager.setCurrentItem(
0
);
t1.setOnClickListener(
new
MyClickListener(
0
));
t2.setOnClickListener(
new
MyClickListener(
1
));
t3.setOnClickListener(
new
MyClickListener(
2
));
mPager.setOnPageChangeListener(
new
MyOnPageChangeListener());
}
//初始化指示器的位置,就是下面那個移動條一開始放的地方
public
void
initCursorPos() {
cursor = (ImageView) findViewById(R.id.cursor);
|