Android实现上下滑动效果

1.     概念:

比如用Scroll手势在浏览器中滚屏,用Fling在阅读器中翻页等。在在Android系统中,

手势的识别是通过 GestureDetector.OnGestureListener接口来实现的。

我们先来明确一些概念:

(1)     首先:Android的事件处理机制是基于Listener(监听器)来实现的,比我们今天所

说的触摸屏相关的事件,就是通过 onTouchListener。

(2)     其次:所有View的子类都可以通过setOnTouchListener()、setOnKeyListener() 等方法来添加对某一类事件的监听器。

(3)     第三:Listener一般会以Interface(接口)的方式来提供,其中包含一个或多个abstract(抽象)方法,我们需要实现这些方法来完成onTouch()、onKey()等等的操作。

2.     实践:

下面我们实现一个手触摸滑动的效果。

编写一个类,继承activity实现OnGestureListener接口。

public class Weight extends Activity implements OnGestureListener {
    privateflipper;
    privatedetector;
    protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
flipper = new ViewFlipper(this);
detector = new GestureDetector(this);
       LinearLayout lin = new LinearLayout(this);
        lin.setLayoutParams(newLinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT));
        lin.setOrientation(LinearLayout.VERTICAL);
        addTxt(lin);
        this.addContentView(lin, new ViewGroup.LayoutParams(200 ,200));
    }
    public void addTxt(ViewGroup view)
    {
       TextView txt1 = new TextView(this);
 txt1.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
"11");
       ...txt2和txt3一样设定
flipper.addView(txt1);
flipper.addView(txt2);
flipper.addView(txt3);
flipper);
    }
    /**
     * 重写GestureDeterctor类里面的onTouchEvent方法
     */
    public boolean onTouchEvent(MotionEvent event) {
       Log.i("golf", "onTouch");
       return this.detector.onTouchEvent(event);
    }
   .....
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
           float velocityY) {
       if (e1.getY() > e2.getY()) 
        this.flipper.showNext();
        else if (e1.getY() < e2.getY()) 
            this.flipper.showPrevious();
       else
            return false;
        return true;
    }
}

这里面用到了两个对象,ViewFlipper和GestureDetector。

我们先说说这ViewFilpper继承自FrameLayout、类似于一个容器,它有一个优点每次只能显示一个view,利用这个优点,我们可以实现类似的翻页的效果。

事先要把View都添加到ViewFlipper中去,代码如下:

TextView txt1 = new TextView(this);
       txt1.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
"11");
        ...txt2和txt3一样设定
viewFlipper中
        flipper.addView(txt1);
        flipper.addView(txt2);
        flipper.addView(txt3);


分析:

我们先从简单的入手,在一个activity中实现滚动,不要再弹出来的dialog中实现这个滚动效果。

要想实现滚动效果,必须实现android.view.GestureDetector包中的OnGestureListener接口,这个接口里面有六个要实现的方法onDown(MotionEvent e)、onShowPress(MotionEvent e)、onSingleTapup(MotionEvent e)、onScroll(MotionEvent e1, MotionEvent e2, float distance, float distanceY)、onLongPress(MotionEvent e)、

onFling(MotionEvent e1, MotionEvent e2, float float velocity)

我们所要做的事就是重写onTouchEvent放,通过GestureDetector对象获取触摸的类型,可能是按下、长时间按下、滑动等、就是对应的6个方法。

下面是重写的onTouchEvent方法:

/**
GestureDeterctor类里面的onTouchEvent方法
     */
    public boolean onTouchEvent(MotionEvent event) {
       System.out.println("onTouch");
       return this.detector.onTouchEvent(event);
    }

这里面的变量detector在onCreate中实例化。

由于我们是滑动的效果,所以只要重写onFling(MotionEvent e1, MotionEvent e2, float floatvelocity)方法

参数说明:(我的理解)

第一个参数:事件源的起始点

第二个参数:事件源的终点

第三个参数:水平方向滑动的距离

第四个参数:垂直方向滑动的距离。

下面是重写的onFling(MotionEvent e1, MotionEvent e2, float float velocity)方法。

 

  

public boolean onFling(MotionEvent e1, MotionEvent e2, floatvelocityX,
           float velocityY) {
       System.out.println("onFling");
       if (e1.getY() > e2.getY())
flipper.showNext();
         else if (e1.getY() < e2.getY()) 
flipper.showPrevious();
         else 
            return false;
       return true;
    }

其他的六个方法比较简单,通过system.out.println()方法看看什么时候调用这个方法。

3.     升华

接下来我们想将这个activity以dialog的形式在其他的activity中显示。

先回忆一下我们dialog是如何创建的:

Dialog dialog = newAlertDialog.Builder(this).setView(flipper).create();

setView(View view)这个参数很灵活。

但是自己尝试了各种方法想在dialog实现这种翻页的效果,但是都是失败的。

那我们就通过视觉上的欺骗的方法来实现跳出来像dialog的activity。

我们新建一个MainActivity,放一个button添加onclickListener事件。

事件中的代码:

Intent intent = new Intent();
       intent.setClass(this, Weight.class);
       startActivity(intent);

这样跳转肯定是跳转到新的activity中了,如何实现视觉上的欺骗呢?

只需要在申明这个activity中,给Weight添加一个属性:

代码如下:

<activity android:name=".Weight"
           android:label="@string/app_name"
           android:theme="@android:style/Theme.Dialog">
</activity>

Android:theme=”@android:style/Theme.Dialog”这个属性就会让Weight乖乖的像dialog一样显示了.