android canvas 의 onDraw() 내에서
삼각형, 별, 하트 그리기 예제입니다.
Canvas 내 터치 영역에서 각 도형을 새로 그리는 예제도 TouchEvent 안에 적용되어 있습니다.
참고url
http://android-er.blogspot.kr/2014/05/draw-star-on-canvas.html
간단히 도형을 선택하는 버튼과 custom view가 정의 됩니다.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/bt_triangle" android:text="삼각형"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/bt_triangle" android:id="@+id/bt_star" android:text="별"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/bt_star" android:id="@+id/bt_heart" android:text="하트"/> <poisonrose.myapplication_canvas.MyView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="10dp" android:layout_below="@id/bt_triangle" android:id="@+id/my_view"/> </RelativeLayout>
MainActivity.java
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final MyView my_view = (MyView) findViewById(R.id.my_view); Button bt_triangle = (Button) findViewById(R.id.bt_triangle); bt_triangle.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { my_view.drawTriangle(); } }); Button bt_star = (Button) findViewById(R.id.bt_star); bt_star.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { my_view.drawStar(); } }); Button bt_heart = (Button) findViewById(R.id.bt_heart); bt_heart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { my_view.drawHeart(); } }); } }
MyView.java
생성자에서는 Paint 와 Path를 초기화 합니다.
실제 도형을 그리는 부분은 onDraw내의 canvas.drawPath() 에서 그리며,
포퍼먼스를 고려하여 항상, path의 reset(), close()를 잘 사용하여야 합니다.
코드내에서 보여지는 x, y 값이 선이 시작하는 부분이며,
TouchEvent에서는 현재 터치값을 불러와서 도형을 그리는 형태로 코드를 작성했습니다.
import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Point; import android.graphics.RectF; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class MyView extends View { Paint m_Paint; Path m_Path; Canvas m_Canvas; enum Mode { TRIANGLE, STAR, HEART } private Mode mMode; private int mViewWidth = 0; private int mViewHeight = 0; public MyView(Context context) { super(context); initMyView(); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); initMyView(); } public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initMyView(); } public void initMyView(){ m_Paint = new Paint(); m_Paint.setAntiAlias(true); m_Paint.setDither(true); m_Paint.setColor(0xFFFF0000); m_Paint.setStyle(Paint.Style.STROKE); m_Paint.setStrokeJoin(Paint.Join.ROUND); m_Paint.setStrokeCap(Paint.Cap.ROUND); m_Paint.setStrokeWidth(4); m_Path = new Path(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { mViewWidth = MeasureSpec.getSize(widthMeasureSpec); mViewHeight = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(mViewWidth, mViewHeight); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); m_Canvas = canvas; m_Canvas.drawColor(0xFFFFFFFF); if(mMode == Mode.HEART) { float x = mViewWidth/2; float y = mViewHeight/2; m_Canvas.rotate(45,x,y); } // Path 갱신 영역 m_Canvas.drawPath(m_Path, m_Paint); } public void drawTriangle() { float x = mViewWidth/2; float y = mViewHeight/2; drawTriangle(x, y); } public void drawTriangle(float x, float y) { mMode = Mode.TRIANGLE; int side = 200; /** 삼각형 크기 */ int height = 300; y = y - height; m_Path.reset(); Point point1_draw = new Point((int)x, (int)y); // 왼 Point point2_draw = new Point((int)x-side, (int)y+height); // 아래 Point point3_draw = new Point((int)x+side, (int)y+height); // 오른 m_Path.moveTo(point1_draw.x, point1_draw.y); m_Path.lineTo(point2_draw.x, point2_draw.y); m_Path.lineTo(point3_draw.x, point3_draw.y); m_Path.lineTo(point1_draw.x, point1_draw.y); m_Path.close(); invalidate(); } public void drawStar() { float x = mViewWidth/2; float y = mViewHeight/2; drawStar(x, y); } public void drawStar(float x, float y) { mMode = Mode.STAR; int radius = 200; /** 별 크기 */ y = y - radius; int numOfPt = 5; double section = 2.0 * Math.PI/numOfPt; int innerRadius = (int) (radius / 2.5); m_Path.reset(); m_Path.moveTo( (float)(x + radius * Math.cos(0)), (float)(y + radius * Math.sin(0))); m_Path.lineTo( (float)(x + innerRadius * Math.cos(0 + section/2.0)), (float)(y + innerRadius * Math.sin(0 + section/2.0))); for(int i=1; i < numOfPt; i++){ m_Path.lineTo( (float)(x + radius * Math.cos(section * i)), (float)(y + radius * Math.sin(section * i))); m_Path.lineTo( (float)(x + innerRadius * Math.cos(section * i + section/2.0)), (float)(y + innerRadius * Math.sin(section * i + section/2.0))); } m_Path.close(); invalidate(); } public void drawHeart() { float x = mViewWidth/2; float y = mViewHeight/2; drawHeart(x, y); } public void drawHeart(float x, float y) { mMode = Mode.HEART; float length = 200; // 하트 크기 m_Path.reset(); m_Path.moveTo(x,y); m_Path.lineTo(x-length, y); m_Path.arcTo(new RectF(x-length-(length/2),y-length,x-(length/2),y),90,180); m_Path.arcTo(new RectF(x-length,y-length-(length/2),x,y-(length/2)),180,180); m_Path.lineTo(x,y); m_Path.close(); invalidate(); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touchDraw(x, y); break; case MotionEvent.ACTION_MOVE: touchDraw(x, y); break; case MotionEvent.ACTION_UP: touchDraw(x, y); break; } return true; } private void touchDraw(float x, float y) { if(mMode == Mode.TRIANGLE) { drawTriangle(x, y); } else if(mMode == Mode.STAR) { drawStar(x, y); } else if(mMode == Mode.HEART) { drawHeart(x, y); } } }
'Android' 카테고리의 다른 글
[안드로이드] Android studio logcat color 변경 (0) | 2018.01.18 |
---|---|
[안드로이드] 갤럭시 S8(18.5:9), LG G6(18:9) 화면비 적용하기 (0) | 2017.06.09 |
[안드로이드] android contentProvider example (A앱 < B앱 db 접근) (1) | 2017.05.16 |
[안드로이드] android keypad 내의 Done(enter,search,...) 눌렀을 경우 이벤트 (0) | 2017.05.14 |
[안드로이드] Android studio vector image 사용하기 (0) | 2017.05.12 |