У меня есть на MainActivity:
setContentView(R.layout.activity_main);
макет такой:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<View
class ="com.example.doie.draw.DrawingView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/drawing_area"/>
</android.support.constraint.ConstraintLayout>
и в классе DrawingView я реализовал этот метод
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
К сожалению, хотя DrawingView
инициализируется в своем onCreate
, когда представление раздувается основным классом, касание не распознается! Я подумал, что, возможно, это связано с тем, что класс DrawingView extends View
теряет фокус, поэтому я должен прикрепить прослушиватель к классу Main, но мне не нравится это решение, потому что во всех учебниках по пользовательскому представлению я видел, что касание реализовано в пользовательском классе представления, а не на Главном, поэтому не могу понять, почему я не могу рисовать на холсте.
(EDIT не является дубликатом, см. комментарии ниже)
н.б. В любом случае, для дальнейшего справки, я также прилагаю небольшой класс DrawingView, если вам нужно:
public class DrawingView extends View {
private final Paint mPaint;
public int width;
public int height;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private Paint circlePaint;
private Path circlePath;
public DrawingView(Context c) {
super(c);
context=c;
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.GREEN);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
circlePaint = new Paint();
circlePath = new Path();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
Log.d("IVO", "DrawingView: ");
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap( mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath( mPath, mPaint);
canvas.drawPath( circlePath, circlePaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
circlePath.reset();
circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
circlePath.reset();
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
DrawingView
потерпит крах, если вы поместите его в макет. Вы уверены, что смотрите на правильную вещь? - person Mike M.   schedule 02.08.2018v
<view>
в макете. Атрибутclass
в настоящее время игнорируется. Тогда вам понадобится дополнительный конструктор; тот, который принимаетContext
иAttributeSet
: stackoverflow.com/questions/12351763. - person Mike M.   schedule 02.08.2018onTouchEvent(MotionEvent event)
, я это сделал! - person Drocchio   schedule 02.08.2018AttributeSets
в качестве параметра. Если вы хотите/нравитесь, пожалуйста, напишите сообщение, чтобы я мог проголосовать за вас и одобрить его, чтобы увеличить вашу репутацию и помочь будущим людям, которые не использовали второстепенный случайview
. Благодарю вас! - person Drocchio   schedule 02.08.2018Ontouch() isn't work with custom view?
, не упоминается мой конкретный случай, так как я переопределил правильный методonTouchEvent
- person Drocchio   schedule 02.08.2018