为什么这是用于SurfaceView的setOnTouchListener但是onTouch for Activity

时间:2015-08-12 23:07:46

标签: android view surfaceview ontouchlistener ontouch

所以我遵循了本教程,代码完美无缺。但是我在理解OnTouchListener和OnTouch如何协同工作方面遇到了一些麻烦。我花了很长时间来管理这个论坛,网站和文档,但我仍然没有。

在此代码中,为ourSurfaceView设置了一个OnTouchListener,然后为该活动调用onTouch?!

有人可以解释OnTouchListener和OnTouch在不同活动和视图之间的关系。非常感谢!

package com.games.michael.waterproofme;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;

public class MainActivity extends Activity implements OnTouchListener{

    MySurface ourSurfaceView;
    float x,y,sX, sY, fX, fY;
    Bitmap test, plus;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ourSurfaceView = new MySurface(this);
        ourSurfaceView.setOnTouchListener(this);
        x = 0;
        y = 0;
        sX = 0;
        sY = 0;
        fX = 0;
        fY = 0;
        test = BitmapFactory.decodeResource(getResources(), R.drawable.sportsball);//draw ball
        plus = BitmapFactory.decodeResource(getResources(), R.drawable.plus);
        setContentView(ourSurfaceView);
    }

@Override
protected  void onPause() {
    super.onPause();
    ourSurfaceView.pause();
}

@Override
protected  void onResume() {
    super.onResume();
    ourSurfaceView.resume();
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    x = event.getX();
    y = event.getY();

    switch(event.getAction()){
        case MotionEvent.ACTION_DOWN:
            sX = event.getX();
            sY = event.getY();
            break;
        case MotionEvent.ACTION_UP:
            fX = event.getX();
            fY = event.getY();
            break;
    }

    return true;//false = finished dont loop through. true = loop through
}

public class MySurface extends SurfaceView implements Runnable{

    SurfaceHolder ourHolder;
    Thread ourThread = null;
    boolean isRunning = false;

    public MySurface(Context context){
        super(context);
        ourHolder = getHolder();
        ourThread = new Thread(this);
        ourThread.start();
    }

    public void pause(){
        isRunning = false;
        while(true){
            try {
                ourThread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            break;
        }
        ourThread = null;
    }

    public void resume(){
        isRunning = true;
        ourThread = new Thread(this);
        ourThread.start();
    }

    public void run() {
        while(isRunning){
            if(!ourHolder.getSurface().isValid()) {/
                continue;}
            Canvas canvas = ourHolder.lockCanvas();
            canvas.drawRGB(02, 02, 150);
            if (x != 0 && y != 0){
                canvas.drawBitmap(test, x-(test.getWidth()/2), y-(test.getHeight()/2), null);//bitmap, left, top, paint
            }
            if (sX != 0 && sY != 0){
                canvas.drawBitmap(plus, sX-(plus.getWidth()/2), sY-(plus.getHeight()/2), null);//bitmap, left, top, paint
            }
            if (fX != 0 && fY != 0){
                canvas.drawBitmap(plus, fX-(plus.getWidth()/2), fY-(plus.getHeight()/2), null);//bitmap, left, top, paint
            }
            ourHolder.unlockCanvasAndPost(canvas);
        }
    }

}
}

2 个答案:

答案 0 :(得分:1)

OnTouchListener是接口 - 实现它的类必须覆盖其方法。对于android.view.View.OnTouchListener,这是一种方法:boolean onTouch(View v, MotionEvent event)

当你的SurfaceView发生触摸事件时,检查是否设置了onTouchListener,如果是,则调用其onTouch方法

答案 1 :(得分:0)

  

有人可以解释OnTouchListener和OnTouch在不同活动和视图之间的关系。

如果您向其注册任何回调,则会调用视图上的触摸事件。 SurfaceView扩展了View类。

  

ourSurfaceView.setOnTouchListener(本);

     

的setContentView(ourSurfaceView);

因此,您只需将 ourSurfaceView 设置为活动作为其内容视图,并注册 View.OnTouchListener 。这意味着onTouch的抽象方法是在 ourSurfaceView 实例上调用的,而不是活动。

  

在此代码中,为ourSurfaceView设置了一个OnTouchListener,然后为该活动调用onTouch?!

不,它会将 ourSurfaceView 实例中的任何触摸事件作为其内容视图委托给您的 MainActivity 类,因为您注册了 View.OnTouchListener < / p>

只是一个简单的Java示例:

public class Main {

public static void main(String[] args){
    SurfaceClass surfaceClass = new SurfaceClass();
    ActivityClass activityClass = new ActivityClass();
    surfaceClass.setOnFartListener(activityClass);

    //Touch event :D
    surfaceClass.fart();
}

public static class ActivityClass implements SurfaceClass.OnFartListener{

    @Override
    public void onFart(String kindOfFart) {
        System.out.println(kindOfFart);
    }
}

public static class SurfaceClass{

    private SurfaceClass.OnFartListener onFartListener;

    public void fart(){
        if(onFartListener != null){
            onFartListener.onFart("Huge One!!");
        }
    }

    public void setOnFartListener(SurfaceClass.OnFartListener onFartListener){
        this.onFartListener = onFartListener;
    }

    public interface OnFartListener{

        void onFart(String kindOfFart);

    }
}}

请参阅下面的触摸事件:D

javac Main.java && java Main