Рисование нескольких линий и запоминание их толщины

Это может быть из-за того, что у меня был долгий день и уже довольно поздно, но я не могу понять, что я делаю неправильно.

Я просто хочу иметь возможность рисовать линии в позиции моего пальца, причем каждая линия имеет разную ширину/цвет и т.д.

Всякий раз, когда ACTION_DOWN запускается, я создаю новый Path и продолжаю добавлять его в ACTION_MOVE. Когда ACTION_UP запускается, я помещаю текущие Path и Paint в свои HashMap, таким образом сохраняя, какие Path использовали какие Paint, верно?

Когда я вызываю setRadius(float radius) извне этого класса, я вызываю paint.setStrokeWidth(radius), тем самым меняя ширину штриха текущего Paint.

Но по какой-то причине каждый раз, когда я вызываю setStrokeWidth(radius) ВСЕ изменения в Map.Entry?? Таким образом, ширина штриха Каждого Paint становится "новой" шириной штриха, и все перерисовывается с новой шириной штриха.

Вероятно, это очень очевидно, но я просто не могу найти ошибку.

Это мой DrawView.java.

package com.example.paintandprint;

import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class DrawView extends View implements OnTouchListener {
    Path path = new Path();
    Paint paint = new Paint();

    Map<Path, Paint> pathMap = new HashMap<Path, Paint>();

    public DrawView(Context context) {
        super(context);
        setFocusable(true);
        setFocusableInTouchMode(true);

        this.setOnTouchListener(this);

        paint.setColor(Color.BLACK);
        paint.setAntiAlias(true);
        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
    }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawPath(path, paint);

        for (Map.Entry<Path, Paint> p : pathMap.entrySet()) {
            canvas.drawPath(p.getKey(), p.getValue());
        }

    }

    public boolean onTouch(View view, MotionEvent event) {
        float eventX = event.getX();
        float eventY = event.getY();

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            path = new Path();
            path.reset();
            path.moveTo(eventX, eventY);
            return true;
        case MotionEvent.ACTION_MOVE:
            path.lineTo(eventX, eventY);
            break;
        case MotionEvent.ACTION_UP:
            pathMap.put(path, paint);
            break;
        default:
            return false;
        }

        invalidate();
        return true;
    }

    public float getRadius() {
        return paint.getStrokeWidth();
    }

    public void setRadius(float radius) {
        paint.setStrokeWidth(radius);
    }
}

Заранее спасибо!


person James    schedule 08.05.2013    source источник


Ответы (1)


В этих строках:

case MotionEvent.ACTION_UP:
    pathMap.put(path, paint);
    break;

Что вы присылаете в "краске"??? Это не указатель на структуру, которая заполняется предустановленными значениями. Разве каждый pathMap.put не отправляет один и тот же указатель, указывающий на одни и те же данные? Вот почему, если вы измените его один раз, вы измените его везде.

Вам нужно создать новый Paint для каждого pathMap.put, который вы делаете, и скопировать в него текущие значения Paint вашего класса.

case MotionEvent.ACTION_UP:
    Paint newPaint = new Paint();
    newPaint.set(paint); //copies the values over from the current class's paint
    pathMap.put(path, newPaint);
    break;
person HalR    schedule 09.05.2013
comment
Большое спасибо за это - я потратил целую вечность, пытаясь понять, как изменить ширину объекта Paint. - person David Christopher Reynolds; 29.10.2014