public class PullDoorView extends RelativeLayout {
private Context mContext;
private Scroller mScroller;
private int mScreenHeight = 0;
private int mLastDownY = 0;
private int mCurryY;
private int mDelY;
private boolean mCloseFlag = false;
private TextView mTvHint;
private LockListen mLockListen;
public PullDoorView(Context context) {
super(context);
this.mContext = context;
initView();
}
public PullDoorView(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
initView();
}
public PullDoorView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
initView();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public PullDoorView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
this.mContext = context;
initView();
}
private void initView() {
// Interpolator 设置插值器 可弹跳
Interpolator polator = new BounceInterpolator();
mScroller = new Scroller(mContext, polator);
// 获取屏幕分辨率
WindowManager wm = (WindowManager) (mContext
.getSystemService(Context.WINDOW_SERVICE));
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
mScreenHeight = dm.heightPixels;
// 这里你一定要设置成透明背景,不然会影响你看到底层布局
this.setBackgroundColor(Color.argb(0, 0, 0, 0));
Drawable drawableLeft = getResources().getDrawable(
R.drawable.ic_launcher);
mTvHint = new TextView(mContext);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.bottomMargin = (int) mContext.getResources().getDimension(R.dimen.y20); //这里我用到了自定义的屏幕适配 可以改成其他长度类型的数值
params.addRule(RelativeLayout.CENTER_HORIZONTAL, -1);//-1 表示相对于父控件的位置
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, -1);
mTvHint.setText("上滑解锁");
mTvHint.setTextColor(Color.WHITE);
mTvHint.setCompoundDrawablesWithIntrinsicBounds(null, null, drawableLeft, null);
mTvHint.setTextSize(16);
mTvHint.setBackgroundResource(R.color.transparent);
mTvHint.setGravity(Gravity.CENTER_VERTICAL);
mTvHint.setLayoutParams(params);
Animation ani = new AlphaAnimation(0.2f, 1f);
ani.setDuration(3000);
ani.setRepeatMode(Animation.REVERSE);
ani.setRepeatCount(Animation.INFINITE);
mTvHint.startAnimation(ani);
addView(mTvHint);
}
//设置提示文字
public void setText(String text) {
mTvHint.setText(text + "");
}
// 表层动画
public void startBounceAnim(int startY, int dy, int duration) {
mScroller.startScroll(0, startY, 0, dy, duration);
invalidate();//这里必须调用invalidate()才能保证computeScroll()会被调用,否则不一定会刷新界面,看不到滚动效果
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
mLastDownY = (int) event.getY();
return true;
case MotionEvent.ACTION_MOVE:
mCurryY = (int) event.getY();
mDelY = mCurryY - mLastDownY;
if (mDelY < 0) {
scrollTo(0, -mDelY);
}
break;
case MotionEvent.ACTION_UP:
mCurryY = (int) event.getY();
mDelY = mCurryY - mLastDownY;
if (mDelY < 0) {
if (Math.abs(mDelY) > mScreenHeight / 5) {
// 向上滑动超过一定高度的时候 开启向上消失动画
startBounceAnim(this.getScrollY(), mScreenHeight, 450);
mCloseFlag = true;
} else {
// 向上滑动未超过半个屏幕高的时候 开启向下弹动动画
startBounceAnim(this.getScrollY(), -this.getScrollY(), 1000);
mCloseFlag = false;
}
}
break;
}
return super.onTouchEvent(event);
}
@Override
public void computeScroll() {
super.computeScroll();
if (mScroller.computeScrollOffset()) {//判断滚动是否完成 true 表示动画还未完成
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
} else {
if (mCloseFlag) {
this.setVisibility(View.GONE);
}
}
}
@Override
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
if (visibility == GONE){
mCloseFlag = false;
mLockListen.unLock();
}else if(visibility == VISIBLE){
scrollTo(0,0);
}
super.onVisibilityChanged(changedView, visibility);
}
public void setLockListen(LockListen lockListen){
mLockListen = lockListen;
}
public interface LockListen{
void unLock();
}
}