我遇到一个面试官给我出了这道上机题,要求当场写出来,比较考验安卓的功力,重点在对安卓的画图API的考察,效果如下:
下面来看几个画图API:
1、moveTo
moveTo
不会进行绘制,只用于移动移动画笔。
2、lineTo
lineTo
用于进行直线绘制。
mPath.lineTo(300, 300); canvas.drawPath(mPath, mPaint);
默认坐标从(0,0)开始
下面这段代码是把画笔移动到(100,100)再开始画
mPath.moveTo(100, 100); mPath.lineTo(300, 300); canvas.drawPath(mPath, mPaint);
3、quadTo
quadTo
用于绘制圆滑曲线,即贝塞尔曲线。
mPath.quadTo(x1, y1, x2, y2)
(x1,y1) 为控制点,(x2,y2)为结束点。
下面我看手指在屏幕上绘制路径的关键代码,我们会创建一个view,然后检测手指在这个view上的路径
@Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFFAAAAAA); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); canvas.drawPath(mPath, mPaint); if(isMirrorDraw) { canvas.drawPath(mOppositePath, mOppoPaint); } } 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; } } private void touch_up() { mPath.lineTo(mX, mY); mCanvas.drawPath(mPath, mPaint); 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); if(isMirrorDraw) { touch_opposite_start(x, y); } //必须调用invalidate重绘屏幕,这样画的线才能展示出来 invalidate(); break; case MotionEvent.ACTION_MOVE: //通过mPath.quadTo,quadTo 用于绘制圆滑曲线,即贝塞尔曲线 touch_move(x, y); if(isMirrorDraw) { touch_opposite_move(x, y); } invalidate(); break; case MotionEvent.ACTION_UP: //讲path最后指向mX,mY,然后mCanvas.drawPath touch_up(); if(isMirrorDraw) { touch_opposite_up(); } invalidate(); break; } return true; }
Activity的layout是:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".OppositeDrawActivity" > <RelativeLayout android:layout_width="match_parent" android:layout_height="60dp" android:paddingTop="5dp" android:id="@+id/bottom" android:layout_alignParentBottom="true" > <TextView android:id="@+id/label" android:layout_width="40dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_marginLeft="10dp" android:text="Mirror Effect" /> <ToggleButton android:id="@+id/settings_toggle_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/label" android:background="@drawable/toggle_background" android:textColor="#FF808080" android:textOff="Off" android:textOn="On" android:width="55sp" /> <Button android:id="@+id/btn_clear" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="20dp" android:background="@drawable/btn_background" android:text="clear" /> <Button android:id="@+id/change" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="20dp" android:layout_toLeftOf="@id/btn_clear" android:layout_toRightOf="@id/settings_toggle_button" android:background="@drawable/btn_background" android:layout_marginLeft="10dp" android:text="change" /> </RelativeLayout> <com.pic.optimize.DrawView android:id="@+id/drawview" android:layout_above="@id/bottom" android:layout_width="match_parent" android:layout_height="match_parent" > </com.pic.optimize.DrawView> </RelativeLayout>
DrawView就是检测和绘制手指路径的view