Android 页面滑动切换(类Launcher滑动屏幕实现)
来源:互联网 发布:淘宝精仿 编辑:程序博客网 时间:2024/05/16 14:41
下面的这个例子也是从网上找来的,不是自己写的,一直想学习下,但是一直没有写,以前也研究研究的是launcher的页面跳转,launcher修改--左右滑动屏幕切换源码追踪说实话,那个代码有点复杂,所以理解的也不是很透彻。看到这个例子,比较简单些,再这里学习下:
首先,看下效果图吧:虽然很花哨,都是背景图片。
看下他的布局文件:
01
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
02
<
RelativeLayout
03
android:layout_width
=
"fill_parent"
04
android:layout_height
=
"fill_parent"
05
xmlns:android
=
"http://schemas.android.com/apk/res/android"
>
06
<
com.genius.scroll.MyScrollLayout
07
xmlns:android
=
"http://schemas.android.com/apk/res/android"
08
android:id
=
"@+id/ScrollLayout"
09
android:layout_width
=
"fill_parent"
10
android:layout_height
=
"fill_parent"
>
11
<
FrameLayout
12
android:background
=
"@drawable/guide01"
13
android:layout_width
=
"fill_parent"
14
android:layout_height
=
"fill_parent"
>
15
</
FrameLayout
>
16
<
FrameLayout
17
android:background
=
"@drawable/guide02"
18
android:layout_width
=
"fill_parent"
19
android:layout_height
=
"fill_parent"
>
20
</
FrameLayout
>
21
<
FrameLayout
22
android:background
=
"@drawable/guide03"
23
android:layout_width
=
"fill_parent"
24
android:layout_height
=
"fill_parent"
>
25
</
FrameLayout
>
26
<
FrameLayout
27
android:background
=
"@drawable/guide04"
28
android:layout_width
=
"fill_parent"
29
android:layout_height
=
"fill_parent"
>
30
</
FrameLayout
>
31
<
FrameLayout
32
android:background
=
"@drawable/guide05"
33
android:layout_width
=
"fill_parent"
34
android:layout_height
=
"fill_parent"
>
35
</
FrameLayout
>
36
</
com.genius.scroll.MyScrollLayout
>
37
<
LinearLayout
38
android:orientation
=
"horizontal"
39
android:id
=
"@+id/llayout"
40
android:layout_width
=
"wrap_content"
41
android:layout_height
=
"wrap_content"
42
android:layout_marginBottom
=
"24.0dip"
43
android:layout_alignParentBottom
=
"true"
44
android:layout_centerHorizontal
=
"true"
>
45
<
ImageView
android:clickable
=
"true"
46
android:padding
=
"15.0dip"
47
android:layout_gravity
=
"center_vertical"
48
android:layout_width
=
"wrap_content"
49
android:layout_height
=
"wrap_content"
50
android:src
=
"@drawable/guide_round"
/>
51
<
ImageView
android:clickable
=
"true"
52
android:padding
=
"15.0dip"
53
android:layout_gravity
=
"center_vertical"
54
android:layout_width
=
"wrap_content"
55
android:layout_height
=
"wrap_content"
56
android:src
=
"@drawable/guide_round"
/>
57
<
ImageView
android:clickable
=
"true"
58
android:padding
=
"15.0dip"
59
android:layout_gravity
=
"center_vertical"
60
android:layout_width
=
"wrap_content"
61
android:layout_height
=
"wrap_content"
62
android:src
=
"@drawable/guide_round"
/>
63
<
ImageView
android:clickable
=
"true"
64
android:padding
=
"15.0dip"
65
android:layout_gravity
=
"center_vertical"
66
android:layout_width
=
"wrap_content"
67
android:layout_height
=
"wrap_content"
68
android:src
=
"@drawable/guide_round"
/>
69
<
ImageView
android:clickable
=
"true"
70
android:padding
=
"15.0dip"
71
android:layout_gravity
=
"center_vertical"
72
android:layout_width
=
"wrap_content"
73
android:layout_height
=
"wrap_content"
74
android:src
=
"@drawable/guide_round"
/>
75
</
LinearLayout
>
76
</
RelativeLayout
>
底部的LinearLayout是放了5个按钮,上面使用到了一个自定义的控件:MyScrollLayout下面再看下这个自定义控件:里面使用frameLayout放了5张图片。
001
public
class
MyScrollLayout
extends
ViewGroup{
002
003
private
static
final
String TAG =
"ScrollLayout"
;
004
private
VelocityTracker mVelocityTracker;
// 用于判断甩动手势
005
private
static
final
int
SNAP_VELOCITY =
600
;
006
private
Scroller mScroller;
// 滑动控制器
007
private
int
mCurScreen;
008
private
int
mDefaultScreen =
0
;
009
private
float
mLastMotionX;
010
011
private
OnViewChangeListener mOnViewChangeListener;
012
public
MyScrollLayout(Context context) {
013
super
(context);
014
init(context);
015
}
016
public
MyScrollLayout(Context context, AttributeSet attrs) {
017
super
(context, attrs);
018
init(context);
019
}
020
public
MyScrollLayout(Context context, AttributeSet attrs,
int
defStyle) {
021
super
(context, attrs, defStyle);
022
init(context);
023
}
024
private
void
init(Context context)
025
{
026
mCurScreen = mDefaultScreen;
027
mScroller =
new
Scroller(context);
028
}
029
030
@Override
031
protected
void
onLayout(
boolean
changed,
int
l,
int
t,
int
r,
int
b) {
032
// TODO Auto-generated method stub
033
if
(changed) {
034
int
childLeft =
0
;
035
final
int
childCount = getChildCount();
036
for
(
int
i=
0
; i<childCount; i++) {
037
final
View childView = getChildAt(i);
038
if
(childView.getVisibility() != View.GONE) {
039
final
int
childWidth = childView.getMeasuredWidth();
040
childView.layout(childLeft,
0
,
041
childLeft+childWidth, childView.getMeasuredHeight());
042
childLeft += childWidth;
043
}
044
}
045
}
046
}
047
048
@Override
049
protected
void
onMeasure(
int
widthMeasureSpec,
int
heightMeasureSpec) {
050
// TODO Auto-generated method stub
051
super
.onMeasure(widthMeasureSpec, heightMeasureSpec);
052
final
int
width = MeasureSpec.getSize(widthMeasureSpec);
053
final
int
widthMode = MeasureSpec.getMode(widthMeasureSpec);
054
final
int
count = getChildCount();
055
for
(
int
i =
0
; i < count; i++) {
056
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
057
}
058
scrollTo(mCurScreen * width,
0
);
059
}
060
061
public
void
snapToDestination() {
062
final
int
screenWidth = getWidth();
063
final
int
destScreen = (getScrollX()+ screenWidth/
2
)/screenWidth;
064
snapToScreen(destScreen);
065
}
066
067
public
void
snapToScreen(
int
whichScreen) {
068
// get the valid layout page
069
whichScreen = Math.max(
0
, Math.min(whichScreen, getChildCount()-
1
));
070
if
(getScrollX() != (whichScreen*getWidth())) {
071
final
int
delta = whichScreen*getWidth()-getScrollX();
072
mScroller.startScroll(getScrollX(),
0
,
073
delta,
0
, Math.abs(delta)*
2
);
074
mCurScreen = whichScreen;
075
invalidate();
// Redraw the layout
076
if
(mOnViewChangeListener !=
null
)
077
{
078
mOnViewChangeListener.OnViewChange(mCurScreen);
079
}
080
}
081
}
082
083
@Override
084
public
void
computeScroll() {
085
// TODO Auto-generated method stub
086
if
(mScroller.computeScrollOffset()) {
087
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
088
postInvalidate();
089
}
090
}
091
092
@Override
093
public
boolean
onTouchEvent(MotionEvent event) {
094
// TODO Auto-generated method stub
095
final
int
action = event.getAction();
096
final
float
x = event.getX();
097
final
float
y = event.getY();
098
switch
(action) {
099
case
MotionEvent.ACTION_DOWN:
100
Log.i(
""
,
"onTouchEvent ACTION_DOWN"
);
101
if
(mVelocityTracker ==
null
) {
102
mVelocityTracker = VelocityTracker.obtain();
103
mVelocityTracker.addMovement(event);
104
}
105
if
(!mScroller.isFinished()){
106
mScroller.abortAnimation();
107
}
108
mLastMotionX = x;
109
break
;
110
case
MotionEvent.ACTION_MOVE:
111
int
deltaX = (
int
)(mLastMotionX - x);
112
if
(IsCanMove(deltaX)){
113
if
(mVelocityTracker !=
null
){
114
mVelocityTracker.addMovement(event);
115
}
116
mLastMotionX = x;
117
scrollBy(deltaX,
0
);
118
}
119
break
;
120
case
MotionEvent.ACTION_UP:
121
int
velocityX =
0
;
122
if
(mVelocityTracker !=
null
){
123
mVelocityTracker.addMovement(event);
124
mVelocityTracker.computeCurrentVelocity(
1000
);
125
velocityX = (
int
) mVelocityTracker.getXVelocity();
126
}
127
if
(velocityX > SNAP_VELOCITY && mCurScreen >
0
) {
128
Log.e(TAG,
"snap left"
);
129
snapToScreen(mCurScreen -
1
);
130
}
else
if
(velocityX < -SNAP_VELOCITY
131
&& mCurScreen < getChildCount() -
1
) {
132
Log.e(TAG,
"snap right"
);
133
snapToScreen(mCurScreen +
1
);
134
}
else
{
135
snapToDestination();
136
}
137
if
(mVelocityTracker !=
null
) {
138
mVelocityTracker.recycle();
139
mVelocityTracker =
null
;
140
}
141
break
;
142
}
143
return
true
;
144
}
145
146
private
boolean
IsCanMove(
int
deltaX)
147
{
148
if
(getScrollX() <=
0
&& deltaX <
0
){
149
return
false
;
150
}
151
if
(getScrollX() >= (getChildCount() -
1
) * getWidth() && deltaX >
0
){
152
return
false
;
153
}
154
return
true
;
155
}
156
157
public
void
SetOnViewChangeListener(OnViewChangeListener listener)
158
{
159
mOnViewChangeListener = listener;
160
}
161
}
首先注意,他继承了ViewGroup类,在这里面主要重写了onMeasure()、onTouchEvent()等方法,在这里使用了一个自定义的接口private OnViewChangeListener mOnViewChangeListener。看下它的定义:
1
public
interface
OnViewChangeListener {
2
public
void
OnViewChange(
int
view);
3
}
这个接口里之定义了一个回调方法:OnViewChange()这个方法的具体实现,是在主Activity中:
01
public
class
SwitchViewDemoActivity
extends
Activity
implements
OnViewChangeListener, OnClickListener{
02
/** Called when the activity is first created. */
03
04
private
MyScrollLayout mScrollLayout;
05
private
ImageView[] mImageViews;
06
private
int
mViewCount;
07
private
int
mCurSel;
08
09
@Override
10
public
void
onCreate(Bundle savedInstanceState) {
11
super
.onCreate(savedInstanceState);
12
setContentView(R.layout.main);
13
init();
14
}
15
16
private
void
init()
17
{
18
mScrollLayout = (MyScrollLayout) findViewById(R.id.ScrollLayout);
19
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.llayout);
20
mViewCount = mScrollLayout.getChildCount();
21
mImageViews =
new
ImageView[mViewCount];
22
for
(
int
i =
0
; i < mViewCount; i++) {
23
mImageViews[i] = (ImageView) linearLayout.getChildAt(i);
24
mImageViews[i].setEnabled(
true
);
25
mImageViews[i].setOnClickListener(
this
);
26
mImageViews[i].setTag(i);
27
}
28
mCurSel =
0
;
29
mImageViews[mCurSel].setEnabled(
false
);
30
mScrollLayout.SetOnViewChangeListener(
this
);
31
}
32
33
private
void
setCurPoint(
int
index)
34
{
35
if
(index <
0
|| index > mViewCount -
1
|| mCurSel == index) {
36
return
;
37
}
38
mImageViews[mCurSel].setEnabled(
true
);
39
mImageViews[index].setEnabled(
false
);
40
mCurSel = index;
41
}
42
43
@Override
44
public
void
OnViewChange(
int
view) {
45
// TODO Auto-generated method stub
46
setCurPoint(view);
47
}
48
49
@Override
50
public
void
onClick(View v) {
51
// TODO Auto-generated method stub
52
int
pos = (Integer)(v.getTag());
53
setCurPoint(pos);
54
mScrollLayout.snapToScreen(pos);
55
}
56
}
这个OnViewChange()方法,主要调用了setCurPoint()方法,就是完成界面的跳转。在MyScrollLayout中的snapToScreen()方法中就是典型的回调方法:
01
public
void
snapToScreen(
int
whichScreen) {
02
// get the valid layout page
03
whichScreen = Math.max(
0
, Math.min(whichScreen, getChildCount()-
1
));
04
if
(getScrollX() != (whichScreen*getWidth())) {
05
final
int
delta = whichScreen*getWidth()-getScrollX();
06
mScroller.startScroll(getScrollX(),
0
,
07
delta,
0
, Math.abs(delta)*
2
);
08
mCurScreen = whichScreen;
09
invalidate();
// Redraw the layout
10
if
(mOnViewChangeListener !=
null
)
11
{
12
mOnViewChangeListener.OnViewChange(mCurScreen);
13
}
14
}
15
}
1
mOnViewChangeListener.OnViewChange(mCurScreen);
这句代码就是典型的回调。
在MyScrollLayout的onTouchEvent()的方法里面是对触屏事件做出的响应:
01
final
int
action = event.getAction();
02
final
float
x = event.getX();
03
final
float
y = event.getY();
04
switch
(action) {
05
case
MotionEvent.ACTION_DOWN:
06
Log.i(
""
,
"onTouchEvent ACTION_DOWN"
);
07
if
(mVelocityTracker ==
null
) {
08
mVelocityTracker = VelocityTracker.obtain();
09
mVelocityTracker.addMovement(event);
10
}
11
if
(!mScroller.isFinished()){
12
mScroller.abortAnimation();
13
}
14
mLastMotionX = x;
15
break
;
16
case
MotionEvent.ACTION_MOVE:
17
int
deltaX = (
int
)(mLastMotionX - x);
18
if
(IsCanMove(deltaX)){
19
if
(mVelocityTracker !=
null
){
20
mVelocityTracker.addMovement(event);
21
}
22
mLastMotionX = x;
23
scrollBy(deltaX,
0
);
24
}
25
break
;
26
case
MotionEvent.ACTION_UP:
27
int
velocityX =
0
;
28
if
(mVelocityTracker !=
null
){
29
mVelocityTracker.addMovement(event);
30
mVelocityTracker.computeCurrentVelocity(
1000
);
31
velocityX = (
int
) mVelocityTracker.getXVelocity();
32
}
33
if
(velocityX > SNAP_VELOCITY && mCurScreen >
0
) {
34
Log.e(TAG,
"snap left"
);
35
snapToScreen(mCurScreen -
1
);
36
}
else
if
(velocityX < -SNAP_VELOCITY
37
&& mCurScreen < getChildCount() -
1
) {
38
Log.e(TAG,
"snap right"
);
39
snapToScreen(mCurScreen +
1
);
40
}
else
{
41
snapToDestination();
42
}
43
if
(mVelocityTracker !=
null
) {
44
mVelocityTracker.recycle();
45
mVelocityTracker =
null
;
46
}
47
break
;
48
}
通过判断移动距离和移动方向做出不同的响应。
其他的代码都比较好懂了,有什么问题欢迎大家讨论,下面是代码的下载地址:
http://download.csdn.net/detail/aomandeshangxiao/4017928
- Android 页面滑动切换(类Launcher滑动屏幕实现)
- Android 页面滑动切换(类Launcher滑动屏幕实现)
- 页面滑动切换(类Launcher滑动屏幕实现)
- 页面滑动切换(类Launcher滑动屏幕实现)
- 页面滑动切换(类Launcher滑动屏幕实现)
- 页面滑动切换(类Launcher滑动屏幕实现)
- 使用ViewPage实现类launcher屏幕滑动
- 使用ViewPage实现类launcher屏幕滑动
- 使用ViewPage实现类launcher屏幕滑动
- 使用ViewPage实现类launcher屏幕滑动
- JQuery Mobile实现滑动屏幕切换页面
- Android 滑动切换页面 以及屏幕手势
- Android 滑动切换页面 以及屏幕手势
- Android 滑动切换页面 以及屏幕手势
- Android 滑动切换页面 以及屏幕手势
- Android 滑动切换页面 以及屏幕手势
- Android 滑动切换页面 以及屏幕手势
- Android 滑动切换页面 以及屏幕手势
- (转)clipRect 介绍
- c#数据类型与所对应的类
- extjs单行编辑RowEditing修改后台部分的东西后呈现的效果
- ubuntu学习系列
- hdu 2152 Fruit
- Android 页面滑动切换(类Launcher滑动屏幕实现)
- ARM嵌入式Linux系统构造与驱动认知
- 编译和链接的区别
- HDU 2206 IP的计算 字符串
- Apache Shiro 集成-Cas
- MATLAB2013a下载地址
- 浅谈C#堆栈与托管堆的工作方式
- magento 添加支付方式
- 什么是句柄??