先上图:
大概就是这种效果,你可以用于滑动解锁,也可以当做个性化的Button来用
这个我已经进行了封装,可以直接在xml中进行编写,然后在activity中重写ontouch方法进行button的判断即可,不用你再调整任何东西,
滑动什么的都是自动适配的
我把这种Button命名为SlidingButton,先看一下代码吧,都是非常简单易用的:
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告诉调用者结果,如果没有,则触发动画滑回去
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的代码:
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文件:
<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,就这样简单。