web-dev-qa-db-ja.com

カスタムビューにはsetOnTouchListenerが呼び出されていますが、performClickをオーバーライドしていません(クラスはActivity NOT Viewを拡張しています)

Androidアクティビティを少しOpenCVを実装するアクティビティを作成しました。これは、カスタムカメラビューを作成するだけで、画面に触れると写真が保存されます。

私の唯一の問題は、BaseLoaderCallback内のコードmOpenCvCameraView.setOnTouchListener(MainActivity.this);に警告が含まれていることです。

mOpenCvCameraView.setOnTouchListener(MainActivity.this);について警告

カスタムビューcom/example/zcameratestv2/Version2CameraViewでsetOnTouchListenerが呼び出されましたが、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ではなく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などのマニフェストファイルに必要な権限を含めました

誰かが問題を特定できますか?君の力が必要。前もって感謝します!

15
Sinned

onTouch()メソッドは、「処理済み」としてマークされていない、基になるビューからすべてのタッチイベントを取得します。 _Version2CameraView_がタッチイベントを処理しない場合、それらはアクティビティで処理され、_Version2CameraView_は_View v_パラメーターとして渡されます。

残念ながら、あなたのJavaCameraViewperformClick()をオーバーライドしませんが、あなたはこのビューでそれを呼び出そうとしています。解決?このメソッドを_Version2CameraView_クラスに追加します。

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

少し遅れると思いますが、解決策は簡単です。 ButtonTextViewのようなクラスは、Viewのサブクラスであり、SurfaceViewおよび_Version2CameraView_の親であるJavaCameraViewのサブクラスでもあります。サブクラス。

そして、違いは何ですか?違いは、TextViewが 'ViewTreeObserver.OnPreDrawListener'インターフェイスを実装することです。このため、Button(TextViewのサブクラス)はperformClick()メソッドをオーバーライドできます。

_Version2CameraView_クラスを使用してどうすればよいですか?performClick()メソッドをオーバーライドするインターフェイスを実装するだけです。 「ViewTreeObserver.OnPreDrawListener」はどれですか?いいえ、次のように_SurfaceHolder.Callback_を使用する必要があります。

_public class Version2CameraView extends JavaCameraView implements PictureCallback, SurfaceHolder.Callback 
{
    ...
   /**
     * Process the MotionEvent.
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        synchronized (getHolder()) {
            // Do something
            ...
            return true;
        }
    }

    @Override
    public boolean performClick() {
        // Calls the super implementation, which generates an AccessibilityEvent
        // and calls the onClick() listener on the view, if any
        super.performClick();

        // Handle the action for the custom click here

        return true;
    }
    ...
}
_

このソリューションでは、警告を削除する必要があります。

0
Teocci

ビューがsetOnTouchListener()を呼び出したため、タッチイベントを処理するメソッドを追加する必要があります。デフォルトメソッドのオーバーライドを追加します。「メソッドはメソッドをオーバーライドしないそのスーパークラスから」、あなたがそこにタッチイベントを処理しないのであれば、あなたはそれを私のサンプルのように残すことができます:

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