버츄얼 디바이스 켜기
1. 커스텀 뷰
Graphic1_CustomView_basic1 프로젝트 만들기
※ 사용자 뷰(커스텀 뷰)
1) View 클래스를 상속받아 구현한다.
- 생성자가 반드시 있어야 한다.
생성자1(Context context) - 자바만
생성자2(Context context, AttributeSet attrs) - xml 파일 존재할 때 AttributeSet 객체 필요하다.
- onDraw(Canvas canvas) 메서드를 오버라이딩해서 구현
- onTouchEvent(MotionEvent event) 메서드 오버라이딩해서 구현
- 필요시 Thread 구현
2) XML에 등록 - AttributeSet attrs 객체가 있는 View(클래스)만 가능
3) Java에서 - setContentView(myView);
- MainActivity.java
package com.example.graphic1_customview_basic1;
import androidx.annotation.Nullable;
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.Typeface;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
//View 클래스 상속받아 구현
class MyView extends View {
int x = 300, y = 100;
int r, g, b;
/**
* 생성자
* @param context
* @param a
* @param y
*/
public MyView(Context context, int a, int y) {
super(context);
this.y += b;
//색상 추가
setBackgroundColor(Color.argb(20,50,80,180));
}
/**
* 그리기 - 그래픽
* canvas : 그림판 - 도형, 이미지, 글자
* paint : 그리기 도구
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//그리기 도구 - Paint 객체생성
Paint paint = new Paint();
//랜덤색상 출력
r = (int)(Math.random() * 256);
g = (int)(Math.random() * 256);
b = (int)(Math.random() * 256);
//paint 설정
/*
- Paint 객체 메서드
setColor() : 색
setStrokeWidth() : 선 두께
setTextSize() : 글자크기
setAntiAlias(true/false) : 경계선을 부드럽게 처리
setStyle(Paint.Style.FILL/STROKE/FILL_AND_STROKE) 등
*/
paint.setColor(Color.rgb(r, g, b));
paint.setStyle(Paint.Style.STROKE); //Paint.Style.FILL은 채우기
paint.setStrokeWidth(7); //선의 굵기
//도형그리기
/*
- 점 그리기 : drawPoint(x, y, paint);
- 직선 그리기 : drawLine(x1, y1, x2, y2, paint);
- 원 그리기 : drawCircle(중심x, 중심y, 반지름, paint);
- 원호 그리기 : drawAct(new RectF(x1, y1, x2, y2)내접원, 시작각, 회전각, 중심점사용여부(false), paint);
- 사각형 그리기 : drawRect(좌상x, 좌상y, 우하x, 우하y, paint);
- 둥근사각형 그리기 : drawRoundRect(Rect rect, 모서리사각형너비(width), 모서리사각형높이(height), paint);
- 글자 그리기 : drawText(글자문자열, x, y, paint);
- 기하학적인 도형 : drawPath(Path path, paint);
path.moveTo(x, y) : 이동
path.lineTo(x, y) : 연결해가는 그리기
*/
canvas.drawCircle(x - 100 , y + 70,80, paint); //원
canvas.drawArc(new RectF(700,400, 1000,700), 45, 320, true, paint); //원호
//글자쓰기
paint.setTextSize(50);
Typeface t = Typeface.create(Typeface.SANS_SERIF, Typeface.ITALIC); //폰트 타입객체 생성
paint.setTypeface(t); //폰트 타입설정
canvas.drawText("안드로이드",500,200, paint);
//경로그리기
Path path = new Path();
path.moveTo(500,500);
path.lineTo(700,700);
path.lineTo(500,700);
path.lineTo(500,500);
canvas.drawPath(path, paint);
canvas.drawRect(x, y,x+150,y+150, paint);
//화면을 다시 그리기
invalidate();
//스레드를 통해 인터벌 주기
try {
Thread.sleep(500);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 터치이벤트 추가
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
//바닥에 닫으면 맨 위로 좌표 이동
if(this.getHeight() > y) {
y = y + 100; //100씩 이동
}else {
y = 0;
}
return false;
}
}
public class MainActivity extends AppCompatActivity {
int x = 0, y = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//사용자 뷰 객체 적용
MyView w = new MyView(this,50,50);
setContentView(w);
}
}
2. 커스텀 뷰2
Graphic2_CustomView_basic2 프로젝트 만들기
그림판 작성
※ 옵션메뉴 추가
※ 커스텀 뷰를 내부 클래스로 적용
※ 터치이벤트 처리
- MainActivity.java
package com.example.graphic2_customview_basic2;
import static android.graphics.drawable.GradientDrawable.LINE;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.KeyEvent;
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, CYCLE = 2, RECT = 3;
static int shape = LINE;
static Paint paint = new Paint();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyView myView = new MyView(this);
setContentView(myView);
setTitle("그림판");
}
/**
* 커스텀 뷰 - 내부클래스
*/
class MyView extends View {
int startX = -1, startY= -1, stopX = -1, stopY = -1 ;
/**
* 생성자
* @param context
*/
public MyView(Context context){
super(context);
}
/**
* 그래픽 그리기
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
switch (shape){
case LINE:
canvas.drawLine(startX, startY, stopX, stopY,paint);
break;
case CYCLE:
int radius = (int) Math.sqrt(Math.pow(stopX-startX,2)+Math.pow(stopY - startX, 2));
canvas.drawCircle(startX,startY,radius,paint);
break;
case RECT:
canvas.drawRect(startX,startY,startX+ Math.abs((stopX-startX)), startY+Math.abs((stopY-startX)), paint);
}
}
/**
* 터치이벤트 추가
* @param event
* @return
*/
@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;
}
}
//-----------------------------------------------------------------------------------------------------------------------------
/*
- 옵션메뉴를 작성한다.
1) 메뉴를 구현 : onCreateOptionsMenu(Menu menu) 메서드 오버라이딩 구현
2) 메뉴가 선택되었을 때 할 일 : onOptionsItemSelected(@NonNull MenuItem item) 오버라이딩 구현
*/
/**
* 메뉴 구현
* @param menu
* @return
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
//add(그룹ID, itemID, orderID); -> getGroupId(), getItemId(), getOrderId()
//메인 메뉴
menu.add(0, 1, 0, "선 그리기");
menu.add(0, 2,0,"원 그리기");
menu.add(0, 3,0,"사각형그리기");
//서브 메뉴 - Menu 객체 생성해서 추가한다.
Menu sub = menu.addSubMenu("색상변경");
sub.add(1,4,1,"빨강");
sub.add(1,4,2,"초록");
sub.add(1,4,3,"파랑");
return true;
}
/**
* 메뉴선택시 이벤트처리
* @param item
* @return
*/
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch(item.getItemId()) {
case 1:
shape = LINE; //shape변수값을 LINE으로 변경
return true;
case 2:
shape = CYCLE; //원
return true;
case 3:
shape = RECT; //사각형
return true;
case 4:
if(item.getOrder() == 1) {
paint.setColor(Color.RED);
}else if(item.getOrder() == 2) {
paint.setColor(Color.GREEN);
}else if(item.getOrder() == 3) {
paint.setColor(Color.BLUE);
}
break;
}
return super.onOptionsItemSelected(item);
}
}
3. 커스텀 뷰3 : XML 가져오기 - AttributeSet
Graphic3_CustomView_SeeInXML 프로젝트 만들기
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--자바로 작성된 클래스를 가져와 구현-->
<com.example.graphic3_customview_seeinxml.CustomView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
- MainActivity.java
package com.example.graphic3_customview_seeinxml;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
- CustomView.java
package com.example.graphic3_customview_seeinxml;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class CustomView extends View {
/**
* 생성자1
* @param context
*/
public CustomView(Context context) {
super(context);
setBackgroundColor(Color.YELLOW);
}
/**
* 생성자2 - XML에서 구현할 생성자
* @param context
* @param attrs
*/
public CustomView(Context context, AttributeSet attrs) {
super(context);
setBackgroundColor(Color.YELLOW);
}
//그리기
float x = 0, y = 0;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawArc(new RectF(50 + x, 50 + y , 600 + x, 600 + y), 45, 300 - (int)x, true, paint);
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
x = event.getX();
y = event.getY();
return true;
}
}
4. 커스텀 뷰4 : 그림판 만들기
Graphic4_CustomView_DrawEX 프로젝트 만들기
res/drawable 경로에 brush.png, eraser.png, new_pic.png, save.png 사진 파일 넣기
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FFCCCCCC">
<include layout="@layout/myframe"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<ImageButton
android:src="@drawable/new_pic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageButton
android:src="@drawable/brush"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageButton
android:src="@drawable/eraser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageButton
android:src="@drawable/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<com.example.graphic4_customview_drawex.MyTouchView
android:id="@+id/drawing"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#FFFFFFFF"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal">
<LinearLayout
android:id="@+id/paint_colors"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal">
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="5dp"
android:background="#FF000000"
android:tag="#FF000000"
android:onClick="clicked"/>
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="5dp"
android:background="#FFFF0000"
android:tag="#FFFF0000"
android:onClick="clicked"/>
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="5dp"
android:background="#FFFF6600"
android:tag="#FFFF6600"
android:onClick="clicked"/>
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="5dp"
android:background="#FFFFCC00"
android:tag="#FFFFCC00"
android:onClick="clicked"/>
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="5dp"
android:background="#FF009900"
android:tag="#FF009900"
android:onClick="clicked"/>
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="5dp"
android:background="#FFFFFFFF"
android:tag="#FFFFFFFF"
android:onClick="clicked"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
- myframe.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#ffffff">
<!--텍스트뷰를 추가 : style을 만들어서 적용해보자-->
<TextView style="@style/myTextView"/>
</LinearLayout>
- res/values/myTextViewStyle.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="myTextView" >
<!--<item name="속성명">속성값</item>-->
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:text">"그림판"</item>
<item name="android:textColor">@color/title</item>
<item name="android:textSize">30sp</item>
<item name="android:textStyle">bold</item>
<item name="android:layout_gravity">center</item>
<item name="android:layout_marginTop">3dp</item>
<item name="android:layout_marginBottom">3dp</item>
</style>
</resources>
- res/values/colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<!--내가만든 색상-->
<color name="title">#3F51B5</color>
</resources>
- res/values/a.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 연습용 스타일이다.. 삭제해도 무방하다-->
<resources>
<style name="myButton">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:text">내가만든버튼</item>
</style>
</resources>
- MyTouchView.java
package com.example.graphic4_customview_drawex;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class MyTouchView extends View {
public Paint paint = new Paint();
private Path path = new Path();
private int paintColor = 0xFF000000;
private Paint canvasPaint;
private Canvas drawCanvas;
private Bitmap canvasBitmap;
/**
* 생성자1
* @param context
*/
public MyTouchView(Context context){super(context);}
/**
* 생성자2 - XML에서 구현할 생성자
* @param context
* @param attrs
*/
public MyTouchView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setAntiAlias(true);
paint.setStrokeWidth(10f);
paint.setColor(paintColor);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
}
/**
* 크기가 변화되면 호출되는 메서드
* @param w
* @param h
* @param oldw
* @param oldh
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//그림판 캔버스 생성
canvasBitmap = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
/**
* 그래픽
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(canvasBitmap,0,0,canvasPaint);
canvas.drawPath(path,paint);
}
/**
* 터치이벤트
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
switch(event.getAction()) {//getAction() 액션값 가져옴
//손가락으로 누르면
case MotionEvent.ACTION_DOWN:
path.moveTo(touchX, touchY); //이동
break;
//이동하면
case MotionEvent.ACTION_MOVE:
path.lineTo(touchX,touchY); //그려라
break;
//손가락 떼면
case MotionEvent.ACTION_UP:
drawCanvas.drawPath(path, paint); //그림 그리고 나서
path.reset(); //지워라
default:
return false;
}
invalidate();
return true;
}
/**
* 컬러설정 메서드 구현
* @param newColor
*/
public void setColor(String newColor) {
invalidate();
paintColor = Color.parseColor(newColor); //색상값 저장
paint.setColor(paintColor);
}
}
- MainActivity.java
package com.example.graphic4_customview_drawex;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity {
MyTouchView myDrawView;
ImageButton currPaint, erasePaint;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myDrawView = (MyTouchView) findViewById(R.id.drawing);
LinearLayout paintLayout = (LinearLayout) findViewById(R.id.paint_colors);
currPaint = (ImageButton) paintLayout.getChildAt(0);
erasePaint = (ImageButton) paintLayout.getChildAt(5);
}
public void clicked(View view) {
if(view != currPaint) {
String color = view.getTag().toString();
if(view == erasePaint) {
myDrawView.paint.setStrokeWidth(80f);
}
else {
myDrawView.paint.setStrokeWidth(10f);
}
myDrawView.setColor(color);
currPaint = (ImageButton) view;
}
}
}
5. 이미지 그리기 : AttributeSet 객체가 아닌 레이아웃에 추가
Image1_basic 프로젝트 만들기
res/drawable 경로에 left.png, lena.png, minus.png, plus.png, right.png 사진 파일 넣기
- activity_main.xml
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:background="#DAD8D8">
<ImageButton
android:id="@+id/imageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="expand"
app:srcCompat="@drawable/plus"/>
<ImageButton
android:id="@+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="shrink"
app:srcCompat="@drawable/minus"/>
<ImageButton
android:id="@+id/imageButton3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="rotateLeft"
app:srcCompat="@drawable/left"/>
<ImageButton
android:id="@+id/imageButton4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="rotateRight"
app:srcCompat="@drawable/right"/>
</LinearLayout>
<LinearLayout
android:id="@+id/imageDisplay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
</LinearLayout>
</LinearLayout>
- MainActivity.java
package com.example.image1_basic;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
/*
이미지 사용방법
1) 방법1 : 이미지를 리소스에 추가해서 사용하는 방법
- 이미지를 res/drawable폴더에 추가한다.
- 안드로이드는 확장자를 제외한 파일의 이름을 식별자로 활용한다.
2) 방법2 : 직접 이미지 파일을 읽어서 그리는 방법
- 이미지 경로를 이용해서 >> 비트맵으로 읽어오는 방법이다.
- 게임과 같은 애플리케이션에서는 개발자가 이미지를 직접 그려주는 방법을 선호한다.
- 순서 1) 비트맵 읽기
Bitmap bitmap = BitmapFactory.decodeFile(filePath.getAbsolutePath());
또는 Bitmap bitmap = BitmapFactory.decodeResource(getResource(), R.drawable.이미지)
- getResource() : 이미지 데이터를 포함하는 애플리케이션 리소스객체
즉, Resource객체를 가져와서... R.drawable.이미지 객체를 잦아
디코딩해서 비트맵으로 전환한다.
- R.drawable.이미지 : 이미지의 리소스 식별자
- 순서 2) 비트맵 그리기 - drawBitmap()
. canvas.drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
- bitmap : 화면에 그릴 비트맵
- x, y : 그릴 위치
- patint: 이미지를 변환할 변환행렬이 들어있는 Pait객체 (없으면 null)
- 확대 축소 - createScaledBitmap
. Bitmap.createScaledBitmap(bitmap, width, height, flase) :
- width * height의 크기로 비트맵을 생성한다.
- 변환 - preScale(float sx, float sy)
. 도형의 크기를 x와 y축으로 sx, sy만큼 변경한다.
. M' = M * S(sx, sy)
*/
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity {
float scaleX = 1.0f, scaleY = 1.0f, rotateAngle;
MyView displayView;
/**
* 내부클래스 - 사용자 뷰
*/
public class MyView extends View {
public MyView(MainActivity context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
//이미지의 중심점
int centerX = getWidth() / 2;
int centerY = getHeight() / 2;
//크기변환
canvas.scale(scaleX, scaleY, centerX, centerY);
//회전
canvas.rotate(rotateAngle, centerX, centerY);
//비트맵 객체 생성
Bitmap picture = BitmapFactory.decodeResource(this.getResources(), R.drawable.lena);
//이미지 그리기
canvas.drawBitmap(picture, 0, 0, paint);
}
}
//실행
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout layout = (LinearLayout) findViewById(R.id.imageDisplay);
//사용자 뷰를 특정한 컨테이너에 추가
displayView = new MyView(this);
layout.addView(displayView);
}
public void expand(View view) {
scaleX += 0.3;
scaleY += 0.3;
displayView.invalidate();
}
public void shrink(View view) {
scaleX -= 0.3;
scaleY -= 0.3;
displayView.invalidate();
}
public void rotateLeft(View view) {
rotateAngle -= 30;
displayView.invalidate();
}
public void rotateRight(View view) {
rotateAngle += 30;
displayView.invalidate();
}
}
6. AnimationDrawable - 애니메이션 동작
Image2_Animation1_dawable 프로젝트 만들기
※ 애니메이션 구현
1) drawable 폴더에 animation-list태그를 루트 요소로 갖는 xml파일을 만든다.
2) Java에서 AnimationDrawable 객체를 생성한다.
start() : 애니메이션 객체 시작
stop() : 애니메이션 객체 중지
res/drawable 경로에 frame1.png, frame2.png, frame3.png, frame4.png, frame5.png, frame6.png, frame7.png, frame8.png 사진 파일 넣기
- res/drawable/myanimation.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<!--oneshot이 false면 한번만, true면 무한반복-->
<!--이미지프레임, 시간(초)-->
<item android:drawable="@drawable/frame1" android:duration="200"/>
<item android:drawable="@drawable/frame2" android:duration="200"/>
<item android:drawable="@drawable/frame3" android:duration="200"/>
<item android:drawable="@drawable/frame4" android:duration="200"/>
<item android:drawable="@drawable/frame5" android:duration="200"/>
<item android:drawable="@drawable/frame7" android:duration="200"/>
<item android:drawable="@drawable/frame8" android:duration="200"/>
</animation-list>
- res/values/mybuttonstyle.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="mybtn">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="backgroundTint">#3F51B5</item>
<item name="android:textColor">@color/white</item>
</style>
</resources>
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_gravity="center_horizontal">
<Button
android:id="@+id/btnStart"
style="@style/mybtn"
android:onClick="mOnClick"
android:layout_marginRight="5dp"
android:text="시작"/>
<Button
android:id="@+id/btnStop"
style="@style/mybtn"
android:onClick="mOnClick"
android:text="정지"/>
</LinearLayout>
<ImageView
android:id="@+id/imgFrame"
android:layout_width="300dp"
android:layout_height="450dp"
android:layout_marginTop="20dp"
android:layout_gravity="center"/>
<EditText
android:id="@+id/state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:hint="걷고 있습니다."
android:gravity="center_horizontal"/>
</LinearLayout>
- MainActivity.java
package com.example.image2_animation1_dawable;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Color;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
AnimationDrawable mAnimation;
EditText state ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView = (ImageView)findViewById(R.id.imgFrame);
state = (EditText)findViewById(R.id.state);
imageView.setBackgroundResource(R.drawable.myanimation);
//애니메이션드로우어블 객체 초기화
mAnimation = (AnimationDrawable)imageView.getBackground();
}
/**
* 버튼 눌렀을 때 호출 메서드
* @param v
*/
public void mOnClick(View v) {
switch(v.getId()) {
case R.id.btnStart:
mAnimation.start(); //start() : 애니메이션 시작
state.setText("걷기시작합니다.");
state.setTextColor(Color.BLUE);
break;
case R.id.btnStop:
mAnimation.stop(); //stop() : 애니메이션 중지
state.setText("정지했습니다.");
state.setTextColor(Color.RED);
break;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
mAnimation.start();
state.setTextColor(Color.BLUE);
return true;
}else if(event.getAction() == MotionEvent.ACTION_UP) {
mAnimation.stop();
state.setTextColor(Color.RED);
return true;
}
return super.onTouchEvent(event);
}
}
7. SurfaceView
Image3_SurfaceView1 프로젝트 만들기
※ SurfaceHolder.Callback 함수 구현
- surfaceCreated()
서피스가 준비되면 스레드를 시작한다.
서피스 뷰의 화면이 생성되면 호출된다.
여기에 그림을 그리는 스레드를 생성해 놓는다.
- surfaceDestroyed()
서피스가 파괴되기 직전에 호출된다.
이 메서드가 호출된 뒤에는 더 이상 그릴 수가 없다.
여기에 그림을 그리는 스레드를 종료시킨다.
- surfaceChanged()
서피스가 변경될 때 호출 - 화면의 구조(포맷, 크기 등)가 변경될 때 호출된다.
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button"/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"/>
</LinearLayout>
- MainActivity.java
package com.example.image3_surfaceview1;
import android.os.Bundle;
/*
서피스 뷰(SurfaceView)를 활용한 그리기 (애니메이션)
. 기존 드로어블뷰의 문제점
복잡하지 않은 그래픽은 캔버스로 그리면 된다. 하지만 복잡해지면... 안드로이드의 메인스레드의 시간을 너무 빼앗아서
느려지거나, 멈춤현상처럼 느껴지고, ANR(Application Not Responding) 오류가 발생할 수도 있다.
. SurfaceView를 활용해서 해결
별도의 스레드로 그림을 그려서 안드로이드 시스템이 그화면을 복사하게 지원하는 방식
. 구현방법
1) activity화면으로 SurfaceView를 설정하고
2) 새로운 Thread에서 SurfaceView에 그림을 그리면 된다.
3) ★ 이때....주의할 점은 안드로이드가 Surface를 생성하기 전에 그림을 그리면 안된다.
그래서 Surface가 생성되고 소멸되는 시점을 그림을 담당하는 스레드에게 알려줘야 한다.
그러한 목적으로 SurfaceHolder.Callback을 구현한다.
4) 서피스 뷰 객체는 우리가 직접처리할 수 없고 반드시 SurfaceHolder를 통해서 처리해야 한다.
- 왜냐하면 안드로이드 시스템이 서피스뷰를 실제장치의 뷰화면으로 부지런히 복사해서 구현하기 때문이다.
>> SurfaceHolder객체 생성
SurfaceHolder holder = getHolder();
>> SurfaceHolder의 콜백메소드 받기
holder.addCallback(this);
5) ★어떤 순서로 그림을 그리는지 보자! ★
① 그림을 그리기전에 lockCanvas()를 호출해서 서피스뷰의 캔버스를 독점적으로 확보해놓는다.
② 캔버스에 그림을 그린다.
③ 다 그리고 나면 unlockCanvasAndPost()를 호출해서 사용자가 그려놓은 그대로 서피스뷰를 실제장치로 복사한다.
*/
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
MySurfaceView view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view = new MySurfaceView(this);
setContentView(view);
}
}
- MySurfaceView.java
package com.example.image3_surfaceview1;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import androidx.annotation.NonNull;
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {//implement 방법 : ctrl + i
public Ball basket[] = new Ball[20]; //Ball 객체 저장 배열
private MyThread thread; //내부클래스로 구현된 클래스
public MySurfaceView(Context context) {
super(context);
SurfaceHolder holder = getHolder(); //서피스뷰 홀더 객체를 가져온다.
holder.addCallback(this); //서피스뷰 홀더의 콜백메서드를 받을 수 있게 서피스뷰 홀더에 콜백메서드 추가한다.
thread = new MyThread(holder); //스레드 생성
for(int i=0 ; i < 20 ; i++) {
basket[i] = new Ball(20);
}
}
/**
* 스레드 객체 반환 메서드
* @return
*/
public MyThread getThread() {
return thread;
}
//-------------------------------------------------------------------------------------
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
//스레드 시작
thread.setRunning(true); //스레드에 구현해 놓은 메서드 : true, false 제어
thread.start();
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int format, int width, int height) { // SurfaceHolder surfaceHolder, int i, int i1, int i2
//Ball.WIDTH = width;
//Ball.HEIGHT = height;
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
boolean retry = true;
thread.setRunning(false);
while(retry) {
try {
thread.join(); //메인스레드와 통합시켜놓음
retry = false; //스레드 종료
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//-------------------------------------------------------------------------------------
/**
* 스레드 클래스 구현
*/
public class MyThread extends Thread {
private boolean mRun = false;
private SurfaceHolder mSurfaceHolder;
public MyThread(SurfaceHolder surfaceHolder) {
this.mSurfaceHolder = surfaceHolder;
}
@Override
public void run() {
while(mRun) {
Canvas canvas = null;
try {
canvas = mSurfaceHolder.lockCanvas(null);
canvas.drawColor(Color.BLACK);
synchronized (mSurfaceHolder) {
for(Ball ball : basket) {
ball.paint(canvas);
}
}
}finally {
//캔버스가 완료되면
if(canvas != null) {
//캔버스 lock을 푼다 - 메인쪽에서 가져다 카피해서 붙인다.
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
/**
* 스레드 제어할 메서드
* @param b
*/
public void setRunning(boolean b) {
mRun = b;
}
}
}
- Ball.java
package com.example.image3_surfaceview1;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
class Ball {
int x, y, xInc = 1, yInc = 1;
int diameter; //공의 반지름
static int WIDTH = 1080, HEIGHT = 1550; //움직이는 공간의 크기(화면너비)
public Ball(int d) {
this.diameter = d; //반지름
//벽에 닿았는지 체크
x = (int)(Math.random() * (WIDTH - d) + 3);
y = (int)(Math.random() * (HEIGHT - d) + 3);
xInc = (int)(Math.random() * 30 + 1);
yInc = (int)(Math.random() * 30 + 1);
}
public void paint(Canvas g) {
Paint paint = new Paint();
if(x < diameter || x > (WIDTH - diameter)) {
xInc = -xInc;
}
if(y < diameter || y > (HEIGHT - diameter)) {
yInc = -yInc;
}
x += xInc; //~Inc: 움직이는 거리
y += yInc;
paint.setColor(Color.RED);
g.drawCircle(x, y, diameter, paint);
}
}
8. 메뉴 - xml로 만들기
Menu1_OptionMenu1 프로젝트 만들기
xml로 구현 - inflate(메뉴 xml 파일, menu)
※ 메뉴(Menu)
1) 옵션 메뉴
- 주된 메뉴
- 탐색, 이메일작성, 설정 등에 사용 - 앱 전체에 영향을 주는 작업에 배치
* 생성 절차
(1) menu 폴더를 생성
(2) menu.xml 등록 (자바 코드로도 등록 가능)
(3) Java의 onCreateOptionsMenu(Menu menu) 메서드에서
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.myoptionmenu, menu); //XML을 객체화
inflate() : xml 파일을 자바코드에 접근시켜서 실제 객체로 만들어 사용하게 한다.
Java의 onOptionsItemSelected(MenuItem item) 메서드에서
switch() {...} 활용
2) 컨텍스트 메뉴
특정요소 클릭시에 뜬다.
3) 팝업 메뉴
res/drawable 경로에 pineapple.png, redapple.png, strawberry.png, watermelon.png 사진 파일 넣기
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="과일 옵션메뉴"
android:textSize="28sp"/>
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:src="@drawable/pineapple"/>
</LinearLayout>
- res/menu/myoptionmenu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/apple"
android:icon="@android:drawable/btn_star_big_on"
android:title="사과"/>
<item
android:id="@+id/strawberry"
android:icon="@android:drawable/ic_btn_speak_now"
android:title="딸기"/>
<item
android:id="@+id/watermelon"
android:icon="@android:drawable/checkbox_on_background"
android:title="수박"
app:showAsAction="never"/>
</menu>
- MainActivity.java
package com.example.menu1_optionmenu1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
ImageView img;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img =(ImageView)findViewById(R.id.img);
}
/**
* 메뉴등록
* @param menu
* @return
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.myoptionmenu, menu); //XML을 객체화
return true;
}
/**
* 선택했을 때 할 일 등록
* @param item
* @return
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.apple:
img.setImageResource(R.drawable.redapple);
Toast.makeText(this,"사과",Toast.LENGTH_LONG).show();
break;
case R.id.strawberry:
img.setImageResource(R.drawable.strawberry);
Toast.makeText(getApplicationContext(),"딸기",Toast.LENGTH_LONG).show();
break;
case R.id.watermelon:
img.setImageResource(R.drawable.watermelon);
Toast.makeText(getApplicationContext(),"수박",Toast.LENGTH_LONG).show();
break;
}
return true;
}
}
9. 메뉴 - Java로 만들기
Menu2_OptionMenu2 프로젝트 만들기
자바로 메뉴를 등록해서 구현하는 옵션메뉴
res/drawable 경로에 mov01.png, mov02.png, mov03.png, mov04.png, mov05.png, mov06.png 사진 파일 넣기
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="#EEE6A4"
android:text="자바로 만드는 옵션메뉴"
android:textSize="26sp"/>
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@drawable/mov06"/>
</LinearLayout>
- MainActivity.java
package com.example.menu2_optionmenu2;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SubMenu;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
ImageView img;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img = (ImageView) findViewById(R.id.img);
}
/**
* 메뉴등록
* @param menu
* @return
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
//메인메뉴 등록
MenuItem item1 = menu.add(0,1,0,"move1");
item1.setIcon(R.drawable.ic_launcher_background);
MenuItem item2 = menu.add(0,2,0,"move2");
item2.setIcon(R.drawable.ic_launcher_background);
menu.add(0,3,0,"move3").setIcon(R.drawable.ic_launcher_background);
//서브메뉴 추가작성방법 - Menu 객체를 추가한후 작성한다.
Menu sub = menu.addSubMenu("서브영화");
sub.add(1,4,0,"라디오스타").setIcon(R.drawable.ic_launcher_background);
sub.add(2,5,0,"비열한거리").setIcon(R.drawable.ic_launcher_background);
return true;
}
/**
* 선택했을 때 할 일 등록
* @param item
* @return
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case 1:
img.setImageResource(R.drawable.mov01);
Toast.makeText(this,"사과",Toast.LENGTH_LONG).show();
break;
case 2:
img.setImageResource(R.drawable.mov02);
Toast.makeText(getApplicationContext(),"딸기",Toast.LENGTH_LONG).show();
break;
case 3:
img.setImageResource(R.drawable.mov03);
Toast.makeText(getApplicationContext(),"수박",Toast.LENGTH_LONG).show();
break;
case 4:
img.setImageResource(R.drawable.mov04);
Toast.makeText(getApplicationContext(),"수박",Toast.LENGTH_LONG).show();
break;
case 5:
img.setImageResource(R.drawable.mov05);
Toast.makeText(getApplicationContext(),"수박",Toast.LENGTH_LONG).show();
break;
case 6:
img.setImageResource(R.drawable.mov06);
Toast.makeText(getApplicationContext(),"수박",Toast.LENGTH_LONG).show();
break;
}
return true;
}
}
10. 컨텍스트 메뉴
Menu3_ContextMenu1 프로젝트 만들기
※ 컨텍스트 뷰
특정한 항목에 LongClick 이벤트가 발생되었을 때 적용되는 동작을 구현할 때 사용.
옵션메뉴와 차이점은 누가 메뉴를 소유할 것이냐의 차이다.
옵션메뉴는 액티비티가 소유하고 컨텍스트 뷰는 선택한 뷰가 소유.
사용 메서드
1) registerForContextMenu(TextView 객체) : 뷰 객체를 컨테스트 메뉴로 등록
2) onCreateContextMenu() : 메뉴등록
3) onContextItemSelected() : 메뉴 선택시 할 일
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/linearLayout01">
<TextView
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="Only I can change my life. No one can do it for me"
android:textSize="100px"
android:typeface="serif"/>
</LinearLayout>
- MainActivity.java
package com.example.menu3_contextmenu1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.graphics.Color;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView)findViewById(R.id.TextView01);
//컨텍스트 메뉴를 장착할 뷰(위젯)
registerForContextMenu(text);
}
/**
* 메뉴 등록
* @param menu
* @param v
* @param menuInfo
*/
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("컨텍스트 메뉴");
menu.add(0,1,0,"배경색:RED");
menu.add(0,2,0,"배경색:GREEN");
menu.add(0,3,0,"배경색:BLUE");
}
/**
* 메뉴가 선택되었을 때
* @param item
* @return
*/
@Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {//getGroupId(), getOrderId()
case 1:
text.setBackgroundColor(Color.RED);
return true;
case 2:
text.setBackgroundColor(Color.GREEN);
return true;
case 3:
text.setBackgroundColor(Color.BLUE);
return true;
default:
return super.onContextItemSelected(item);
}
}
}
11. 팝업 메뉴
Menu4_PopUpMenu1 프로젝트 만들기
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="150dp"
android:onClick="onClick"
android:text="show popup menu"
android:textSize="30sp"/>
</LinearLayout>
- res/menu/popup.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/search"
android:icon="@android:drawable/ic_menu_search"
android:title="search"/>
<item
android:id="@+id/add"
android:icon="@android:drawable/ic_menu_add"
android:title="add"/>
<item
android:id="@+id/edit"
android:icon="@android:drawable/ic_menu_edit"
android:title="edit">
<!--서브메뉴설정-->
<menu>
<item
android:id="@+id/share"
android:icon="@android:drawable/ic_menu_share"
android:title="share"/>
</menu>
</item>
</menu>
- MainActivity.java
package com.example.menu4_popupmenu1;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.PopupMenu;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View textview) {
//1. 팝업 메뉴 객체 생성
PopupMenu popup = new PopupMenu(this, textview); //특정 뷰를 지정
//2. inflate() 메서드로 xml 메뉴 파일을 객체화시켜 메뉴로 등록한다.
popup.getMenuInflater().inflate(R.menu.popup, popup.getMenu());
//3. 메뉴를 선택했을 때 이벤트리스너 등록
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(getApplicationContext(), "클릭된 팝업 메뉴: "+ item.getTitle(), Toast.LENGTH_SHORT).show();
return true;
}
});
//4. 팝업 보여주기
popup.show();
}
}
12. Dialog - Alert
Menu5_Dialog1_Alert 프로젝트 만들기
자바스크립트의 confirm 같은 것이다.
※ 대화상자
사용자에게 메시지 출력
로그인윈도우, 진행현황을 보여줄 때 주로 사용
현재 액티비티 앞에 보여지는 작은 윈도우다.
이 대화상자가 나오면 메인 엑티비티는 제어권을 잃는다.
종료
1) AlertDialog
구현방법1. AlertDialog.Builder 객체를 생성하고 속성을 지정해서 AlertDialog 객체 생성
구현방법2. 제목설정 : setMessage("제목");
구현방법3. 메뉴버튼을 설정한다.
setPositiveButton() : 완료 >> 구현
setNegativeButton() : 취소 >> 구현
setNeutralButton() : 무시
구현방법4. 보여준다 - show()
2) DatePickerDialog / TimePickgerDialog - 앞에서 학습(예약)
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:layout_gravity="center_horizontal"
android:backgroundTint="#2196F3"
android:text="결제 하시겠습니까?"
android:textSize="20sp"
android:onClick="open"/>
</LinearLayout>
- MainActivity.java
package com.example.menu5_dialog1_alert;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void open(View view) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("결제를 진행하시겠습니까? ");
alertDialogBuilder.setPositiveButton("예", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(getApplicationContext(), "결제가 완료되었습니다.", Toast.LENGTH_SHORT).show();
}
});
alertDialogBuilder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(MainActivity.this,"결제가 취소되었습니다.", Toast.LENGTH_SHORT ).show();
//finish(); //이것을 적용하면 액티비티가 종료된다.
}
});
AlertDialog alertDialog = alertDialogBuilder.create(); //Builder의 create()활용해서 객체생성한다.
alertDialog.show();
}
}
13. Dialog - ListAlert
Menu6_Dialog2_ListAlert 프로젝트 만들기
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/backColor">
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:layout_gravity="center_horizontal"
android:backgroundTint="#2196F3"
android:text="색상을 선택하시겠습니까?"
android:textSize="20sp"
android:onClick="open"/>
</LinearLayout>
- MainActivity.java
package com.example.menu6_dialog2_listalert;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
LinearLayout layout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout = (LinearLayout)findViewById(R.id.backColor);
}
public void open(View view) {
final CharSequence[] items = {"Red", "Green", "Blue"};
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
//제목
alertDialogBuilder.setTitle("색상을 선택하시오 ");
//-------------------------------------------------------------------------------------------------
//리스트 달기
alertDialogBuilder.setSingleChoiceItems(items,-1, new DialogInterface.OnClickListener() {//checkedItem -1은 아직 선택되지 않음
@Override
public void onClick(DialogInterface dialogInterface, int i) {//배열 인덱스 가져옴
if(i == 0) {
layout.setBackgroundColor(Color.RED);
}else if(i == 1) {
layout.setBackgroundColor(Color.GREEN);
}else if(i == 2) {
layout.setBackgroundColor(Color.BLUE);
}
Toast.makeText(getApplicationContext(),items[i], Toast.LENGTH_SHORT).show();
}
});
//-------------------------------------------------------------------------------------------------
alertDialogBuilder.setPositiveButton("선택", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(getApplicationContext(), "색상선택이 되었습니다", Toast.LENGTH_SHORT).show();
}
});
alertDialogBuilder.setNegativeButton("취소", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
layout.setBackgroundColor(Color.WHITE);
Toast.makeText(MainActivity.this,"색상선택이 취소되었습니다..",Toast.LENGTH_SHORT ).show();
//finish(); // 이것을 적용하면 액티비티가 종료된다.
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
14. CustomDialog
Menu7_CustomDialog1_LogIn 프로젝트 만들기
사용자 지정 Dialog
※ 사용자 다이얼로그
사용자가 직접 만든 창
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:backgroundTint="#2196F3"
android:onClick="onClick"
android:text="로그인" >
</Button>
</LinearLayout>
- custom_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="username" >
<requestFocus />
</EditText>
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="password"
android:inputType="textPassword" >
</EditText>
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<Button
android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#00BCD4"
android:layout_marginRight="5dp"
android:text="로그인" >
</Button>
<Button
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#FF5722"
android:text="취소" >
</Button>
</LinearLayout>
</LinearLayout>
- MainActivity.java
package com.example.menu7_customdialog1_login;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Dialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 이벤트 메서드
* @param v
*/
@Override
public void onClick(View v) {
Dialog loginDialog = new Dialog(this);
loginDialog.setContentView(R.layout.custom_dialog);
loginDialog.setTitle("로그인 화면");
Button login = (Button)loginDialog.findViewById(R.id.login);
Button cancel = (Button)loginDialog.findViewById(R.id.cancel);
EditText username = (EditText)loginDialog.findViewById(R.id.username);
EditText password = (EditText)loginDialog.findViewById(R.id.password);
//login 버튼을 눌렀을 때 리스너
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (username.getText().toString().trim().length() > 0 && password.getText().toString().trim().length() > 0) {
Toast.makeText(getApplicationContext(), "로그인 성공", Toast.LENGTH_LONG).show();
loginDialog.dismiss();
}else {
Toast.makeText(getApplicationContext(), "다시 입력하시오",
Toast.LENGTH_LONG).show();
}
}
});
//cancel 버튼을 눌렀을 때 리스너
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loginDialog.dismiss(); //dismiss() : 사용자 다이얼로그 닫기
}
});
//보여주기
loginDialog.show();
}
}
15. Fragment
View1_Fragment 프로젝트 만들기
※ 프래그먼트
액티비티 안의 작은 조각(서브 액티비티)라 한다.
특징1. 자신만의 레이아웃을 가질 수 있다.
특징2. 자신만의 생명주기 콜백 메서드를 가질 수 있다.
특징3. 액티비티가 실행되는 동안에 프래그먼트를 액티비티에 추가하거나 삭제할 수 있다.
특징4. 하나의 프래그먼트는 여러 액티비티에서 공유할 수 있다.
특징5. 생명주기는 호스트 액티비티의 수명주기와 연관된다.
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp">
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#C6C3C3"
android:onClick="setFrag1"
android:text="프래그먼트1"
android:textColor="#000000"/>
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#C6C3C3"
android:onClick="setFrag2"
android:text="프래그먼트2"
android:textColor="#000000"/>
<!--프래그먼트 뷰를 겹쳐놓으려고 FrameLayout으로 설정-->
<FrameLayout
android:id="@+id/fame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#52DAEC"/>
</LinearLayout>
- MainActivity.java
package com.example.view1_fragment;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
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);
}
/**
* 버튼에 따른 이벤트 메서드1
* @param v
*/
public void setFrag1(View v) {
//1. 프래그먼트 매니저 객체를 가져온다 - getSupportFragmentManager()
FragmentManager manager = getSupportFragmentManager();
//2. 프래그먼트 매니저 객체에서 프래그먼트 트랜젝션 객체 가져옴
FragmentTransaction ft = manager.beginTransaction();
Fragment1 f1 = new Fragment1();
//3. 프래그먼트 교체
ft.replace(R.id.fame_container, f1, "첫번째프래그먼트");
//4. 커밋처리
ft.commit();
//ft.commitAllowingStateLoss(); //상태에 대한 손실을 우려해서 즉시 실행하고자 할 때 사용
//ft.commitNow(); //현재 제출하려 하는 트랜젝션만 실행처리, back stack에 추가할 트랜젝션을 사용할 수 없다.
}
/**
* 버튼에 따른 이벤트 메서드2
* @param v
*/
public void setFrag2(View v) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
Fragment2 f2 = new Fragment2();
ft.replace(R.id.fame_container, f2, "두번째프래그먼트");
//ft.commit();
ft.commitAllowingStateLoss();
// ft.commitNow();
}
}
- activity_fragment1.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imgView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/m10_clothes8"
android:background="#6CBDCA87"/>
</FrameLayout>
- Fragment1.java
package com.example.view1_fragment;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import java.io.File;
public class Fragment1 extends androidx.fragment.app.Fragment {
ImageView imageView;
/**
* 프래그먼트가 액티비티와 연결될 경우 호출
* 여기서 액티비티가 전달된다.
* @param context
*/
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
/**
* ★ 프래그먼트를 생성할 때 호출
* 프래그먼트가 일시정지나 중단된 후 재개되었을 때 유지해야할 정보(Bundle savedInstanceState 매개변수)
* 초기화 작업 적용
* @param savedInstanceState
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/**
* ★ 자신의 뷰를 그리기위해 호출
* 레이아웃을 inflate 해서 생성
* @param inflater
* @param container
* @param savedInstanceState
* @return
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_fragment1, container, false);
}
@Override
public void onActivityCreated( Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
/**
* 액티비티가 시작되는 상태에 들어가면서 호출
* 여기서부터 사용자에게 보여진다.
*/
@Override
public void onStart() {
super.onStart();
}
/**
* 사용자와 상호작용을 시작한다.
* onPause() 메서드를 호출하고 다시 재개되면 onResume() 메서드를 호출하게 된다.
*/
@Override
public void onResume() {
super.onResume();
}
/**
* ★ 사용자가 프래그먼트를 떠나면 호출
* 사용자가 다시 오지 않을 수도 있으므로 현재 사용자 세션을 넘어 지속해야 하는 변경사항을 여기서 저장해 놓는다.
*/
@Override
public void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onDetach() {
super.onDetach();
}
}
- activity_fragment2.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_gravity="right|center_vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#2196f3"
android:gravity="center"
android:text="프래그먼트"
android:textSize="30dp"
android:textStyle="bold"
android:textColor="#fff"/>
</FrameLayout>
- Fragment2.java
package com.example.view1_fragment;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment2 extends Fragment {
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_fragment2, container, false);
}
@Override
public void onActivityCreated( Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onDetach() {
super.onDetach();
}
}
16. Fragment2
View2_Fragment2 프로젝트 만들기
프래그먼트는 액티비티 단위로 된다.
res/drawable 경로에 soul.png 사진 파일 넣기
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_horizontal">
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#00BCD4"
android:layout_marginRight="5dp"
android:text="프래그먼트1"
android:onClick="setFrag"/>
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#00BCD4"
android:text="프래그먼트2"
android:onClick="setFrag"/>
</LinearLayout>
<!--프래그먼트 추가할 위젯-->
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_margin="15dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:onClick="moveToSub"
android:text="서브창가기"/>
</LinearLayout>
- MainActivity.java
package com.example.view2_fragment2;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
Sub sub;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sub = new Sub();
}
public void setFrag(View v) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
switch (v.getId()) {
case R.id.btn1:
//Intent : 현재 액티비티 정보 가지고 다음 페이지로 정보 넘겨줌
Intent intent = new Intent(getApplicationContext(), Sub.class); //Intent(this, 이동할 페이지(Java))
ft.replace(R.id.container, new Fragment1(), "myfrag1");
ft.commit();
break;
case R.id.btn2:
ft.replace(R.id.container, new Fragment2(), "myfrag2");
ft.commitAllowingStateLoss();
break;
}
}
//서브창가기 인텐트
public void moveToSub(View v) {
Intent intent = new Intent(this, Sub.class);
startActivity(intent);
}
}
- sub.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="서브창"/>
<Button
android:id="@+id/end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="end"
android:layout_gravity="center"
android:text="종료"/>
</LinearLayout>
- Sub.java
package com.example.view2_fragment2;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
public class Sub extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sub);
}
public void end(View v) {
Intent intent = getIntent();
finish();
}
}
- fragment1.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
android:layout_margin="15dp"
android:background="#ff0000">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="내가만든 조각화면1"/>
</FrameLayout>
- Fragment1.java
package com.example.view2_fragment2;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class Fragment1 extends Fragment {
public Fragment1() {}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
LayoutInflater inflater1 = getLayoutInflater();
View fragment1 = inflater1.inflate(R.layout.fragment1,container,false); //container : activity_main.xml의 FrameLayout을 말한다.
return fragment1;
}
}
- fragment2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:background="#FFEB3B"
android:text="내가만든 조각화면2"
android:textSize="20sp"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="@drawable/soul"
android:scaleType="fitCenter"/>
</LinearLayout>
- Fragment2.java
package com.example.view2_fragment2;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class Fragment2 extends Fragment {
Activity c = getActivity();
Fragment2() {}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment2, container, false);
}
}
- AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.view2_fragment2">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.View2_Fragment2">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--서브창은 등록해야한다.-->
<activity android:name=".Sub" />
</application>
</manifest>
'교육 정리 > 안드로이드 앱 제작(Java)' 카테고리의 다른 글
6일차. 데이터 저장과 관리2, 파일, 서비스, 브로드캐스트, 프로바이더, 맵 (2) | 2022.11.12 |
---|---|
5일차. 프래그먼트, 어댑터뷰, 리사이클러, 뷰 페이저, 액티비티와 인텐트, 데이터 저장과 관리 (0) | 2022.11.05 |
3일차. 레이아웃 익히기2, 이벤트, 고급 위젯 다루기 (2) | 2022.10.22 |
2일차. 레이아웃 익히기, 고급위젯 다루기 (2) | 2022.10.08 |
1일차. 안드로이드의 개요와 개발환경 설치, 안드로이드 애플리케이션, Java 문법, 기본 위젯 익히기 (0) | 2022.10.01 |
댓글