일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- 개인정보보호
- package-lock.json
- arrow function
- 개인정보보호교육
- 덧셈 암호
- 백엔드
- 한국정보보호산업협회기자단
- 호이스팅
- 한국산업인력공단
- function scope
- 곱셈 암호
- 가명정보처리
- 유클리드_알고리즘
- 한국정보보호산업협회
- pwnable.tw
- 디오판투스 알고리즘
- 포너블
- 웹 프레임워크
- Writeup
- 백엔드입문
- 동적타이핑
- node.js
- 개인정보안전성
- 개인정보보호위원회
- 모듈러 연산
- package.json
- 마감임박
- 무료교육
- 확장 유클리드 알고리즘
- 국가인적자원개발컨소시엄
- Today
- Total
짱짱해커가 되고 싶은 나
09-1. 그래픽 본문
안드로이드는 화면에 선, 원 등의 도형을 그리는 방식을 제공한다.
관련 메소드에서 좌표를 입력해서 그릴 수도 있고, 손가락으로 화면을 터치해서 그릴 수도 있다.
그래픽을 표현할 때는 View 클래스를 재정의하는 형태가 많이 사용된다.
* Canvas 클래스 (android.graphics.Canvas)
- 점, 선, 원, 사각형 그리기
- 텍스트 쓰기
- 이미지 출력
- drawPoint(float x, float y, Paint paint) : Paint 개체에 설정된 색상, 두께 등으로 점이 그려진다.
* Paint 클래스 (android.graphics.Paint)
- 색상 선택
- 스타일 선택
- 펜 두께 선택
- 글꼴 선택
- setColor() : 색상 지정
package com.example.graphic;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
setContentView(new MyGraphicView(this));
}
private static class MyGraphicView extends View {
public MyGraphicView(Context context){
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
canvas.drawLine(10, 10, 300, 10, paint);
paint.setColor(Color.BLUE);
paint.setStrokeWidth(5);
canvas.drawLine(10, 30, 300, 30, paint);
paint.setColor(Color.RED);
paint.setStrokeWidth(0);
paint.setStyle(Paint.Style.FILL);
Rect rect1 = new Rect(10, 50, 10+100, 50+100);
canvas.drawRect(rect1, paint);
paint.setStyle(Paint.Style.STROKE);
Rect rect2 = new Rect(130, 50, 130+100, 50+100);
canvas.drawRect(rect2, paint);
RectF rect3 = new RectF(250, 50, 250+100, 50+100);
canvas.drawRoundRect(rect3, 20, 20, paint);
canvas.drawCircle(60, 220, 50, paint);
paint.setStrokeWidth(5);
Path path1 = new Path();
path1.moveTo(10,290);
path1.lineTo(10+50, 290+50);
path1.lineTo(10+100, 290);
path1.lineTo(10+150, 290+50);
path1.lineTo(10+200, 290);
canvas.drawPath(path1, paint);
paint.setStrokeWidth(0);
paint.setTextSize(30);
canvas.drawText("안드로이드", 10, 390, paint);
}
}
}
onDraw()는 클래스가 생성되거나 무효화(invalidate)되면 호출되는 메소드다.
- Paint.setAntiAlias() : 도형의 끝을 부드럽게 처리
- Paint.setStorkeWidth() : 그려질 도형/글자 외곽선의 두께 설정 (0 == 기본 1px)
- Paint.setStyle() : 그려질 도형의 내부를 채울지 여부 결정 (기본 == FILL)
- Canvas.drawLine(x 시작, y 시작, x 끝, y 끝, Paint)
- Canvas.drawRect(rect, paint)
- Canvas.drawRoundRect(rect, x반지름, y반지름, paint) : 사각형 모서리를 둥글게 처리(x,y 값이 클수록 더 부드럽)
- Canvas.drawCircle(중심x, 중심y, 반지름, paint)
- Canvas.drawPath(path, paint)
- Canvas.drawText(text, x, y, paint)
- Rect 클래스(int 형)
- RectF 클래스(float 형)
- Path 클래스 : 연결된 여러 점을 가진 클래스
- Path.moveTo() : 해당 점으로 이동
- Path.lineTo() : moveTo()이후 점을 계속 추가
package com.example.graphic;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
setContentView(new MyGraphicView(this));
}
private static class MyGraphicView extends View {
public MyGraphicView(Context context){
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStrokeWidth(50);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLACK);
canvas.drawLine(40, 40, 40+500, 40, paint);
paint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawLine(40, 130, 40+500, 130, paint);
RectF rect3 = new RectF(100, 200, 500, 200+200);
canvas.drawOval(rect3, paint);
RectF rect4 = new RectF(100, 450, 100+200, 450+200);
canvas.drawArc(rect4, 45, 90, true, paint);
Rect rect5 = new Rect(100, 700, 300, 900);
paint.setColor(Color.BLUE);
canvas.drawRect(rect5, paint);
Rect rect6 = new Rect(150, 750, 350, 950);
paint.setColor(Color.argb(120, 255, 0, 0));
canvas.drawRect(rect6, paint);
}
}
}
- Paint.setStrokeCap() : 선이 끝나는 지점의 모양 설정
- Canvas.drawOval(RectF, paint) : 타원 그리기
- Canvas.drawArc(RectF, 시작 각, 스위핑 각, t/f, paint) : RectF에 맞는 원에서 호(false)/부채꼴(ture)을 그린다.
- Color.argb(투명도, 빨, 초, 파)
* 터치 이벤트
화면에 생성한 뷰를 터치하면 Touch 이벤트가 발생한다.
터치를 구현할 때는 View 클래스의 onTouchEvent()를 오버라이딩한다.
- MotionEvent.ACTION_DOWN : 손가락으로 화면을 누르기 시작했을 때
- MotionEvent.ACTION_MOVE : 터치 후 손가락을 움직일 때
- MotionEvent.ACTION_UP : 손가락을 화면에서 뗄 때
- MotionEvent.ACTION_CANCEL : 터치가 취소될 때
프로젝트1 : 그림판
- 옵션 메뉴 ( 선 그리기/원 그리기)
- 터치 이벤트로 그리기
package com.example.graphic;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
public class MainActivity extends AppCompatActivity {
final static int LINE = 1, CIRCLE = 2;
static int curShape = LINE;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
setContentView(new MyGraphicView(this));
setTitle("간단 그림판");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0,1,0, "선 그리기");
menu.add(0,2,0,"원 그리기");
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch(item.getItemId()){
case 1:
curShape = LINE;
return true;
case 2:
curShape = CIRCLE;
return true;
}
return super.onOptionsItemSelected(item);
}
private static class MyGraphicView extends View{
int startX = -1, startY = -1, stopX = -1, stopY = -1;
public MyGraphicView(Context context){
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
startX = (int)event.getX();
startY = (int)event.getY();
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
stopX = (int)event.getX();
stopY = (int)event.getY();
this.invalidate();
break;
}
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.RED);
switch(curShape){
case LINE:
canvas.drawLine(startX, startY, stopX, stopY, paint);
break;
case CIRCLE:
int radius = (int)Math.sqrt(Math.pow(stopX - startX, 2) +
Math.pow(stopY - startY, 2));
canvas.drawCircle(startX, startY, radius, paint);
break;
}
}
}
}
ACTION_MOVE와 ACTION_UP을 동일하게 처리하는 이유는 드래그할 때마다 그려지는 선/원이 손가락을 계속 따라다니며 보이는 효과를 주기 위함이다. 화면에서 손가락을 떼면 ACTION_UP이 발생하고 onTouchEvent()를 더 이상 실행하지 않는다.
프로젝트2 : 그림판 수정
옵션 메뉴 - 선, 원, 사각형, 서브 메뉴(색상 변경-빨,초,파)
package com.example.graphic;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
public class MainActivity extends AppCompatActivity {
final static int LINE = 1, CIRCLE = 2, RECT = 3;
final static int RED = 1, GREEN = 2, BLUE = 3;
static int curShape = LINE;
static int curColor = RED;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
setContentView(new MyGraphicView(this));
setTitle("간단 그림판");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0,1,0, "선 그리기");
menu.add(0,2,0,"원 그리기");
menu.add(0,3,0,"사각형 그리기");
SubMenu subMenu = menu.addSubMenu("색상 변경 >>");
subMenu.add(1, 1, 0, "빨강");
subMenu.add(1,2,0,"초록");
subMenu.add(1,3,0,"파랑");
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch(item.getGroupId()) {
case 0:
switch (item.getItemId()) {
case 1:
curShape = LINE;
return true;
case 2:
curShape = CIRCLE;
return true;
case 3:
curShape = RECT;
return true;
}
break;
case 1:
switch (item.getItemId()) {
case 1:
curColor = RED;
return true;
case 2:
curColor = GREEN;
return true;
case 3:
curColor = BLUE;
return true;
}
}
return super.onOptionsItemSelected(item);
}
private static class MyGraphicView extends View{
int startX = -1, startY = -1, stopX = -1, stopY = -1;
public MyGraphicView(Context context){
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
startX = (int)event.getX();
startY = (int)event.getY();
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
stopX = (int)event.getX();
stopY = (int)event.getY();
this.invalidate();
break;
}
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
switch(curColor){
case RED:
paint.setColor(Color.RED);
break;
case GREEN:
paint.setColor(Color.GREEN);
break;
case BLUE:
paint.setColor(Color.BLUE);
break;
}
switch(curShape){
case LINE:
canvas.drawLine(startX, startY, stopX, stopY, paint);
break;
case CIRCLE:
int radius = (int)Math.sqrt(Math.pow(stopX - startX, 2) +
Math.pow(stopY - startY, 2));
canvas.drawCircle(startX, startY, radius, paint);
break;
case RECT:
canvas.drawRect(startX, startY, stopX, stopY, paint);
break;
}
}
}
}
'모바일' 카테고리의 다른 글
10-1. 액티비티와 인텐트 (0) | 2021.02.24 |
---|---|
09-2. 이미지 (0) | 2021.02.24 |
08-2. SD 카드 폴더/파일 처리 연습 (0) | 2021.02.22 |
08-1. 파일 처리 (0) | 2021.02.22 |
07-3. 메뉴/토스트/다이얼로그 연습 (0) | 2021.02.20 |