Android自定义视图严格保留在布局自定义范围内

时间:2019-02-04 11:46:15

标签: java android android-layout

我正在设计布局内的Canvas Drawable。这是我的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">

<LinearLayout
    android:layout_width="0dp"
    android:layout_weight="4"
    android:layout_height="match_parent">

    <com.sensennetworks.senanpr.ui.DrawPolygonCanvas
        android:id="@+id/drawPolygonCanvas"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</LinearLayout>

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:background="#000"
    android:orientation="vertical">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:onClick="onSave"
        android:text="Save" />

    <android.support.v4.widget.Space
        android:layout_width="20dp"
        android:layout_height="wrap_content" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:onClick="onReset"
        android:text="Clear" />
</LinearLayout>

此布局文件创建了一个自定义可绘制的“ DrawPolygonCanvas”,可以将其拖动,在下面的图像中将其拖出边界。

enter image description here

而且,这会产生这样的结果。...结果完全超出了边界。

enter image description here

现在,我的问题是如何创建一个布局,以使“ DrawPolygonCanvas”严格位于布局内,并且不会同时通过两个按钮进入其黑色区域。

    // Debug helpers to draw lines between the two touch points
    private HashMap<String, List<Vector2D>> polygons = new HashMap();

    public DrawPolygonCanvas(Context context) {
        super(context);
        init(context);
    }

    public DrawPolygonCanvas(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public DrawPolygonCanvas(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public DrawPolygonCanvas(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }

    private void init(Context context) {
        Log.e(TAG, "called init");
        this.context = context;
//        Activity host = (Activity) getContext();
//        Log.e(TAG, "called getContext");
//        if (host.getIntent().hasExtra("byteArray")) {
//            Log.e(TAG, "called hasExtra");
//            byte[] byteArray = host.getIntent().getByteArrayExtra("byteArray");
//
//
//            Bitmap bm = BitmapFactory.decodeByteArray(byteArray
//                    , 0, byteArray.length);
//            ((GlobalApp) context.getApplicationContext()).setCurrentPreviewBitmap(bm);
//        }
        Log.e(TAG, "calling setOnTouchListener");
        setOnTouchListener(this);
    }

    public void clearROI() {
        Log.e(TAG, "called clearROI");
        // Get ROI from the shared preferences.
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        cameraROI = sharedPreferences.getString(SettingsActivity.ROI, AnprSettings.DEFAULT_CAMERA_ROI);
        Log.e(TAG, "Reloaded ROI = " + cameraROI);
        convertString2Polygons();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Log.e(TAG, "called onDraw");
        super.onDraw(canvas);

        if (!isInitialized) {
            // Get ROI from the shared preferences.
            SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
            cameraROI = sharedPreferences.getString(SettingsActivity.ROI, AnprSettings.DEFAULT_CAMERA_ROI);
            if (cameraROI.isEmpty()) {
                cameraROI = AnprSettings.DEFAULT_CAMERA_ROI;
            }
            convertString2Polygons();

            circlePaint = new Paint();
            circlePaint.setColor(0xFFFF0000);

            linePaint = new Paint();
            linePaint.setColor(0xFF00FF00);
            linePaint.setStyle(Paint.Style.STROKE);
            linePaint.setStrokeWidth(10);

            isInitialized = true;
        }


        Rect dest = new Rect(0, 0, getWidth(), getHeight());
        Paint paint = new Paint();
        paint.setFilterBitmap(true);

        // get
        Bitmap bm = ((GlobalApp) this.context.getApplicationContext()).getCurrentPreviewBitmap();
        canvas.drawBitmap(bm, null, dest, paint);

        try {
            for (Map.Entry<String, List<Vector2D>> entry : polygons.entrySet()) {

                List<Vector2D> polygon = entry.getValue();

                for (int i = 0; i < polygon.size() - 1; i++) {
                    canvas.drawLine(polygon.get(i).getX(), polygon.get(i).getY(), polygon.get(i + 1).getX(), polygon.get(i + 1).getY(), linePaint);
                }
                canvas.drawLine(polygon.get(polygon.size() - 1).getX(), polygon.get(polygon.size() - 1).getY(), polygon.get(0).getX(), polygon.get(0).getY(), linePaint);

                for (int i = 0; i < polygon.size(); i++) {
                    canvas.drawCircle(polygon.get(i).getX(), polygon.get(i).getY(), 40, circlePaint);
                }
            }
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onDetachedFromWindow() {
        Log.e(TAG, "called onDetachedFromWindow");
        super.onDetachedFromWindow();

        // Convert polygon back to string.
        convertPolygons2String();

//        SharedPreferences.Editor editor = UserSharedPref.initializeSharedPreferencesForCameraROI(context).edit();
        SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(getContext()).edit();
        editor.putString(SettingsActivity.ROI, cameraROI);
        editor.apply();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.e(TAG, "called onTouch");
        canvasTouchManager.update(event);
        Vector2D vct = canvasTouchManager.getPoint();

        float minDist = 200000.0f;
        float radius = 200;

        int minIndex = -1;
        String key = "";

        for (Map.Entry<String, List<Vector2D>> entry : polygons.entrySet()) {

            List<Vector2D> points = entry.getValue();
            for (int i = 0; i < points.size(); i++) {
                float dist = points.get(i) == null ? 0 : Vector2D.subtract(vct, points.get(i)).getLength();
                if (dist >= radius) {
                    continue;
                }

                if (dist < minDist) {
                    minDist = dist;
                    minIndex = i;
                    Log.e(TAG, "Matching x = " + points.get(i).getX() + ", y = " + points.get(i).getY());
                    key = entry.getKey();
                }
            }
        }

        if (minIndex != -1 && !key.isEmpty()) {
            polygons.get(key).set(minIndex, vct);
        } else {
            Log.e("OK2", "Touch point is too far, dist = " + minDist);
        }

        invalidate();

        return true;
    }
}

0 个答案:

没有答案