滑动按钮,滑动锁的实现
先上图:
大概就是这种效果,你可以用于滑动解锁,也可以当做个性化的Button来用
这个我已经进行了封装,可以直接在xml中进行编写,然后在activity中重写ontouch方法进行button的判断即可,不用你再调整任何东西,
滑动什么的都是自动适配的
我把这种Button命名为SlidingButton,先看一下代码吧,都是非常简单易用的:
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
|
package
com.test.slidingbutton;
import
android.content.Context;
import
android.util.AttributeSet;
import
android.util.Log;
import
android.view.MotionEvent;
import
android.view.animation.AccelerateInterpolator;
import
android.view.animation.Animation;
import
android.view.animation.Interpolator;
import
android.view.animation.TranslateAnimation;
import
android.view.animation.Animation.AnimationListener;
import
android.widget.Button;
import
android.widget.FrameLayout;
import
android.widget.LinearLayout;
public
class
SlidingButton
extends
Button {
public
SlidingButton(Context context, AttributeSet attrs,
int
defStyle) {
super
(context, attrs, defStyle);
}
public
SlidingButton(Context context) {
super
(context);
}
private
boolean
isMe =
false
;
public
boolean
isMe() {
return
isMe;
}
public
void
setMe(
boolean
isMe) {
this
.isMe = isMe;
}
public
SlidingButton(Context context, AttributeSet attrs) {
super
(context, attrs);
}
@Override
public
boolean
onTouchEvent(MotionEvent event) {
if
(event.getAction() == MotionEvent.ACTION_DOWN) {
isMe =
true
;
}
else
if
(event.getAction() == MotionEvent.ACTION_UP) {
isMe =
false
;
}
return
false
;
}
public
boolean
handleActivityEvent(MotionEvent activityEvent) {
boolean
result =
false
;
if
(isMe()) {
if
(activityEvent.getAction() == MotionEvent.ACTION_UP) {
// Log.v("yupeng", "frame left" + ((FrameLayout)this.getParent().getParent()).getLeft());
// Log.v("yupeng", "my left" + this.getLeft());
// Log.v("yupeng", "touch " + this.getLeft());
if
(
this
.getLeft() +
this
.getWidth()/
2
> ((FrameLayout)
this
.getParent().getParent()).getWidth() -
this
.getWidth()){
//用户完成了选择动作
Log.v(
"yupeng"
,
"sliding true"
);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
this
.getLayoutParams();
lp.leftMargin =
0
;
this
.setLayoutParams(lp);
this
.setMe(
false
);
result =
true
;
}
else
{
TranslateAnimation trans =
new
TranslateAnimation(
Animation.ABSOLUTE,
0
,
Animation.ABSOLUTE,-
this
.getLeft(), Animation.RELATIVE_TO_SELF,
0
,
Animation.RELATIVE_TO_SELF,
0
);
// trans.setStartOffset(0);
trans.setDuration(
600
);
// trans.setFillAfter(true);
trans.setInterpolator(
new
AccelerateInterpolator());
trans.setInterpolator(
new
Interpolator() {
@Override
public
float
getInterpolation(
float
input) {
// TODO Auto-generated method stub
return
0
;
}
});
trans.setAnimationListener(
new
SlidingAnimationListener(
this
));
startAnimation(trans);
}
}
else
{
// 还在拖动
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) getLayoutParams();
// Log.v("yupeng", "yu" + lp.leftMargin);
lp.leftMargin = (
int
) (activityEvent.getX() - ((FrameLayout)
this
.getParent().getParent()).getLeft()) -
this
.getWidth()/
2
;
if
(lp.leftMargin >
0
&& lp.leftMargin < ((FrameLayout)
this
.getParent().getParent()).getWidth() -
this
.getWidth()) {
setLayoutParams(lp);
}
}
}
return
result;
}
private
static
class
SlidingAnimationListener
implements
AnimationListener {
private
SlidingButton but;
public
SlidingAnimationListener(SlidingButton button) {
this
.but = button;
}
@Override
public
void
onAnimationEnd(Animation animation) {
rePosition();
but.setMe(
false
);
but.clearAnimation();
}
private
void
rePosition() {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) but
.getLayoutParams();
lp.leftMargin =
0
;
but.setLayoutParams(lp);
}
@Override
public
void
onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public
void
onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
}
}
|
SlidingButton是集成了Button,重写onTouchEvent方法,但是这里的ontouchEvent里只是判断是否touch了自己,如果是
则把自己的boolean isMe这个变量置为true,然后在activity中执行SlidingButton的handleActivityEvent方法,handleActivityEvent方法
来判断是否滑动,以及是否滑动到了进度条的末端,如果是则返回Boolean告诉调用者结果,如果没有,则触发动画滑回去
1
2
3
4
5
|
lp.leftMargin = (
int
) (activityEvent.getX() - ((FrameLayout)
this
.getParent().getParent()).getLeft()) -
this
.getWidth()/
2
;
if
(lp.leftMargin >
0
&& lp.leftMargin < ((FrameLayout)
this
.getParent().getParent()).getWidth() -
this
.getWidth()) {
setLayoutParams(lp);
}
|
再看Activity的代码:
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
|
package
com.test.slidingbutton;
import
android.app.Activity;
import
android.os.Bundle;
import
android.util.Log;
import
android.view.MotionEvent;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.widget.Button;
import
android.widget.FrameLayout;
import
android.widget.LinearLayout;
import
android.widget.Toast;
public
class
SlidingButtonActivity
extends
Activity {
private
SlidingButton mSlidingButton;
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSlidingButton = (SlidingButton)
this
.findViewById(R.id.mainview_answer_1_button);
}
@Override
public
boolean
onTouchEvent(MotionEvent event) {
if
(mSlidingButton.handleActivityEvent(event)) {
Toast.makeText(SlidingButtonActivity.
this
,
"touch"
,
1
).show();
}
return
super
.onTouchEvent(event);
}
}
|
这就不用解释了吧?要是看不懂你就放弃吧…
需要注意的是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
|
<FrameLayout
android:layout_width=
"250dip"
android:layout_height=
"60dip"
android:layout_gravity=
"center"
>
<TextView
android:id=
"@+id/mainview_answer_1"
android:layout_width=
"fill_parent"
android:layout_height=
"fill_parent"
android:background=
"@drawable/w_bg1"
android:gravity=
"center"
android:paddingLeft=
"35dip"
android:text=
"滑动按钮测试"
android:textColor=
"#FFFFFF"
android:textSize=
"18sp"
/>
<!-- 此处,滑动按钮的父亲组件不能为FrameLayout -->
<LinearLayout
android:layout_width=
"fill_parent"
android:layout_height=
"fill_parent"
>
<com.test.slidingbutton.SlidingButton
android:id=
"@+id/mainview_answer_1_button"
android:layout_width=
"wrap_content"
android:layout_height=
"fill_parent"
android:background=
"@drawable/bn_jt1"
android:gravity=
"center"
/>
</LinearLayout>
</FrameLayout>
|
最外层一定要用FrameLayout,因为在SlidingButton中我一路找到它的父类并把它强转为了FrameLayout,你自己如果
愿意改也可以。
ok,就这样简单。