Пользовательский вид имеет setOnTouchListener, который вызывает его, но не переопределяет performClick (класс extends Activity NOT View)

Я создал Android-активность, реализующую немного OpenCV. То, что он делает, это просто создать пользовательский вид камеры, и когда экран коснется, фотография будет сохранена.

Моя единственная проблема заключается в том, что код mOpenCvCameraView.setOnTouchListener(MainActivity.this); внутри BaseLoaderCallback содержится предупреждение.

mOpenCvCameraView.setOnTouchListener(MainActivity.this); предупреждает о

Пользовательский вид com/example/zcameratestv2/Version2CameraView вызвал setOnTouchListener, но не переопределяет функцию performClick

В отличие от других вопросов, мой класс расширяет Activity not View, поэтому, когда я пытаюсь переопределить функцию private boolean performClick() {...super.performClick(); } private boolean performClick() {...super.performClick(); } он не распознается. Вот мои классы

package com.example.zcameratestv2;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.core.Mat;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.widget.Toast;

public class MainActivity extends Activity implements CvCameraViewListener, OnTouchListener {

private Version2CameraView mOpenCvCameraView;
private static final String TAG = "Version 2::Activity";

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                Log.i(TAG, "OpenCV loaded successfully");
                mOpenCvCameraView.enableView();
                mOpenCvCameraView.setOnTouchListener(MainActivity.this);
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};

public MainActivity() {
    Log.i(TAG, "Version 2 Class instantiated");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    setContentView(R.layout.activity_main);

    mOpenCvCameraView = (Version2CameraView) findViewById(R.id.java_surface_view);

    mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);

    mOpenCvCameraView.setCvCameraViewListener(this);

}

public void onPause()
{
    super.onPause();
    if (mOpenCvCameraView != null)
        mOpenCvCameraView.disableView();
}

@Override
public void onResume()
{
    super.onResume();
    OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
}

public void onDestroy() {
    super.onDestroy();
    if (mOpenCvCameraView != null)
        mOpenCvCameraView.disableView();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onCameraViewStarted(int width, int height) {
    // TODO Auto-generated method stub

}

@Override
public void onCameraViewStopped() {
    // TODO Auto-generated method stub

}

@Override
public Mat onCameraFrame(Mat inputFrame) {
    // TODO Auto-generated method stub
    return null;
}

@SuppressLint("SimpleDateFormat")
@Override
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        //some code....
        break;
    case MotionEvent.ACTION_UP:
        Log.i(TAG,"onTouch event");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
        String currentDateandTime = sdf.format(new Date());
        String fileName = Environment.getExternalStorageDirectory().getPath() +
                               "/sample_picture_" + currentDateandTime + ".jpg";
        mOpenCvCameraView.takePicture(fileName);
        Toast.makeText(this, fileName + " saved", Toast.LENGTH_SHORT).show();
        v.performClick();
        break;
    default:
        break;
    }
    return true;
 }


}

Ранее public boolean onTouch(View v, MotionEvent event) имело аналогичное предупреждение, подобное OnTouchListener, оно показывает, что я должен использовать функцию performClick(); но я не могу переопределить его, так как я перехожу к Activity not a View. И я обнаружил, что применение v.PerformClick(); исправляет это.

Этот другой класс обрабатывает процессы камеры

package com.example.zcameratestv2;

import java.io.FileOutputStream;

import org.opencv.android.JavaCameraView;

import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.util.AttributeSet;
import android.util.Log;

public class Version2CameraView extends JavaCameraView implements PictureCallback {

private static final String TAG = "Version2::CameraView";
private String mPictureFileName;

public Version2CameraView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public void takePicture(final String fileName) {
    Log.i(TAG, "Taking picture");
    this.mPictureFileName = fileName;
    // Postview and jpeg are sent in the same buffers if the queue is not empty when performing a capture.
    // Clear up buffers to avoid mCamera.takePicture to be stuck because of a memory issue
    mCamera.setPreviewCallback(null);

    // PictureCallback is implemented by the current class
    mCamera.takePicture(null, null, this);
}

@Override
public void onPictureTaken(byte[] data, Camera camera) {
    Log.i(TAG, "Saving a bitmap to file");
    // The camera preview was automatically stopped. Start it again.
    mCamera.startPreview();
    mCamera.setPreviewCallback(this);

    // Write the image in a file (in jpeg format)
    try {
        FileOutputStream fos = new FileOutputStream(mPictureFileName);

        fos.write(data);
        fos.close();

    } catch (java.io.IOException e) {
        Log.e("PictureDemo", "Exception in photoCallback", e);
    }

}
}

Я включил необходимые разрешения в файл манифеста, такие как CAMERA и WRITE_EXTERNAL_STORAGE

Может ли кто-нибудь определить проблему? Нужна ваша помощь. Заранее спасибо!

Ответы

Ответ 1

onTouch() получает каждое событие касания из основного представления, которое не было помечено как "обработанное". Если ваш Version2CameraView не обрабатывает события касания, они обрабатываются в Activity и ваш Version2CameraView передается как параметр View v.

К сожалению, ваш JavaCameraView не переопределяет performClick(), но вы пытаетесь вызвать ее в этом представлении. Решение? Добавьте этот метод в класс Version2CameraView:

@Override
public boolean performClick() {
    // do what you want
    return true;
}

Ответ 2

Вам нужно добавить метод обработки событий касания, так как ваше представление setOnTouchListener(), добавьте переопределение метода по умолчанию, обязательно вызовите супер метод внутри, чтобы избежать ошибок, таких как "Метод не отменяет метод из своего суперкласса",, вы можете оставить его как мой образец, если вы не собираетесь обрабатывать события касания там:

@Override
public boolean performClick() {
    super.performClick();
    return true;
}