您的位置:首页 > 其它

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);
}

}


`
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: