我有以下两个类: 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类来保持原始布局?
答案 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>