** Action Bar
** 이미지 뷰 위에 ActionBar를 출력하고 ActionBar에 Image를 출력하고 텍스트를 변경
1. Android Application 생성
2. imag.png, icon.png를 drawable 디렉토리에 복사
3. 레이아웃 디자인
4. ActionBar에 적용할 style 생성 - res/values/styles.xml
5. AndroidManifest.xml 파일에 MainActivity를 등록하는 옵션을 수정
6. MainActivity.java 파일의 onCreate 메소드에 ActionBar를 동적으로 변경하는 코드를 작성
** Menu
1. 안드로이드에서의 메뉴
2. Context Menu
3. Popup Menu
** Custom View
1. 목적
2. 하는 방법
3. Custom View에 그리기
4. Custom View를 Activity에 출력하기
5. Custom View를 Activity에 출력하고 그림 그리기
6. CustomView의 이벤트 처리
** Bitmap
1. Image 출력하는 메소드
2. Matrix를 이용해서 크기나 위치 및 각도를 조절해서 출력할 수 있다.
3. Sprite Image
** Intent
1. 다른 Activity를 호출할 때
2. Intent의 종류
3. Intent의 Constructor
4. 기본적인 화면 전환
5. 스마트 폰 Application의 화면 관리
6. RootActivity와 SubActivity 사이의 화면 전환
7. 데이터 공유
8. startActivityResult(Intent intent, int requestCode)
9. Web Programming에서의 데이터 공유
10. 이전 프로젝트의 각 화면에 EditText를 추가해서 EditText에 입력한 내용을 다음 화면이나 이전 화면에 전송해서 TextView에 출력
** Action Bar
- API Level 11에서 추가된 상단의 TitleBar
- 기본적으로는 타이틀로 설정한 문자열이 출력되지만 App Icon이나 View Control, Action Button, Overflow Menu 등을 출력하는 것이 가능하다.
- 테마 설정을 이용해서 보이지 않도록 설정하는 것이 가능하다.
- ActionBar를 보이게 하고 보이지 않도록 하기
Activity에서 getSupportActionBar()를 호출해서 ActionBar 객체를 얻어내고 show나 hide 메소드를 호출해서 동적으로 보여주고 숨기는 것이 가능하다.
- 테마 설정에서 windowActionBarOverlay를 이용하면 액션 바를 투명하게 만들어서 ContentView에 떠 있도록 하는 것이 가능하다.
- ActionBar에 보여지는 문자열을 설정
AndroidManifest.xml 파일의 Activity 등록하는 태그에서 android:label="문자열"을 추가하면 Activity마다 보여지는 문자열을 별도로 설정 가능하다.
** 이미지 뷰 위에 ActionBar를 출력하고 ActionBar에 Image를 출력하고 텍스트를 변경
1. Android Application 생성
2. img.png, icon.png를 drawable 디렉토리에 복사
3. 레이아웃 디자인
<?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"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/img"/>
</LinearLayout>
4. ActionBar에 적용할 style 생성 - res/values/styles.xml
<style name="MainTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#00000000</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="windowActionBarOverlay">true</item>
</style>
5. AndoridManifest.xml 파일에 MainActivity를 등록하는 옵션을 수정
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android0731">
<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/AppTheme">
<activity
android:name=".MainActivity"
android:label="액션바와 메뉴 및 커스텀 뷰"
android:theme="@style/MainTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
6. MainActivity.java 파일의 onCreate 메소드에 ActionBar를 동적으로 변경하는 코드를 작성
//액션 바를 가져오기
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setIcon(R.drawable.icon);
- 애플리케이션을 구현한 후에 각 Activity에 맞게 구성을 다시 하는 것을 권장한다.
** Menu
- PC용 애플리케이션에서 상단에 배치해서 사용자의 명령을 받아들이는 인터페이스
1. 안드로이드에서의 메뉴
1) Option Menu
- 안드로이드 기기 하단의 메뉴 버튼을 누르면 보이던 것이었는데 지금은 상단으로 이동했다.
- 이 메뉴는 최대 6개 까지 항목을 가질 수 있고, 6개가 넘는 경우 6번째 메뉴가 More가 되고 More를 눌러야 나머지 메뉴를 출력한다.
- 이미지를 출력할 수 있지만 체크 박스나 라디오 버튼은 배치 못한다.
- Activity에 boolean onCreateOptionsMenu(Menu menu) 메소드를 재정의해서 menu에 항목들을 add해서 배치
- 이전에는 Activity를 만들면 위의 메소드가 구현된 상태였는데 최근의 AndroidStudio에서는 Activity를 만들어도 위의 메소드가 구현되어 있지 않다.
이전 기기들에는 기기 하단의 오른쪽에 메뉴 버튼이 있었지만 지금은 없다.
메뉴의 이름을 설정할 수 없기 때문에 화면에서 메뉴에 어떤 항목이 있는지 알지 못하기 떄문에 메뉴에 대한 설명을 해주어야 해서 모바일에서는 메뉴를 잘 사용하지 않는다.
2. Context Menu
- View를 길게 누르면 보여지는 메뉴
- iOS는 이 메뉴에 이벤트 설정이 가능한데 안드로이드는 LongClick으로만 사용
3. Popup Menu
- 특정 이벤트가 발생했을 때 보여지는 메뉴
** Custom View
- 사용자 정의 뷰라고 하는데 직접 View Class를 만드는 것
1. 목적
- Drawing을 하기 위해서 : 그리기를 하기 위한 것
- 제공되는 뷰 클래스의 모양을 변경하기 위해서
2. 하는 방법
- 필요한 View 클래스를 extends해서 구현한다.
- 제공되는 클래스를 상속받아서 필요한 기능을 구현하는 것을 subclassing이라고 한다.
- Custom View를 만드는 경우 대부분 Activity 안에 내부 클래스로 만드는 경우가 많다.
하나의 Activity 안에서만 사용될 가능성이 높고 명칭 충돌 발생 가능성을 배제하기 위해서이다.
Java에서는 GUI 이벤트 처리를 위한 클래스나 인터페이스를 별도의 클래스나 인터페이스로 제공한다.
이름들은 대부분 Camel 표기법을 사용하고 클래스 이름에 기능을 명시하는 경우가 많기 때문에 이름 충돌이 많이 발생한다.
Andorid에서의 이벤트 처리 인터페이스나 클래스들을 내부 인터페이스나 클래스로 만들었다.
3. Custom View에 그리기
- Canvas를 이용해서 그린다.
다른 프로그래밍에서는 대부분 Context라고 한다.
안드로이드에서는 Context라는 클래스가 존재하기 때문에 Canvas라고 이름붙인 것이다.
1) Canvas(Context)
- 화면에 그림을 그리기 위해서는 여러가지 정보가 필요하다.
선 색상, 면 색상, 선 두께 등이 필요하다.
그림을 그릴 때마다 위의 정보를 매번 설정하게 되며 그림을 그리는 코드가 너무 복잡해지게 된다.
기본적인 그리기 정보를 어떤 객체에 저장해두고 그림을 그리는 메소드를 호출하면 그 정보를 이용해서 그리도록 한다.
이러한 그리기 정보를 가지고 있는 객체를 일반적으로 Context라고 한다.
2) 기존 View 클래스를 상속받아서 그리는 이유
- GUI 프로그래밍에서는 Canvas를 직접 생성하는 것을 허용하지 않기 때문이다.
- View 클래스 안의 onDraw 메소드의 매개변수로 전달된다.
onDraw 메소드는 View가 화면에 그리기 직전에 호출되서 View를 화면에 그려주는 메소드이다.
View가 처음 보여질 때 그리고 가려졌다가 다시 나타날 때 호출되는 메소드이다.
3) Canvas 클래스의 그리는 메소드
void drawPoint(floast x, float y, Paint paint)
void drawLine(floast cx, float cy, float stopX, float stopY, Paint paint)
void drawRect(floast cx, float cy, float right, float bottom, Paint paint)
void drawCircle(floast cx, float cy, float radius, Paint paint)
void drawText(String text, float cx, float cy, Paint paint)
4. Custom View를 Activity에 출력하기
- 전체 화면으로 만들고자 하는 경우는 setContentView(View view)를 호출하고 현재 화면 위에 출력하고자 하는 경우는 addContenView(View view)
5. Custom View를 Activity에 출력하고 그림 그리기
1) 실행 가능한 Activity 추가 - CustomViewActivity
2) Activity 클래스 안에 View 클래스를 상속받는 클래스를 생성
class MyView extends View {
//기본 생성자가 없으므로 생성자를 만들어서 상위 클래스의 생성자를 호출
public MyView(Context context) {
super(context);
}
//View가 화면에 표시될 때 호출되는 메소드
@Override
protected void onDraw(Canvas canvas) {
//그리기 정보를 저장할 객체를 생성
Paint paint = new Paint();
paint.setColor(Color.BLUE);
canvas.drawColor(Color.TRANSPARENT);
canvas.drawCircle(100, 100, 100, paint);
}
}
3) Activity의 onCreate 메소드에서 앞에서 만든 뷰를 화면에 출력하는 코드를 작성
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_custom_view);
//새로운 뷰를 현재 화면에 추가
setContentView(R.layout.activity_custom_view);
addContentView(new MyView(this), new LinearLayout.LayoutParams(500, 500));
}
6. CustomView의 이벤트 처리
- View 클래스이므로 Touch 이벤트를 처리할 수 있는 onTouch 메소드를 소유하고 있고 View의 터치 이벤트나 클릭 이벤트를 사용할 수 있다.
- 터치를 처리하는 메소드
public boolean onTouchEvent(MotionEvent event)
return타입이 boolean인 경우는 기본적으로 제공되는 기능의 수행 여부를 리턴한다.
event는 터치 처리를 위한 부가 정보가 전달된다.
getAction에는 MotionEvent의 상수로 터피의 동작 상태를 리턴해준다.
좌표는 getX(), getY()로 리턴한다.
- 터치를 이용해서 선을 그리고자 할 때는 터치가 시작되는 시점의 좌표를 출발점으로 하고 움직임이 있을 때마다 그 좌표를 기억해서 좌표까지 선을 그려주면 된다.
펜의 움직임도 터치로 감지한다.
1) Activity 클래스에 터치 정보를 저장할 class를 생성
- x, y 좌표 그리고 그릴 것인지 여부를 저장할 변수 생성
class Vertex{
//점의 좌표를 저장
float x;
float y;
//그리기 여부를 저장
boolean isDraw;
//3개의 매개변수를 받아서 초기화하는 생성자
public Vertex(float x, float y, boolean isDraw){
this.x = x;
this.y = y;
this.isDraw = isDraw;
}
}
2) Activity 클래스에 터치 정보를 저장할 변수를 선언
//터치 정보를 저장할 List 변수 선언
ArrayList<Vertex> arVertex;
3) MyView 클래스를 수정
//View 클래스로부터 상속받는 CustomView
class MyView extends View {
Paint paint;
//기본 생성자가 없으므로 생성자를 만들어서 상위 클래스의 생성자를 호출
public MyView(Context context) {
super(context);
//paint를 생성
paint = new Paint();
//색상 설정과 선 두께 설정
paint.setColor(Color.BLACK);
paint.setStrokeWidth(3);
paint.setAntiAlias(true);
}
//View가 화면에 표시될 때 호출되는 메소드
@Override
protected void onDraw(Canvas canvas) {
//arVertex의 내용을 가지고 선을 그리기
for(int i = 0; i < arVertex.size(); i = i + 1){
//isDraw가 true인 경우 이전 점에서부터 현재 점까지 그리기
if(arVertex.get(i).isDraw == true){
canvas.drawLine(
arVertex.get(i-1).x, arVertex.get(i-1).y,
arVertex.get(i).x, arVertex.get(i).y, paint);
}
}
/*
//그리기 정보를 저장할 객체를 생성
Paint paint = new Paint();
paint.setColor(Color.BLUE);
canvas.drawColor(Color.WHITE);
canvas.drawCircle(100, 100, 100, paint);
*/
}
//터치 이벤트 처리를 위한 메소드
@Override
public boolean onTouchEvent(MotionEvent event){
//터치가 처음 시작되는 경우에는 선을 그릴 필요는 없고 좌표만 저장
if(event.getAction() == MotionEvent.ACTION_DOWN){
arVertex.add(new Vertex(event.getX(), event.getY(), false));
return true;
}
//터치가 움직일 때 onDraw를 호출해서 현재위치까지 선을 그림
if(event.getAction() == MotionEvent.ACTION_MOVE){
arVertex.add(new Vertex(event.getX(), event.getY(), true));
//전체 화면을 전부 삭제하고 다시 그려달라고 요청
invalidate();
return true;
}
//기본적으로 제공되는 기능을 사용하지 않는다.
return false;
}
}
4) Activity.java의 onCreate 메소드 수정
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_custom_view);
//새로운 뷰를 현재 화면에 추가
setContentView(new MyView(this));
arVertex = new ArrayList<>();
}
** Bitmap
- Bitmap은 2가지 의미로 사용되는데 하나는 윈도우즈 그림판의 기본 확장자인 bmp를 의미하는 경우가 있고,
프로그래밍에서는 그림 파일의 내용을 메모리에 저장한 것을 bitmap이라고 한다.
- 이미지를 출력할 때 ImageView를 이용하게 되면 이미지의 확대 축소가 가능하지만 해상도에 문제가 발생할 수 있다.
- Bitmap의 내용을 조작해서 이미지를 확대나 축소해서 출력할 수 있다.
1. Image 출력하는 메소드
Canvas.drawBitmap(Bitmap bitmap, x좌표, y좌표, null) : 좌표에 원본 크기 그대로 출력
Canvas.drawBitmap(Bitmap bitmap, Rect rect, null) : 확대나 축소해서 출력
Canvas.drawBitmap(Bitmap bitmap, Rect rect, Rect rect, null) : 원본 이미지에서 첫 번째 크기만큼자라서 두 번째 크기만큼 출력 출력
2. Matrix를 이용해서 크기나 위치 및 각도를 조절해서 출력할 수 있다.
3. Sprite Image
- 이미지 파일은 기본적으로 보조기억장치에 저장된 상태인데 이 이미지를 호출해서 화면에 그릴 때 보조기억장치에서 불러와서 그려야 하기 때문에 그리는 속도가 느려질 수 있다.
- 위의 작업을 해결하는 방법에는 리소스에 저장해서 사용하는 방법이 있고 하나의 이미지에 여러 개의 이미지를 그리고 잘라서 출력하는 방법이 있다.
- 게임같은 경우 이미지가 너무 많기 때문에 리소스에 저장하는 방법을 사용할 수 없다.
1) 이미지 파일을 Drawable 디렉토리에 복사
2) 실행 가능한 Activity 추가 - SpriteActivity
3) SpringActivity.java 파일에 커스텀 뷰 클래스 생성해서 이미지 출력
class MyView extends View {
public MyView(Context context){
super(context);
}
public void onDraw(Canvas canvas){
Paint paint = new Paint();
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img);
//bitmap에서 앞의 Rect만큼 가져와서 뒤의 Rect 만큼으로 그리기
canvas.drawBitmap(bitmap,
new Rect(0, 0, 350, 350),
new Rect(0, 0, 700, 700), paint);
}
}
4) SpriteActivity.java 파일의 onCreate 메소드 수정
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_sprite);
setContentView(new MyView(this), new LinearLayout.LayoutParams(350, 350));
}
** Intent
- 컴포넌트를 실행하기 위해 시스템에 넘기는 정보
- 컴포넌트 : 화면 출력을 위한 Activity, 백 그아운드 작업을 위한 Service, 데이터 공유를 위한 Content Provider, 알림을 위한 Broadcast Receiver
- 개발자가 작성은 했는데 개발자가 작성하는 자바 코드를 이용해서 결합하지 않고 수명 주기를 관리하는 프레임워크나 라이브러리가 결합하는 것 - IoC(Inversion of Control : 제어의 역전, 제어의 역흐름)
안드로이드에서는 Component라고 하고 Spring에서는 bean이라고 한다.
- 제어의 역전이 적용되면 코드가 직접 결합하지 않기 때문에 모듈 간의 결합도가 약해져서 모듈의 의존성이 낮아진다.
1. 다른 Activity를 호출할 때
startActivitty(Intent intent)
2. Intent의 종류
1) Explicit Intent(명시적 Intent)
- 호출할 대상의 클래스 이름을 명시
- 동일한 애플리케이션에 존재하는 컴포넌트를 이용할 때 사용
2) Implicit Intent(암시적 인텐트)
- 호출할 대상을 직접 명시하지 않는 인텐트
- 클래스 이름 대신에 별명을 사용하는 인텐트
- 다른 애플리케이션의 컴포넌트를 이용할 때 사용
- 안드로이드는 다른 애플리케이션을 실행하는 것 뿐 아니라 다른 애플리케이션의 자원을 공유할 수도 있다.
3. Intent의 Constructor
- Intent() : 매개변수가 없는 생성자 - Default Constructor
- Intent(Intent intent) : 다른 Intent를 매개변수로 받아서 생성 - 복사 생성자
복사 생성자를 이용하는 이유는 Clone을 위해서 이다.
- Intent(String action[, Uri uri]) : 기본 제공되는 애플리케이션의 Activity를 호출할 때 사용하는 생성자
- Intent(Context context, Class <?> cls) : 두 번째 제공되는 컴포넌트 클래스를 이용해서 명시적 인텐트를 만드는 생성자이다. - 가장 많이 사용된다.
- Intent(String action, Uri uri, Context context, Class <?> cls) : 기본 제공되는 애플리케이션의 Activity에 직접 생성한 Activity를 추가해서 생성한다.
4. 기본적인 화면 전환
1) 하나의 Activity에서 다른 Activity를 호출할 때 메소드
Intent intent = new Intent(자신의 Activity 참조, 다른 Activity.class);
startActivity(intent);
2) 현재 Activity 종료하는 메소드
finish();
5. 스마트 폰 Application의 화면 관리
- Stack(LIFO - Last In First Out 구조 : 마지막에 삽입한 데이터가 첫 번째에 위치하는 자료구조)을 이용해서 관리한다.
- 이전 화면으로 돌아갈 때는 이전 화면을 새로 출력하지 않고 보통 자신을 제거한다.
- Main에서 Sub를 출력할 때는 Sub를 생성해서 출력하지만 Sub에서 Main으로 돌아갈 때는 Main이 생성되는 것이 아니고 다시 출력되는 것이다.
- onCreate : 생성될 때 호출되는 메소드
onResume : 다시 활성화될 때 호출되는 메소드
6. RootActivity와 SubActivity 사이의 화면 전환
1) 실행 가능한 Activity를 추가 : RootActivity
2) 화면 디자인 : TextView 1개, Button 1개
<?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=".RootActivity"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RootActivity"
android:id="@+id/lblroot"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="하위 액티비티 호출"
android:id="@+id/subcall"/>
</LinearLayout>
3) 일반 Activity를 추가 : SubActivity(실행 가능하지 않은 Activity)
4) SubActivity 화면 디자인 : TextView 1개, Button 1개
<?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=".SubActivity"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="하위 액티비티"
android:id="@+id/lblsub"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="뒤로"
android:id="@+id/rootcall"/>
</LinearLayout>
5) RootActivity에서 Button을 누르면 SubActivity를 출력하도록 작성
package com.example.android0731;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class RootActivity extends AppCompatActivity {
Button subcall;
TextView lblroot;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_root);
lblroot = (TextView)findViewById(R.id.lblroot);
subcall = (Button)findViewById(R.id.subcall);
subcall.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View view) {
//SubActivity를 이용한 Intent를 생성
Intent intent = new Intent(RootActivity.this, SubActivity.class);
//Activity 호출
startActivity(intent);
}
});
}
}
6) SubActivity에서 Button을 누르면 RootActivity를 출력하도록 작성
- 인스턴스 변수 선언 및 onCreate 메소드에 버튼 클릭 이벤트 작성
package com.example.android0731;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.w3c.dom.Text;
public class SubActivity extends AppCompatActivity {
TextView lblsub;
Button maincall;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sub);
lblsub = (TextView)findViewById(R.id.lblsub);
maincall = (Button)findViewById(R.id.rootcall);
maincall.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View view) {
//자신의 Activity 종료
finish();
}
});
}
}
7. 데이터 공유
- 관계형 데이터베이스에서 테이블 간의 데이터 공유는 Foreign Key 이용
- 동일한 클래스로 부터 만들어진 인스턴스 간의 데이터 공유는 static 변수를 이용한다.
- 서로 다른 클래스로부터 만들어진 인스턴스 간의 데이터 공유는 하나의 인스턴스 안에서 다른 인스턴스를 생성한다면 생성자를 이용한 주입이나 setter 메소드를 이용한 주입을 한다.
- 전혀 관계없는 인스턴스 간에 데이터를 공유하고자 하면 공유 변수 영역을 만들어야 합니다.
public class를 만들어서 static 변수를 만들어도 되고 singleton 패턴의 클래스를 만들고 인스턴스 변수를 만들어도 된다.
- 안드로이드는 위의 방법 중 공유 변수 영역을 만드는 것만 가능
안드로이드의 Component는 인스턴스를 직접 생성하지 않기 때문에 생성자를 이용하는 방법이나 setter를 이용하는 방법은 안된다.
- 객체 지향 언어에서는 공유 영역을 만드는 것을 금기시 한다.
- 안드로이드에서는 Intent에 데이터 저장 영역을 추가해 주었다.
데이터 저장 영역을 용어로 표현할 때는 Bundle이라고 한다.
Intent에는 Bundle 자료형으로 Extras가 존재한다.
Bundle은 Map처럼 사용한다.
저장할 때는 putExtra(String name, 데이터)
- 저장할 수 있는 데이터는 Serializable 인터페이스를 implements한 객체만 가능하다.
기본형, String, Date, 자료구조 클래스들은 모두 Serializable 인터페이스가 구현되어 있고 개발자가 만드는 데이터 클래스(DTO-VO)를 전송하고자 할 때는 Serializable 인터페이스를 implements 해야 한다.
- 데이터를 읽어낼 때는 getIntent라는 메소드로 자신을 호출한 Intent를 찾아오고,
get자료형Extra(String name)을 호출하면 된다.
없는 자료형인 경우는 getSerializableExtra를 호출하고 강제 형 변환을 해서 사용한다.
- Map의 Key와 Value는 모든 자료형이 가능하지만 Key에는 String만 사용
8. startActivityResult(Intent intent, int requestCode)
- Intent를 화면에 출력하는 메소드
requestCode는 호출하는 Intent를 구분하기 위한 식별값
- 호출당한 Intent에서 resultCode를 만들 수 있다.
setResult(int resultCode Intent intent)를 호출하면 intent에서 호출된 경우 결과값으로 resultCode를 리턴한다.
- 호출하는 Activity에서는 추가된 Activity가 제거될 때 아래 메소드가 호출된다.
void onActivityResult(int requestCode, int resultCode, Intent intent)
2개의 코드를 이용해서 자신이 호출한 Intent를 알 수 있고 그 때 intent의 Extra를 꺼내서 데이터를 확인할 수 있다.
Main -> Sub 데이터 전송은 쉽다.
Sub -> Main 데이터 전송은 위의 것보다 어렵다.
9. Web Programming에서의 데이터 공유
- request 객체 : forwarding할 때의 데이터 공유
- session 객체 : 하나의 브라우저 안에서의 데이터 공유
- application 객체 : 전체 애플리케이션 내에서의 데이터 공유
10. 이전 프로젝트의 각 화면에 EditText를 추가해서 EditText에 입력한 내용을 다음 화면이나 이전 화면에 전송해서 TextView에 출력
- 보조 입력을 받는 경우 보조 화면에 입력한 내용을 메인화면으로 전송해 주어야 한다.
1) RootActivity.xml의 레이아웃에 EditText 추가
<?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=".RootActivity"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RootActivity"
android:id="@+id/lblroot"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/inputroot"
android:hint="서브에게 넘기는 데이터"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="하위 액티비티 호출"
android:id="@+id/subcall"/>
</LinearLayout>
2) SubActivity의 레이아웃에 EditText를 추가
<?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=".SubActivity"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="하위 액티비티"
android:id="@+id/lblsub"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/inputsub"
android:text="메인에게 넘기는 데이터"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="뒤로"
android:id="@+id/rootcall"/>
</LinearLayout>
3) RootActivity에서 SubActivity에게 데이터를 넘겨서 출력하기
- RootActivity의 onCreate 메소드에 작성
package com.example.android0731;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class RootActivity extends AppCompatActivity {
Button subcall;
TextView lblroot;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_root);
lblroot = (TextView)findViewById(R.id.lblroot);
subcall = (Button)findViewById(R.id.subcall);
final EditText inputroot = (EditText)findViewById(R.id.inputroot);
//이벤ㅌ 핸들러에서 사용하기 위해 final을 추가한 것이다.
subcall.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View view) {
//입력한 내용을 가져오기
String content = inputroot.getText().toString();
//SubActivity를 이용한 Intent를 생성
Intent intent = new Intent(RootActivity.this, SubActivity.class);
//하위 Activity에게 전송할 데이터를 생성
intent.putExtra("data", content);
//Activity 호출
startActivity(intent);
}
});
}
}
- SubActivity의 onCreate 메소드를 수정해서 전송된 내용을 출력
package com.example.android0731;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.w3c.dom.Text;
public class SubActivity extends AppCompatActivity {
TextView lblsub;
Button maincall;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sub);
lblsub = (TextView)findViewById(R.id.lblsub);
maincall = (Button)findViewById(R.id.rootcall);
//자신을 호출한 Intent를 찾아오기
Intent intent = getIntent();
String data = intent.getStringExtra("data");
//데이터 출력
lblsub.setText(data);
maincall.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View view) {
//자신의 Activity 종료
finish();
}
});
}
}
4) SubActivity에서 RootActivity에게 데이터 넘기기
1) 전역 공유 변수 만들어서 넘기기 - 권장하지 않지만 쉬운 방법
- SubActivity에서 onCreate 메소드 안에 finish 전에 공유 변수 생성
final EditText inputsub = (EditText)findViewById(R.id.inputsub);
maincall.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View view) {
//데이터를 공유 전역 변수 Data에 삽입
ShareData.Data = inputsub.getText().toString();
//자신의 Activity 종료
finish();
}
});
- RootActivity에 onResume을 오버라이딩
@Override
protected void onResume() {
super.onResume();
//공유 전역 변수 Data의 내용을 출력
lblroot.setText(ShareData.Data);
}
2) SubActivity에서 RootActivity에게 데이터 넘기기(Android가 권장하는 방법)
- RootActivity에서 startActivity 호출 구문 작성
//Activity 호출
//startActivity(intent);
//응답을 받기 위해 하위 액티비티를 호출할 때 구분하기 위한 번호와 함께 호출
startActivityForResult(intent, 10);
- SubActivity에서 finish 하기 전에 작성
@Override
public void onClick(View view) {
//데이터를 공유 전역 변수 Data에 삽입
//ShareData.Data = inputsub.getText().toString();
//호출한 곳에 데이터를 전송하기 위한 코드 requestCode는 10 resultcode는 30
Intent intent = new Intent();
intent.putExtra("pass", inputsub.getText().toString());
setResult(30, intent);
//자신의 Activity 종료
finish();
}
- RootActivity 클래스에서 onActivityResult 메소드를 오버라이딩해서 하위 액티비티가 전송한 내용을 출력(onResume은 주석 처리)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if(requestCode == 10 && resultCode == 30){
String pass = intent.getStringExtra("pass");
lblroot.setText(pass);
}
}
'안드로이드&IOS 앱 개발자 양성' 카테고리의 다른 글
안드로이드&iOS 앱 개발자 양성(83일차) (0) | 2020.08.04 |
---|---|
안드로이드&iOS 앱 개발자 양성(82일차) (0) | 2020.08.03 |
안드로이드&iOS 앱 개발자 양성(80일차) (0) | 2020.07.30 |
안드로이드&iOS 앱 개발자 양성(79일차) (0) | 2020.07.29 |
안드로이드 MySQL&Hibernate 연동(76 ~ 78일차) (0) | 2020.07.23 |