将触摸事件的数据从自定义视图传递到活动android

时间:2016-12-14 03:03:22

标签: android android-layout android-custom-view android-touch-event

如何将数据从自定义视图传递到父活动?我在自定义视图中触摸了哪个框的数据。我想在触摸一个框时将该数据传递给父活动。

这是我的活动布局: 1

编辑: 这是父活动:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:visibility="invisible">
    <SearchView
        android:id="@+id/searchView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        >
    </SearchView>
</RelativeLayout>
<com.example.gaurav.dummyapp.FaceOverlayView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/face_overlay"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

FaceOverlayView.java

公共类FaceOverlayView扩展了View {

private Bitmap mBitmap;
private SparseArray<Face> mFaces;
float left = 0;
float top = 0;
float right = 0;
float bottom = 0;
double sc;
private String faceData;

public FaceOverlayView(Context context) {
    this(context, null);
}

public FaceOverlayView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public FaceOverlayView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public void setBitmap( Bitmap bitmap ) {
    mBitmap = bitmap;
    FaceDetector detector = new FaceDetector.Builder( getContext() )
            .setTrackingEnabled(true)
            .setLandmarkType(FaceDetector.ALL_LANDMARKS)
            .setMode(FaceDetector.ACCURATE_MODE)
            .build();

    if (!detector.isOperational()) {
        //Handle contingency
    } else {
        Frame frame = new Frame.Builder().setBitmap(bitmap).build();
        mFaces = detector.detect(frame);
        detector.release();
    }
    logFaceData();
    invalidate();
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if ((mBitmap != null) && (mFaces != null)) {
        double scale = drawBitmap(canvas);
        drawFaceBox(canvas, scale);

    }
}

private double drawBitmap(Canvas canvas) {
    double viewWidth = canvas.getWidth();
    double viewHeight = canvas.getHeight();
    double imageWidth = mBitmap.getWidth();
    double imageHeight = mBitmap.getHeight();
    double scale = Math.min(viewWidth / imageWidth, viewHeight / imageHeight);
    sc = scale;
    Rect destBounds = new Rect(0, 0, (int)(imageWidth * scale), (int)(imageHeight * scale));
    canvas.drawBitmap(mBitmap, null, destBounds, null);
    return scale;
}

private void drawFaceBox(Canvas canvas, double scale) {
    //This should be defined as a member variable rather than
    //being created on each onDraw request, but left here for
    //emphasis.
    Paint paint = new Paint();
    paint.setColor(Color.GREEN);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(5);



    for( int i = 0; i < mFaces.size(); i++ ) {
        Face face = mFaces.valueAt(i);

        left = (float) ( face.getPosition().x * scale );
        top = (float) ( face.getPosition().y * scale );
        right = (float) scale * ( face.getPosition().x + face.getWidth() );
        bottom = (float) scale * ( face.getPosition().y + face.getHeight() );

        canvas.drawRect( left, top, right, bottom, paint );
    }
}

private void drawFaceLandmarks(Canvas canvas, double scale ) {
    Paint paint = new Paint();
    paint.setColor( Color.GREEN );
    paint.setStyle( Paint.Style.STROKE );
    paint.setStrokeWidth( 5 );

    for( int i = 0; i < mFaces.size(); i++ ) {
        Face face = mFaces.valueAt(i);

        for ( Landmark landmark : face.getLandmarks() ) {
            int cx = (int) ( landmark.getPosition().x * scale );
            int cy = (int) ( landmark.getPosition().y * scale );
            canvas.drawCircle( cx, cy, 10, paint );
        }

    }
}

private void logFaceData() {
    float smilingProbability;
    float leftEyeOpenProbability;
    float rightEyeOpenProbability;
    float eulerY;
    float eulerZ;
    for( int i = 0; i < mFaces.size(); i++ ) {
        Face face = mFaces.valueAt(i);

        smilingProbability = face.getIsSmilingProbability();
        leftEyeOpenProbability = face.getIsLeftEyeOpenProbability();
        rightEyeOpenProbability = face.getIsRightEyeOpenProbability();
        eulerY = face.getEulerY();
        eulerZ = face.getEulerZ();

        Log.e( "Face Detection", "Smiling: " + smilingProbability );
        Log.e( "Face Detection", "Left eye open: " + leftEyeOpenProbability );
        Log.e( "Face Detection", "Right eye open: " + rightEyeOpenProbability );
        Log.e( "Face Detection", "Euler Y: " + eulerY );
        Log.e( "Face Detection", "Euler Z: " + eulerZ );
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    int action = event.getAction() & MotionEvent.ACTION_MASK;

    int x = (int) event.getX();
    int y = (int) event.getY();
    float eulerY;
    float eulerZ;
    switch(action) {
        case MotionEvent.ACTION_DOWN : {
            for( int i = 0; i < mFaces.size(); i++ ) {
                Face face = mFaces.valueAt(i);

                left = (float) ( face.getPosition().x * sc );
                top = (float) ( face.getPosition().y * sc );
                right = (float) sc * ( face.getPosition().x + face.getWidth() );
                bottom = (float) sc * ( face.getPosition().y + face.getHeight() );

                if((x > left && x < right) && (y > top && y < bottom)){
                    Log.e("BOX>>>>>>>>>>", String.valueOf(i));

                }
            }


            break;
        }
        case MotionEvent.ACTION_MOVE : {
            //path.lineTo(event.getX(), event.getY());

            break;
        }

    }

    invalidate();

    return super.onTouchEvent(event);
}

活动类: public class dummyActivity扩展AppCompatActivity {

private FaceOverlayView fooView;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_dummy);
    fooView.setBitmap("bitmap");
}

1 个答案:

答案 0 :(得分:0)

我认为你需要的是关于父活动的onTouchListenter

box_view.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_UP){

            // Do what you want/Get data from view etc... depends what kind of data it is, can you explain more?
            return true;
        }
        return false;
    }
});

我认为你的盒子里面有一个包含整数值的文本字段,所以你在onTouch里面做了

    tv_box_1.getText(); 
//To get the text of the box1 (do for tv_box_2.getText) etc...
//after that just convert to integer
Integer.parseInt(tv_box_1.getText());

你可以采取另一种方式,在父母内部实现触摸并处理触摸,做一些ifs检查视图ID并处理

另一种方式更简单的是在框内为文本视图提供match_parent用于两个方向并设置onClick,它更容易,如果你真的不需要触摸,你应该使用这个