我需要拖动并选择ImageView
中图像集的一部分并检索所选矩形的终点而不会进行任何修改(例如裁剪)。
到目前为止,我所能做的就是找出用户点击屏幕的点的坐标。
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//Simply displays a toast
Utilities.displayToast(getApplicationContext(), "Touch coordinates : " +
String.valueOf(event.getX()) + "x" + String.valueOf(event.getY()));
return true;
}
});
但这远不是我想要的地方。我真的无法在StackOverFlow / Google上找到任何相关内容。
我该如何实施?
答案 0 :(得分:13)
这是您可以使用的一种方式(但是,实现相同的方法有很多可能性)。它基于创建自定义视图以绘制和跟踪选择矩形。此外,您只需在自己onTouch()
中应用OnTouchListener()
自定义视图中的逻辑。
主要布局:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="@+id/root"
android:background="@android:color/background_dark">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/image"
android:src="@drawable/up_image"
android:scaleType="fitXY" />
<com.example.TestApp.DragRectView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/dragRect" />
</RelativeLayout>
自定义视图:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class DragRectView extends View {
private Paint mRectPaint;
private int mStartX = 0;
private int mStartY = 0;
private int mEndX = 0;
private int mEndY = 0;
private boolean mDrawRect = false;
private TextPaint mTextPaint = null;
private OnUpCallback mCallback = null;
public interface OnUpCallback {
void onRectFinished(Rect rect);
}
public DragRectView(final Context context) {
super(context);
init();
}
public DragRectView(final Context context, final AttributeSet attrs) {
super(context, attrs);
init();
}
public DragRectView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
init();
}
/**
* Sets callback for up
*
* @param callback {@link OnUpCallback}
*/
public void setOnUpCallback(OnUpCallback callback) {
mCallback = callback;
}
/**
* Inits internal data
*/
private void init() {
mRectPaint = new Paint();
mRectPaint.setColor(getContext().getResources().getColor(android.R.color.holo_green_light));
mRectPaint.setStyle(Paint.Style.STROKE);
mRectPaint.setStrokeWidth(5); // TODO: should take from resources
mTextPaint = new TextPaint();
mTextPaint.setColor(getContext().getResources().getColor(android.R.color.holo_green_light));
mTextPaint.setTextSize(20);
}
@Override
public boolean onTouchEvent(final MotionEvent event) {
// TODO: be aware of multi-touches
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDrawRect = false;
mStartX = (int) event.getX();
mStartY = (int) event.getY();
invalidate();
break;
case MotionEvent.ACTION_MOVE:
final int x = (int) event.getX();
final int y = (int) event.getY();
if (!mDrawRect || Math.abs(x - mEndX) > 5 || Math.abs(y - mEndY) > 5) {
mEndX = x;
mEndY = y;
invalidate();
}
mDrawRect = true;
break;
case MotionEvent.ACTION_UP:
if (mCallback != null) {
mCallback.onRectFinished(new Rect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY),
Math.max(mEndX, mStartX), Math.max(mEndY, mStartX)));
}
invalidate();
break;
default:
break;
}
return true;
}
@Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
if (mDrawRect) {
canvas.drawRect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY),
Math.max(mEndX, mStartX), Math.max(mEndY, mStartY), mRectPaint);
canvas.drawText(" (" + Math.abs(mStartX - mEndX) + ", " + Math.abs(mStartY - mEndY) + ")",
Math.max(mEndX, mStartX), Math.max(mEndY, mStartY), mTextPaint);
}
}
}
活动很简单:
public class MyActivity extends Activity {
private static final String TAG = "MyActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final DragRectView view = (DragRectView) findViewById(R.id.dragRect);
if (null != view) {
view.setOnUpCallback(new DragRectView.OnUpCallback() {
@Override
public void onRectFinished(final Rect rect) {
Toast.makeText(getApplicationContext(), "Rect is (" + rect.left + ", " + rect.top + ", " + rect.right + ", " + rect.bottom + ")",
Toast.LENGTH_LONG).show();
}
});
}
}
}
输出如下:
答案 1 :(得分:1)
我刚尝试了你的解决方案,这很酷。也许我错了,但我认为你的Toast输出中有一个拼写错误:
mCallback.onRectFinished(new Rect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY),
Math.max(mEndX, mStartX), Math.max(mEndY, mStartX)));
必须是:
mCallback.onRectFinished(new Rect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY),
Math.max(mEndX, mStartX), Math.max(mEndY, mStartY)));
否则底部的值有时计算错误。
答案 2 :(得分:0)
另一种方式:https://github.com/edmodo/cropper
来自Doc:
Cropper是一种图像裁剪工具。它提供了一种设置方法 以编程方式在XML中显示图像,并显示可调整大小的裁剪 窗口在图像上方。调用getCroppedImage()方法会 然后返回由裁剪窗口标记的位图。
开发人员可以自定义以下属性(通过XML和XML) 编程):
裁剪窗口中的指南外观是否有纵横比 是固定还是非宽高比(如果长宽比固定)图像 resource按指定数量旋转图像的公共方法 学位也包括在内。这可以用来为用户提供 如果Android错误计算,则可以选择修复图像方向 预期的方向。
API级别7及以上版本支持。
有关更多信息,请参阅链接的Github Wiki页面。