activity实现滑动效果
2016-03-25 19:27
295 查看
可滑动的activity
可滑动的activity原理,就是将activity的theme设置为透明,之后滑动view的parent即可效果图
主题透明
android:theme="@android:style/Theme.Translucent.NoTitleBar"
之后自定义一个SwipLayout 继承FrameLayout
`public class SwipLayout extends FrameLayout { private View parent; public SwipLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public SwipLayout(Context context, AttributeSet attrs) { this(context, attrs,0); // TODO Auto-generated constructor stub } public SwipLayout(Context context) { this(context,null); }`
之后我们拿到swiplayout的parent。因为我们使用scrollto,因此应该对父容器进行滚动
`public void onWindowFocusChanged(boolean hasWindowFocus) { // 在界面可以和用户交互的时候 并且第一次的时候 才进行初始化 super.onWindowFocusChanged(hasWindowFocus); if(hasWindowFocus&&isFirst){ isFirst=false; init(); //拿到父容器 当window可见的时候 } } private void init() { parent = (View) getParent(); }
`
之后对相关事件进行拦截
`public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: curX = (int) ev.getRawX(); x=curX; break; case MotionEvent.ACTION_MOVE: int touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); if(ev.getRawX()-curX>touchSlop) { // Log.e("", "actionMove"); //小于触摸的范围就可以 if(ev.getRawX()<100) return true;//拦截 } break; } return super.onInterceptTouchEvent(ev); }`
一定要使用屏幕坐标,否则会造成卡顿,因为我们在拿view的坐标的时候,view的位置也在改变
在onTouchEvent中处理,拦截的事件即可
`public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: x = (int) event.getRawX();// 要拿到屏幕的坐标 break; case MotionEvent.ACTION_MOVE: int min=(int) (event.getRawX()-x); if(parent.getScrollX()<=0&&parent.getScrollX()>=-parent.getWidth()) {parent.scrollTo(Math.min(Math.max(parent.getScrollX()-min, -parent.getWidth()), 0), 0); x=(int) event.getRawX(); //一定获得屏幕的坐标 不要 相对坐标 否则会造成闪动 return true; } break; case MotionEvent.ACTION_UP: if(parent.getScrollX()<-parent.getWidth()/2){ //关闭 colse(); }else if(parent.getScrollX()>-parent.getWidth()/2){ //打开 open(); } break; } return super.onTouchEvent(event); }`
之后我们自定义了动画,完成关闭和开启
`class ScrollAnimation extends Animation{ private int end; private int lenght; private int start; public ScrollAnimation(int end) { this.end = end; lenght=end-parent.getScrollX(); setDuration(Math.abs(lenght)/2); start=parent.getScrollX(); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { // 0--100 1s //interpolatedTime 比例 0f-1f super.applyTransformation(interpolatedTime, t); int path= (int) (interpolatedTime*lenght); int currentX=start+path; if(currentX>0)currentX=0; if(currentX<-parent.getWidth())currentX=-parent.getWidth(); parent.scrollTo(currentX, 0); } }`
activity滑出右侧时候,接口回调
`public interface onSwipCloseListener{ public void onSwipClose(); } public void setOnSwipCloseListener(onSwipCloseListener closeListener){ this.swipCloseListener=closeListener; }`
swiplayout一定是顶层布局才生效
总结,滑动的activity本质就是修改contentView的父容器 也就是修改id为content的FragmentLayout的子view
源码如下
`package com.example.swiplayout; import android.app.Activity; import android.content.Context; import android.graphics.drawable.BitmapDrawable; import android.provider.ContactsContract.CommonDataKinds.Event; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewParent; import android.view.ViewPropertyAnimator; import android.view.WindowManager; import android.widget.FrameLayout; import android.view.View.OnTouchListener; import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; import android.view.animation.Transformation; public class SwipLayout extends FrameLayout { private View parent; public SwipLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public SwipLayout(Context context, AttributeSet attrs) { this(context, attrs,0); // TODO Auto-generated constructor stub } public SwipLayout(Context context) { this(context,null); } private void init() { parent = (View) getParent(); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: x = (int) event.getRawX();// 要拿到屏幕的坐标 break; case MotionEvent.ACTION_MOVE: int min=(int) (event.getRawX()-x); if(parent.getScrollX()<=0&&parent.getScrollX()>=-parent.getWidth()) {parent.scrollTo(Math.min(Math.max(parent.getScrollX()-min, -parent.getWidth()), 0), 0); x=(int) event.getRawX(); //一定获得屏幕的坐标 不要 相对坐标 否则会造成闪动 return true; } break; case MotionEvent.ACTION_UP: if(parent.getScrollX()<-parent.getWidth()/2){ //关闭 colse(); }else if(parent.getScrollX()>-parent.getWidth()/2){ //打开 open(); } break; } return super.onTouchEvent(event); } private void colse() { ScrollAnimation closeAnimation=new ScrollAnimation(-parent.getWidth()); parent.startAnimation(closeAnimation); closeAnimation.setAnimationListener(new AnimationListenerAdapter(){ @Override public void onAnimationEnd(Animation animation) { // TODO Auto-generated method stub super.onAnimationEnd(animation); if(swipCloseListener!=null){ swipCloseListener.onSwipClose(); } } }); } private void open() { ScrollAnimation open=new ScrollAnimation(0); parent.startAnimation(open); } boolean isFirst=true; private int x; @Override public void onWindowFocusChanged(boolean hasWindowFocus) { // 在界面可以和用户交互的时候 并且第一次的时候 才进行初始化 super.onWindowFocusChanged(hasWindowFocus); if(hasWindowFocus&&isFirst){ isFirst=false; init(); //拿到父容器 当window可见的时候 } } class ScrollAnimation extends Animation{ private int end; private int lenght; private int start; public ScrollAnimation(int end) { this.end = end; lenght=end-parent.getScrollX(); setDuration(Math.abs(lenght)/2); start=parent.getScrollX(); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { // 0--100 1s //interpolatedTime 比例 0f-1f super.applyTransformation(interpolatedTime, t); int path= (int) (interpolatedTime*lenght); int currentX=start+path; if(currentX>0)currentX=0; if(currentX<-parent.getWidth())currentX=-parent.getWidth(); parent.scrollTo(currentX, 0); } } private onSwipCloseListener swipCloseListener; private int curX; public interface onSwipCloseListener{ public void onSwipClose(); } public void setOnSwipCloseListener(onSwipCloseListener closeListener){ this.swipCloseListener=closeListener; } //实现了一个animation适配器 class AnimationListenerAdapter implements AnimationListener{ @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: curX = (int) ev.getRawX(); x=curX; break; case MotionEvent.ACTION_MOVE: int touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); if(ev.getRawX()-curX>touchSlop) { // Log.e("", "actionMove"); //小于触摸的范围就可以 if(ev.getRawX()<100) return true;//拦截 } break; } return super.onInterceptTouchEvent(ev); } }
`
相关文章推荐
- 给予 HoloCircularProgressBar 实现自定义 标签展示
- 软件工程:vs单元测试
- OC中的数组定义和方法使用
- Spring框架的7个模块
- 如何做个好员工?
- Android手机 Fildder真机抓包
- Android APP分享(第三方友盟)
- 给定入栈序列,判断出栈序列是否合法
- 手机移动端WEB资源整合
- 给定入栈序列,判断出栈序列是否合法
- 【iOS】银联支付
- linux下使用mutt发送带附件的邮件
- 构建之法阅读笔记02
- Lua_第19章 String 库(上)
- impdp、expdp和sqlplus中登陆sys
- android显示当前时间
- PAT (Advanced Level) Practise 1094 The Largest Generation (25)
- java 异常处理
- 关于对复数物理意义的理解
- TCP协议中的三次握手和四次挥手图解