(原创)滑动按钮,滑动锁的实现
先上图:
大概就是这种效果,你可以用于滑动解锁,也可以当做个性化的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,就这样简单。