처음부터 차근차근
안드로이드 그래픽 본문
반응형
안드로이드에서의 그래픽
안드로이드는 XML 파일로 그래픽이나 애니메이션을 정의한다.
그리는 작업은 안드로이드 시스템이 담당한다.
onDraw() 메소드 안에 draw...()와 같은 메소드를 호출하여 직접 그린다.
전체적인 구조
public class MyView extends View {
...
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
// 여기에 그림그리는 코드
}
...
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// MyView를 생성하고 이것을 Activity의 컨텐트 뷰로 설정
MyView myView = new MyView(this);
setContentView(myView);
}
}
Canvas 클래스와 Paint 클래스
- Canvas 클래스 : 그림을 그리는 캔버스(화포)에 해당
- Paint 클래스 : 색상이나 선의 스타일, 채우기 스타일, 폰트, 앤티앨리어싱 여부 등과 같은 그리기 속성을 가지고 있는 클래스
예제
MyView class MainActivity 위치에다가 새로 생성
public class MyView extends View {
public MyView(Context context) {
super(context);
setBackgroundColor(Color.BLUE);
}
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.YELLOW);
paint.setStrokeWidth(20);
paint.setTextSize(50);
canvas.drawLine(100, 100, 300, 100, paint);
canvas.drawRect(100, 200, 300, 300, paint);
canvas.drawCircle(300, 500, 100, paint);
canvas.drawText("This is a test", 100, 350, paint);
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
MyView myView = new MyView(this);
setContentView(myView);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</LinearLayout>
예제2
위의 코드에서 MyView만 변경
public class MyView extends View {
public MyView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.YELLOW);
paint.setStrokeWidth(20);
paint.setTextSize(50);
//canvas.drawRoundRect(new RectF(30, 50, 600, 600), 45, 45, paint);
//canvas.drawOval(new RectF(30, 50, 400, 600), paint);
//canvas.drawArc(new RectF(30, 50, 400, 600), 0, 90, true, paint);
float[] pts = {30, 120, 120, 220, 120, 220, 180, 50, 180, 50, 400, 400};
canvas.drawLines(pts, paint);
}
}
커스텀 뷰를 XML에서 참조하기
위의 예제에서 MyView class와 activity_main 수정
public class MyView extends View {
public MyView(Context context) {
super(context);
setBackgroundColor(Color.YELLOW);
}
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(20);
canvas.drawArc(new RectF(30, 50, 600, 600), 120, 270, true, paint);
}
}
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
RectF(float left, float top, float right, float bottom)
지정된 타원 내부에 맞게 크기가 조정되는 지정된 호를 그리는 함수
RectF : rect 사각형 안에 원을 그린다.
startAngle : 시작 각도입니다
sweepAngle : 몇 도 그릴지 정합니다(시계반향)
useCenter : 맨 위 결과화면을 보면 됩니다(false : 호, true : 부채꼴모양)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.induk.graphic.MyView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
컨텍스트 도형 이용해서 도형그리기
drawable 아래에서 New -> Drawable Resource file 클릭 한후 이미지와 같이 새로 생성
border.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:thickness="0sp">
<size android:width="30sp" />
<solid android:color="#0000ff" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="5sp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="#0000FF"
android:text="컨텍스트 메뉴를 이용하여 도형그리기" />
<EditText
android:id="@+id/edtCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:inputType="number"
android:textColor="#ffffff"
android:gravity="center"
android:background="@drawable/border"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:text="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="개" />
</LinearLayout>
<com.induk.graphic.MyView
android:id="@+id/vCanvas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5sp"/>
</LinearLayout>
public class MyView extends View {
private int count;
private int what;
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
setBackgroundColor(Color.YELLOW);
setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
contextMenu.setHeaderTitle("도형선택");
contextMenu.add(0, 1, 0, "선");
contextMenu.add(0, 2, 0, "면");
contextMenu.add(0, 3, 0, "원");
contextMenu.add(0, 4, 0, "타원");
contextMenu.add(0, 5, 0, "부채꼴");
contextMenu.add(0, 6, 0, "텍스트");
}
});
}
public void setting(int w, int c) {
what = w;
count = c;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setTextSize(100);
paint.setStrokeWidth(20);
switch (what) {
case 1:
for (int ii=0; ii < count; ii++) {
canvas.drawLine(100, 100 + (50 * ii), 600, 100 + (50 * ii), paint);
}
break;
case 2:
canvas.drawRect(100, 200, 300, 300, paint);
break;
case 3:
for (int ii=0; ii < count; ii++) {
canvas.drawCircle(300 + (150 * ii), 500, 100, paint);
}
break;
case 4:
canvas.drawOval(new RectF(30, 50, 400, 600), paint);
break;
case 5:
canvas.drawArc(new RectF(30, 50, 400, 600), 0, 90, true, paint);
break;
case 6:
canvas.drawText("This is a test", 100, 350, paint);
break;
default:
break;
}
}
}
public class MainActivity extends AppCompatActivity {
private MyView myView;
private EditText edtCount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edtCount = (EditText) findViewById(R.id.edtCount);
myView = (MyView) findViewById(R.id.vCanvas);
}
@Override
public boolean onContextItemSelected(@NonNull MenuItem item) {
// int count;
// if (edtCount.getText().toString().equals("")) {
// count = 0;
// Toast myToast = Toast.makeText(this.getApplicationContext(),"숫자를 입력해주세요!", Toast.LENGTH_SHORT);
// myToast.show();
// }
// else {
// count = Integer.parseInt(edtCount.getText().toString());
// }
switch (item.getItemId()) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
myView.setting(item.getItemId(), count);
myView.invalidate(); // 중요!!!이 코드 없으면 감점, 메뉴가 바뀔 때마다 다시 그리게 하는 코드
return true;
default:
return super.onContextItemSelected(item);
}
}
}
출처 : 안드로이드프로그래밍(22-1학기)김용남교수 강의 내용 변형 및 요약
반응형
'프로그래밍 > Android' 카테고리의 다른 글
고급 위젯과 프래그먼트 (0) | 2022.06.13 |
---|---|
Splash 화면 만들기 (0) | 2022.06.03 |
RxJava (0) | 2022.05.08 |
Reactive programming(수정) (1) | 2022.04.22 |
팝업 메뉴 (1) | 2022.04.19 |
Comments