如何在活动类中使用自定义类(扩展View类)来绘制路径而不更改android中主要布局的其他部分

时间:2013-11-13 04:45:30

标签: android path android-linearlayout draw

我有以下两个类: 1. ImageGalleryDemoActivity(从图库中导入图像) 2. DrawClass(在导入的图像上绘制徒手路径)

public class ImageGalleryDemoActivity extends Activity {
    private static int RESULT_LOAD_IMAGE = 1;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button buttonLoadImage = (Button) findViewById(R.id.buttonLoadPicture);
        buttonLoadImage.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {

                Intent i = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

                startActivityForResult(i, RESULT_LOAD_IMAGE);
            }
        });
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };

            Cursor cursor = getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);
            cursor.close();

            ImageView imageView = (ImageView) findViewById(R.id.imgView);
            imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath));



        }


    }
}

和以下类在导入的图像上绘制路径。

public class DrawClass extends View implements OnTouchListener {

    private Paint paint;
    List<Point> points;
    int DIST = 2;
    boolean flgPathDraw = true;

    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.id.imgView);

    public DrawClass(Context c  ) {
        super(c);
        setFocusable(true);
        setFocusableInTouchMode(true);

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(2);
        paint.setColor(Color.BLACK);

        this.setOnTouchListener(this);
        points = new ArrayList<Point>();
    }
    public DrawClass(Context context, AttributeSet attrs) {
        super(context, attrs);
        setFocusable(true);
        setFocusableInTouchMode(true);

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(2);
        paint.setColor(Color.BLACK);

        this.setOnTouchListener(this);
        points = new ArrayList<Point>();

    }

    public void onDraw(Canvas canvas) 
    {
        canvas.drawBitmap(bitmap, 0, 0, null);

        Path path = new Path();
        boolean first = true;

        for (int i = 0; i < points.size(); i += 2) 
        {
            Point point = points.get(i);
            if (first) {
                first = false;
                path.moveTo(point.x, point.y);
            } else if (i < points.size() - 1) {
                Point next = points.get(i + 1);
                path.quadTo(point.x, point.y, next.x, next.y);
            } else {
                path.lineTo(point.x, point.y);
            }
        }
        canvas.drawPath(path, paint);
    }

    public boolean onTouch(View view, MotionEvent event) {
        // if(event.getAction() != MotionEvent.ACTION_DOWN)
        // return super.onTouchEvent(event);
        Point point = new Point();
        point.x = (int) event.getX();
        point.y = (int) event.getY();

        if (flgPathDraw) {
            points.add(point);
        }

        invalidate();
        Log.e("Hi  ==>", "Size: " + points.size());

        return true;
    }
    public void fillinPartofPath()
    {
        Point point = new Point();
        point.x = points.get(0).x;
        point.y = points.get(0).y;

        points.add(point);
        invalidate();
    }
    public void resetView()
    {
        points.clear();
        paint.setColor(Color.WHITE);
        paint.setStyle(Style.STROKE);
        flgPathDraw=true;
        invalidate();
    }
}

class Point {
    public float dy;
    public float dx;
    float x, y;

    @Override
    public String toString() {
        return x + ", " + y;
    }
}

现在,问题是我可以使用setContentView更改整个主要布局,但我想使用“加载图片”按钮保留原始布局并在图像上绘制路径。那么,如何在活动类中使用DrawClass类来保持原始布局?

3 个答案:

答案 0 :(得分:1)

制作框架布局或相对布局 这不会打扰原始视图

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:CustomTexView="http://schemas.android.com/apk/res/com.example.testapp"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_blue_bright"
    android:orientation="vertical" >

    <CustomView
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </CustomView>

    <RelativeLayout
        android:id="@+id/youroriginalviewhere"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </RelativeLayout>

</RelativeLayout>

答案 1 :(得分:1)

使用以下代码创建内部类签名..

public class signature extends View {
        private static final float STROKE_WIDTH = 5f;
        private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;
        private Paint paint = new Paint();
        private Path path = new Path();
        private float lastTouchX;
        private float lastTouchY;
        private final RectF dirtyRect = new RectF();
        public signature(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint.setAntiAlias(true);
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeWidth(STROKE_WIDTH);
        }
        @Override
        protected void onDraw(Canvas canvas) {
        canvas.drawPath(path, paint);
        }
        @Override
        public boolean onTouchEvent(MotionEvent event) {
        float eventX = event.getX();
        float eventY = event.getY();
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        path.moveTo(eventX, eventY);
        lastTouchX = eventX;
        lastTouchY = eventY;
        return true;
        case MotionEvent.ACTION_MOVE:
        case MotionEvent.ACTION_UP:
        resetDirtyRect(eventX, eventY);
        int historySize = event.getHistorySize();
        for (int i = 0; i < historySize; i++) {
        float historicalX = event.getHistoricalX(i);
        float historicalY = event.getHistoricalY(i);
        expandDirtyRect(historicalX, historicalY);
        path.lineTo(historicalX, historicalY);
        }
        path.lineTo(eventX, eventY);
        break;
        default:
        debug("Ignored touch event: " + event.toString());
        return false;
        }
        invalidate((int) (dirtyRect.left - HALF_STROKE_WIDTH),
        (int) (dirtyRect.top - HALF_STROKE_WIDTH),
        (int) (dirtyRect.right + HALF_STROKE_WIDTH),
        (int) (dirtyRect.bottom + HALF_STROKE_WIDTH));
        lastTouchX = eventX;
        lastTouchY = eventY;
        return true;
        }

        private void debug(String string) {
        }

        private void expandDirtyRect(float historicalX, float historicalY) {
        if (historicalX < dirtyRect.left) {
        dirtyRect.left = historicalX;
        } else if (historicalX > dirtyRect.right) {
        dirtyRect.right = historicalX;
        }
        if (historicalY < dirtyRect.top) {
        dirtyRect.top = historicalY;
        } else if (historicalY > dirtyRect.bottom) {
        dirtyRect.bottom = historicalY;
        }
        }
        private void resetDirtyRect(float eventX, float eventY) {
        dirtyRect.left = Math.min(lastTouchX, eventX);
        dirtyRect.right = Math.max(lastTouchX, eventX);
        dirtyRect.top = Math.min(lastTouchY, eventY);
        dirtyRect.bottom = Math.max(lastTouchY, eventY);
        }
    }

并创建其对象signature mSignature =new signature(this, null);

答案 2 :(得分:0)

最后我可以设法使用DrawClass。我使用FrameLayout代替LinearLayout并使用LayoutInflater来使用我保留新XML的customView。在那个XML中,我使用一个视图来连接DrawClass。下面给出了代码,这可能对某人有所帮助。

View view;
FrameLayout flayout = (FrameLayout) findViewById(R.id.custom_frame);
view = getLayoutInflater().inflate(R.layout.draw, flayout,false);
flayout.addView(view);
在draw.XML中

<?xml version="1.0" encoding="utf-8"?>      
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/crop_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
<com.example.imageDrawTest.DrawClass
     android:layout_width="match_parent"
     android:layout_height="match_parent"/>
</FrameLayout>