Canvas에서 패스를 그리는 데 다음 코드를 사용하고 있습니다. 지금까지 모든 것이 잘 작동하며이 코드를 사용하여 쉽게 패스를 그릴 수 있습니다.캔버스에서 가변 너비로 패스를 그리는 방법
하지만 이제 우리의 요구 사항은 가변 너비로 경로를 그리는 것입니다. 즉, 사용자가 적용한 압력을 기반으로 사용자가 그리는 경로를 의미합니다. 사용자가 가벼운 압력을 가하면 경로가 얇아지며 사용자가 높은 압력을 가하면 통로가 두꺼워 질 것입니다. 지금까지 나는 가변 너비로 도출 경로를 도출했지만 그려진 선은 매끄럽지 않습니다. 왜 그런 일이 벌어지는가? 내 코드에서 놓칠만한 것이있다.
도와주게 도와주세요. 나는 폭
public class FingerPaint extends GraphicsActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
public void colorChanged(int color)
{
}
public class MyView extends View
{
private static final float STROKE_WIDTH = 5f;
private Paint paint = new Paint();
private Path mPath = new Path();
ArrayList<Path> mPaths = new ArrayList<Path>();
ArrayList<Integer> mStrokes = new ArrayList<Integer>();
private float lastTouchX;
private float lastTouchY;
private final RectF dirtyRect = new RectF();
private int lastStroke = -1;
int variableWidthDelta = 0;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
public MyView(Context context)
{
super(context);
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
}
public void clear()
{
mPath.reset();
// Repaints the entire view.
invalidate();
}
@Override
protected void onDraw(Canvas canvas)
{
for(int i=0; i<mPaths.size();i++)
{
paint.setStrokeWidth(mStrokes.get(i));
canvas.drawPath(mPaths.get(i), paint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
float eventX = event.getX();
float eventY = event.getY();
int historySize = event.getHistorySize();
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
{
resetDirtyRect(eventX, eventY);
mPath.reset();
mPath.moveTo(eventX, eventY);
mX = eventX;
mY = eventY;
break;
}
case MotionEvent.ACTION_MOVE:
{
if (event.getPressure()>=0.00 && event.getPressure()<0.05)
{
variableWidthDelta = -2;
}
else if (event.getPressure()>=0.05 && event.getPressure()<0.10)
{
variableWidthDelta = -2;
}
else if (event.getPressure()>=0.10 && event.getPressure()<0.15)
{
variableWidthDelta = -2;
}
else if (event.getPressure()>=0.15 && event.getPressure()<0.20)
{
variableWidthDelta = -2;
}
else if (event.getPressure()>=0.20 && event.getPressure()<0.25)
{
variableWidthDelta = -2;
}
else if (event.getPressure() >= 0.25 && event.getPressure()<0.30)
{
variableWidthDelta = 1;
}
else if (event.getPressure() >= 0.30 && event.getPressure()<0.35)
{
variableWidthDelta = 2;
}
else if (event.getPressure() >= 0.35 && event.getPressure()<0.40)
{
variableWidthDelta = 3;
}
else if (event.getPressure() >= 0.40 && event.getPressure()<0.45)
{
variableWidthDelta = 4;
}
else if (event.getPressure() >= 0.45 && event.getPressure()<0.60)
{
variableWidthDelta = 5;
}
float dx = Math.abs(eventX - mX);
float dy = Math.abs(eventY - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
{
if(lastStroke != variableWidthDelta)
{
mPath.lineTo(mX, mY);
mPath = new Path();
mPath.moveTo(mX,mY);
mPaths.add(mPath);
mStrokes.add(variableWidthDelta);
}
mPath.quadTo(mX, mY, (eventX + mX)/2, (eventY + mY)/2);
mX = eventX;
mY = eventY;
}
for (int i = 0; i < historySize; i++)
{
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
}
break;
}
case MotionEvent.ACTION_UP:
{
for (int i = 0; i < historySize; i++)
{
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
}
mPath.lineTo(mX, mY);
break;
}
}
// Include half the stroke width to avoid clipping.
invalidate();
lastTouchX = eventX;
lastTouchY = eventY;
lastStroke = variableWidthDelta;
return true;
}
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;
}
}
/**
* Resets the dirty region when the motion event occurs.
*/
private void resetDirtyRect(float eventX, float eventY)
{
// The lastTouchX and lastTouchY were set when the ACTION_DOWN
// motion event occurred.
dirtyRect.left = Math.min(lastTouchX, eventX);
dirtyRect.right = Math.max(lastTouchX, eventX);
dirtyRect.top = Math.min(lastTouchY, eventY);
dirtyRect.bottom = Math.max(lastTouchY, eventY);
}
}
}
하나의 경로를 그리기 위해 사용
코드
어때 이것에 대해 http://stackoverflow.com/questions/9312518/android-find-pressure-on-screen – Raghunandan
그게 사실이 아닙니다. 쿠마. 'getPressure()'메서드를 사용할 수 있습니다. http://developer.android.com/reference/android/view/MotionEvent.html#getPressure(int) –
네, 틀 렸습니다. 이 API가 존재한다는 것을 결코 알지 못했습니다. 내 대답을 편집 할 것입니다. –