Transcript Document

Do It! 안드로이드 앱 프로그래밍
둘째 마당 - Chapter 03
다양한 위젯과 이벤트 활용하기
Jun. 2013
이지스퍼블리싱(주) 제공 강의 교안
저자 : 정재곤
이번 장에서는 무엇을 다룰까요?
화면을 좀더 다양하게 만들 수 있는 방법을 알고 싶어요.
• 화면을 손가락으로 눌렀을 때 어떻게 처리하는지 알아볼까요?
• 웹 브라우저를 화면 안에 넣어 볼까요?
• 간단한 애니메이션을 넣는 방법을 알아볼까요?
• 액션바와 탭을 사용하는 방법을 알아볼까요?
• 필요할 때 애니메이션으로 보여지는 슬라이딩 위젯을 알아볼까요?
• 여러 화면을 손가락으로 드래그하여 넘기는 뷰플리퍼를 알아볼까요?
• 프로그레스바와 시크바에 대해 살펴볼까요?
• 입력상자를 터치했을 때 뜨는 키패드 형태를 다르게 만들어 볼까요?
-3-
이번 장에서는 무엇을 다룰까요?
3. 다양한 위젯과 이벤트 활용
-4-
강의 주제 및 목차
강의 주제
다양한 위젯의 사용 방법과 이벤트 처리에 대한 이해
목 차
1
이벤트 처리
2
웹 브라우저사용하기
3
6
프로그레스바와 시크바 사용
하기
7
메뉴와 탭 사용하기
8
키패드 설정하기
간단한 애니메이션 사용하기
4
페이지 슬라이딩 사용하기
5
뷰플리퍼 사용하기
-5-
둘째 마당 – CH3. 다양한 위젯과 이벤트 활용하기
1.
이벤트 처리
뷰의 이벤트 처리하기
▶ 이벤트를 각각의 뷰가 처리하는 방식 : 위임 모델 (Delegation 패턴)
▶ 뷰 객체를 사용할 때는 리스너를 설정하고 뷰를 상속할 때는 이벤트 처리를 위한 메소드를 재정의
뷰를 상속할 때 이벤트 처리를 위한 메소드 재정의
boolean onTouchEvent (MotionEvent event)
boolean onKeyDown (int keyCode, KeyEvent event)
boolean onKeyUp (int keyCode, KeyEvent event)
[버튼에 OnClickListener를 설정할 때의 패턴]
뷰 객체에 전달되는 이벤트를 처리하기 위한 리스너 설정
View.OnTouchListener : boolean onTouch (View v, MotionEvent event)
View.OnKeyListener : boolean onKey (View v, int keyCode, KeyEvent event)
View.OnClickListener : void onClick (View v)
View.OnFocusChangeListener : void onFocusChange (View v, boolean hasFocus)
1. 이벤트 처리
-7-
대표적인 이벤트
•
터치 이벤트
- 화면을 손가락으로 누를 때 발생하는 이벤트
•
키 이벤트
•
제스처 이벤트
•
포커스
•
화면 방향 변경
- 키패드나 하드웨어 버튼을 누를 때 발생하는 이벤트
- 터치 이벤트 중에서 일정 패턴을 만들어 내는 이벤트
- 뷰마다 순서대로 주어지는 포커스
- 화면의 방향이 가로/세로로 바뀜에 따라 발생하는 이벤트
1. 이벤트 처리
-8-
제스처를 통해 처리할 수 있는 이벤트
메소드
onDown()
onShowPress()
onSingleTapUp()
이벤트 유형
- 화면이 눌렸을 경우
- 화면이 눌렸다 떼어지는 경우
- 화면이 한 손가락으로 눌렸다 떼어지는 경우
onSingleTapConfirmed()
- 화면이 한 손가락으로 눌려지는 경우
onDoubleTap()
- 화면이 두 손가락으로 눌려지는 경우
onDoubleTapEvent()
액션을 취하는 경우
onScroll()
- 화면이 눌린 채 일정한 속도화 방향으로 움직였다 떼는 경우
onFling()
- 화면이 눌린 채 가속도를 붙여 손가락을 움직였다 떼는 경우
onLongPress()
1. 이벤트 처리
- 화면이 두 손가락으로 눌려진 상태에서 떼거나 이동하는 등 세부적인
- 화면을 손가락으로 오래 누르는 경우
-9-
대표적인 이벤트 처리 예제
대표적인 이벤트 처리 예제
-손가락으로 화면 터치시의 이벤트 처리
-텍스트뷰의 이벤트를 받아 처리
메인 액티비티의
XML 레이아웃
-간단한 레이아웃 코드 작성
1. 이벤트 처리
메인 액티비티 코드 작성
-이벤트 처리 코드 작성
- 10 -
메인 액티비티 코드 만들기
public boolean onTouchEvent(MotionEvent event) {
if (mGestures != null) {
return mGestures.onTouchEvent(event);
} else {
1 터치 이벤트를 제스처와
구분하여 처리
return super.onTouchEvent(event);
}
}
…
public void onCreate(Bundle savedInstanceState) {
…
2 GestureDetector
객체 정의
mGestures = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
…
Continued..
1. 이벤트 처리
- 11 -
메인 액티비티 코드 만들기 (계속)
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
TextView01.append("\nonFling \n\tx = " + velocityX + "\n\ty=“ + velocityY);
3 Fling 이벤트 처리
return super.onFling(e1, e2, velocityX, velocityY);
}
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
TextView01.append("\nonScroll \n\tx = " + distanceX + "\n\ty = “ + distanceY);
return super.onScroll(e1, e2, distanceX, distanceY);
}
4 Scroll 이벤트 처리
});
Continued..
1. 이벤트 처리
- 12 -
메인 액티비티 코드 만들기 (계속)
TextView01.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
TextView01.append("\nonLongClick: " + v.toString());
return true;
6 LongClick 이벤트
처리
}
});
TextView01.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
TextView01.append("\nonFocusChange, hasFocus : " + hasFocus);
} else {
TextView01.append("\nonFocusChange, hasFocus : " + hasFocus);
}
}
});
}
}
1. 이벤트 처리
- 13 -
7 FocusChange 이벤트
처리
실행 화면
1. 이벤트 처리
- 14 -
키 입력 이벤트 처리하기
[키를 눌렀을 때 전달되는 대표적인 키값]
키 코드
뷰를 상속할 때 키 이벤트 처리를 위한 메소드 재정의
boolean onKeyDown (int keyCode, KeyEvent event)
boolean onKey (View v, int keyCode, KeyEvent event)
1. 이벤트 처리
설명
KEYCODE_DPAD_LEFT
- 왼쪽 화살표
KEYCODE_DPAD_RIGHT
- 오른쪽 화살표
KEYCODE_DPAD_UP
- 위쪽 화살표
KEYCODE_DPAD_DOWN
- 아래쪽 화살표
KEYCODE_DPAD_CENTER
- [중앙] 버튼
KEYCODE_CALL
- [통화] 버튼
KEYCODE_ENDCALL
- [통화 종료] 버튼
KEYCODE_HOME
- [홈] 버튼
KEYCODE_BACK
- [뒤로 가기] 버튼
KEYCODE_VOLUME_UP
- [소리 크기 증가] 버튼
KEYCODE_VOLUME_DOWN
- [소리 크기 감소] 버튼
KEYCODE_0 ~ KEYCODE_9
- 숫자 0부터 9까지의 키값
KEYCODE_A ~ KEYCODE_Z
- 알파벳 A부터 Z까지의 키값
- 15 -
BACK 버튼과 포커스 이벤트 처리 예제
BACK 버튼과 포커스 예제
-BACK 버튼을 눌렀을 때의 이벤트 처리
-입력상자가 포커스를 받았을 때의 이벤트 처리
메인 액티비티의
코드 수정
-BACK 버튼 이벤트 처리하도록 수정
포커스 처리 XML로 정의
EditText의 속성 설정
-포커스 처리를 위한 XML 정의
-입력상자의 속성으로 설정
1. 이벤트 처리
- 16 -
BACK 버튼 처리를 위한 액티비티 코드 만들기
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK) {
close();
1 하드웨어 [BACK] 버튼이
눌렸을 경우 새로 정의한
close() 메소드 호출
return true;
}
return false;
}
private void close() {
Intent resultIntent = new Intent();
resultIntent.putExtra("name", "mike");
setResult(1, resultIntent);
finish();
}
3
2
호출한 액티비티로
결과값 전송
액티비티 없애기
}
1. 이벤트 처리
- 17 -
포커스 이벤트 처리를 위한 XML 레이아웃
<EditText
android:id="@+id/edit01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
1
android:hint="텍스트를 입력하세요."
android:textSize="20dp"
android:background="@drawable/button_selector"
/>
<Button
android:id="@+id/btnShow"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:text="보여주기"
android:textSize="20dp"
android:textStyle="bold"
/>
</LinearLayout>
1. 이벤트 처리
- 18 -
입력 상자 정의
포커스 처리를 위한 XML 정의
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_focused="true"
android:state_pressed="true"
android:drawable="@drawable/red"
/>
<item
android:state_focused="false"
android:state_pressed="true"
android:drawable="@drawable/green"
/>
<item
android:drawable="@drawable/blue"
/>
</selector>
1. 이벤트 처리
- 19 -
단말 방향전환 이벤트 처리 예제
단말 방향전환 이벤트 예제
-단말 방향이 가로와 세로로 바뀌었을 때 이벤트 처리
매니페스트 속성 추가
메인 액티비티 코드 작성
-매니페스트의 액티비티 속성
-가로와 세로 방향으로 바뀌었을
추가
때 처리 코드 작성
1. 이벤트 처리
- 20 -
매니페스트 파일에 속성 추가
......중략
<activity android:name=".MainActivity"
android:label="@string/title_activity_main"
방향 전환을 알 수 있도록
1
android:configChanges="orientation|screenSize"
configChanges 속성 설정
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
......중략
1. 이벤트 처리
- 21 -
메인 액티비티 코드 만들기
…
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(getApplicationContext(), "Orientation : ORIENTATION_LANDSCAPE",
Toast.LENGTH_LONG).show();
4
가로 방향 전환 시 처리
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
Toast.makeText(getApplicationContext(), "Orientation : ORIENTATION_PORTRAIT",
Toast.LENGTH_LONG).show();
5
}
}
…
1. 이벤트 처리
- 22 -
세로 방향 전환 시 처리
액티비티를 가로 또는 세로 방향으로 고정
[Code]
<activity
android:name=".MainActivity"
android:theme="@android:style/Theme.NoTitleBar"
android:screenOrientation="landscape"
android:configChanges="orientation"
>
</activity>
1. 이벤트 처리
- 23 -
둘째 마당 – CH3. 다양한 위젯과 이벤트 활용하기
2.
웹 브라우저 사용하기
웹브라우저 사용하기
<WebView
…
/>
<uses-permission android:name="android.permission.INTERNET" />
• 웹브라우저는 안드로이드에서 미리 제공하는 웹킷(WebKit) 엔진을 사용
• 플래시(Flash)도 지원할 수 있는 브라우저가 장착되어 있으므로 모바일 단말에서
대부분의 웹페이지를 PC에서 보는 것처럼 볼 수 있음
 향후에는 HTML5 표준 태그들을 이용한 기능이 지속적으로 추가될 것임
• 웹브라우저를 애플리케이션 안에 넣고 싶은 경우에는 웹뷰(WebView)를 사용하면
되는데 XML 레이아웃에서는 <WebView> 태그로 정의함
2. 웹 브라우저 사용하기
- 25 -
웹브라우저 포함하기 예제
웹브라우저 포함하기 예제
-웹뷰 위젯을 이용한 화면 구성
-이벤트 처리 추가
메인 액티비티의
XML 레이아웃 정의
웹페이지와 자바스크립트
코드 작성
-메인 액티비티를 위한 레이아
-보여줄 웹 페이지 작성
웃 정의
-자바스크립트 액션 정의
메인 액티비티 코드 작성
-웹뷰 설정과 이벤트 처리
2. 웹 브라우저 사용하기
- 26 -
메인 액티비티 코드 만들기
webView = (WebView) findViewById(R.id.webview);
…
1
웹뷰 객체 참조
2
웹뷰에
WebSettings 설정
WebSettings webSettings = webView.getSettings();
webSettings.setSavePassword(false);
webSettings.setSaveFormData(false);
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportZoom(false);
webView.setWebChromeClient(new WebBrowserClient());
3 웹뷰에 클라이언트
객체 지정
webView.addJavascriptInterface(new JavaScriptMethods(), "sample");
4
webView.loadUrl("file:///android_asset/sample.html");
웹뷰에 자바스크립트
인터페이스 객체 지정
Continued..
2. 웹 브라우저 사용하기
- 27 -
메인 액티비티 코드 만들기 (계속)
loadBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
6 사용자가 직접 입력한
일반 웹페이지 로딩
webView.loadUrl(urlInput.getText().toString());
}
});
}
final class JavaScriptMethods {
JavaScriptMethods() {
}
7 애플리케이션에서 정의한 메소드로
웹페이지에서 호출할 대상
public void clickOnFace() {
mHandler.post(new Runnable() {
public void run() {
loadBtn.setText("클릭후열기");
8 애플리케이션 화면의
버튼 글자 변경
Continued..
2. 웹 브라우저 사용하기
- 28 -
메인 액티비티 코드 만들기 (계속)
webView.loadUrl("javascript:changeFace()");
10
}
웹페이지의 자바스크립트
함수 호출
});
…
final class WebBrowserClient extends WebChromeClient {
public boolean onJsAlert(WebView view, String url, String message,
JsResult result) {
11
result.confirm();
return true;
}
}
}
2. 웹 브라우저 사용하기
- 29 -
웹브라우저 클라이언트
클래스 정의
자바스크립트 함수 정의
<html>
<script language="javascript">
1 자바스크립트 함수 정의한
것으로 애플리케이션에서
호출할 대상
function changeFace() {
document.getElementById("face").src="face_angry.png";
}
</script>
<body>
<a onClick="window.sample.clickOnFace()">
2
<div style="width:120px;
margin:0px auto;
padding:10px;
text-align:center;
border:2px solid #202020;"
>
<img id="face" src="face_normal.png"/>
<br>
</div>
3 웹페이지의 이미지 ID를
“face"로 지정
</a>
</body>
</html>
2. 웹 브라우저 사용하기
- 30 -
웹페이지에서 보이는 그림을
눌렀을 때 clickOnFace()
메소드 호출
실행 화면
2. 웹 브라우저 사용하기
- 31 -
둘째 마당 – CH3. 다양한 위젯과 이벤트 활용하기
3.
간단한 애니메이션 사용하기
애니메이션 사용 방식
▶ 전형적인 애니메이션 사용 방식은 애니메이션 액션 정보를 XML로 정의한 후 사용
▶ Animation 객체로 만든 후 뷰의 startAnimation() 메소드를 사용하면 간단하게 애니메이션 동작
자바 소스
리소스
/res/anim
startAnimation( )
View
객체
3. 간단한 애니메이션 사용하기
loadAnimation( )
Animation
객체
- 33 -
flow.xml
간단한 애니메이션 예제
간단한 애니메이션 예제
-텍스트뷰가 들어가는 화면 구성
-텍스트뷰 이동 애니메이션 적용
메인 액티비티의
XML 레이아웃 정의
-메인 액티비티를 위한 레이아
애니메이션 액션
XML 정의
-애니메이션을 XML로 정의
웃 정의
메인 액티비티 코드 작성
-애니메이션 처리
3. 간단한 애니메이션 사용하기
- 34 -
애니메이션 액션 XML 정의
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="100%p"
1
위치 이동을 위한
애니메이션 액션 정의
2
투명도 변경을 위한
애니메이션 액션 정의
android:toXDelta="0%p"
android:duration="6000"
android:repeatCount="3"
/>
<alpha
android:fromAlpha="0.5"
android:toAlpha="1"
android:duration="6000"
android:repeatCount="3"
/>
</set>
3. 간단한 애니메이션 사용하기
- 35 -
메인 액티비티 코드 만들기
package org.androidtown.ui.anim;
...
public class MainActivity extends Activity {
Animation flowAnim;
1 애니메이션 객체 선언
TextView text01;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
flowAnim = AnimationUtils.loadAnimation(this, R.anim.flow);
text01 = (TextView) findViewById(R.id.text01);
2 XML에 정의한 애니메이션
액션 정보 로딩
Button startBtn = (Button) findViewById(R.id.startBtn);
startBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Continued..
3. 간단한 애니메이션 사용하기
- 36 -
메인 액티비티 코드 만들기 (계속)
flowAnim.setAnimationListener(new FlowAnimationListener());
text01.startAnimation(flowAnim);
3 애니메이션 리스너
설정
텍스트뷰 객체의
애니메이션 시작
4
}
});
}
private final class FlowAnimationListener implements Animation.AnimationListener {
public void onAnimationEnd(Animation animation) {
Toast.makeText(getApplicationContext(), "애니메이션 종료됨.", Toast.LENGTH>LONG).show();
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
}
}
}
3. 간단한 애니메이션 사용하기
- 37 -
5
애니메이션 종료 시
토스트 메시지 표시
실행 화면
3. 간단한 애니메이션 사용하기
- 38 -
둘째 마당 – CH3. 다양한 위젯과 이벤트 활용하기
4.
페이지 슬라이딩 사용하기
페이지 슬라이딩
▶ 뷰의 중첩과 애니메이션을 접목한 방식
▶ 하나의 뷰 위에 다른 뷰를 올라가 있을 때 보이거나 보이지 않는 과정을 애니메이션으로 적용
아래쪽 뷰
아래쪽 뷰
위쪽 뷰
열기
위쪽 뷰
닫기
Animation 객체 적용
왼쪽 방향으로 Translate
4. 페이지 슬라이딩 사용하기
- 40 -
Animation 객체 적용
오른쪽 방향으로 Translate
페이지 슬라이딩 사용하기
페이지 슬라이딩 사용하기
예제
-페이지 슬라이딩을 이용해 뷰 보여주기
메인 액티비티의
XML 레이아웃 정의
-메인 액티비티 레이아웃 정의
4. 페이지 슬라이딩 사용하기
메인 액티비티 코드 작성
-슬라이딩 기능 넣기
- 41 -
레이아웃 만들기
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff5555ff">
1 첫 번째 레이아웃 :
바탕 레이아웃
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Base Area"
android:textColor="#ffffffff"
/>
</LinearLayout>
Continued..
4. 페이지 슬라이딩 사용하기
- 42 -
레이아웃 만들기 (계속)
<LinearLayout
android:id="@+id/slidingPage01"
android:orientation="vertical"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:background="#ffffff66"
2
android:visibility="gone">
두 번째 레이아웃 :
슬라이딩으로 보일 레이아웃
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Area #1"
android:textColor="#ff000000"
/>
Continued..
4. 페이지 슬라이딩 사용하기
- 43 -
레이아웃 만들기 (계속)
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Area #2"
android:textColor="#ff000000"
/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:background="#00000000">
3
<Button
android:id="@+id/openBtn01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Open"
/>
</LinearLayout>
</FrameLayout>
4. 페이지 슬라이딩 사용하기
- 44 -
세 번째 레이아웃 :
버튼이 들어 있는 레이아웃
메인 액티비티 코드 만들기
package org.androidtown.ui.sliding;
...
public class MainActivity extends Activity {
boolean isPageOpen = false;
1 슬라이딩 페이지가
보이는지 여부
Animation translateLeftAnim;
2
Animation translateRightAnim;
3
왼쪽으로 이동
애니메이션 객체
오른쪽으로 이동
애니메이션 객체
LinearLayout slidingPage01;
Button openBtn01;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
slidingPage01 = (LinearLayout) findViewById(R.id.slidingPage01);
4 슬라이딩으로 보여줄
페이지와 애니메이션
객체 참조
translateLeftAnim = AnimationUtils.loadAnimation(this, R.anim.translate_left);
translateRightAnim = AnimationUtils.loadAnimation(this, R.anim.translate_right);
Continued..
4. 페이지 슬라이딩 사용하기
- 45 -
메인 액티비티 코드 만들기 (계속)
SlidingPageAnimationListener animListener = new SlidingPageAnimationListener();
translateLeftAnim.setAnimationListener(animListener);
5 슬라이딩 애니메이션을
감시할 리스너
translateRightAnim.setAnimationListener(animListener);
openBtn01 = (Button) findViewById(R.id.openBtn01);
openBtn01.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (isPageOpen) {
6 페이지가 열려 있으면
오른쪽으로 애니메이션
slidingPage01.startAnimation(translateRightAnim);
} else {
7
slidingPage01.setVisibility(View.VISIBLE);
slidingPage01.startAnimation(translateLeftAnim);
페이지가 닫혀 있으면
보이도록 한 후 왼쪽으로
애니메이션
}
}
});
}
Continued..
4. 페이지 슬라이딩 사용하기
- 46 -
메인 액티비티 코드 만들기 (계속)
private class SlidingPageAnimationListener implements AnimationListener {
public void onAnimationEnd(Animation animation) {
if (isPageOpen) {
slidingPage01.setVisibility(View.INVISIBLE);
8 페이지가 열려 있으면
안보이도록 하고
버튼의 텍스트를
“Open"으로 변경
openBtn01.setText("Open");
isPageOpen = false;
} else {
9 페이지가 닫혀 있으면
버튼의 텍스트를
“Close"로 변경
openBtn01.setText("Close");
isPageOpen = true;
}
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
}
}
}
4. 페이지 슬라이딩 사용하기
- 47 -
실행 화면
4. 페이지 슬라이딩 사용하기
- 48 -
둘째 마당 – CH3. 다양한 위젯과 이벤트 활용하기
5.
뷰플리퍼 사용하기
뷰플리퍼 사용하기
• 하나의 화면에서 여러 개의 뷰가 전환되며 보이는 대표적인 위젯임
• ViewFlipper라는 클래스를 별도로 만들어 제공한다는 점에서 훨씬 더 많이 사용하는 방식임
• 뷰플리퍼와 같은 형태로 구현한 대표적인 화면이 바로 애플리케이션 런처 화면임
[삼성 갤럭시 단말에서 뷰플리퍼 방식의 화면 전환]
5. 뷰플리퍼 사용하기
- 50 -
뷰플리퍼 사용하기 예제
뷰플리퍼 사용하기
예제
-뷰플리퍼를 이용해 뷰 보여주기
메인 액티비티의
XML 레이아웃 정의
-메인 액티비티 레이아웃 정의
새로운 클래스 정의
-뷰플리퍼 기능을 위한 새로운
클래스 정의
메인 액티비티 코드 작성
-뷰플리퍼 사용 코드 넣기
5. 뷰플리퍼 사용하기
- 51 -
레이아웃 만들기
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
1
android:id="@+id/buttonLayout"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</LinearLayout>
<ViewFlipper
android:id="@+id/flipper"
android:layout_width="match_parent"
2
뷰플리퍼 정의
android:layout_height="match_parent"
>
</ViewFlipper>
</LinearLayout>
5. 뷰플리퍼 사용하기
- 52 -
현재 페이지를 표시할
상단의 버튼들이 들어갈
레이아웃
뷰플리퍼 화면을 위한 클래스 정의
public class ScreenViewFlipper extends LinearLayout implements OnTouchListener {
…
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
1 뷰플리퍼 화면을 위한
레이아웃 인플레이션
inflater.inflate(R.layout.screenview, this, true);
buttonLayout = (LinearLayout) findViewById(R.id.buttonLayout);
flipper = (ViewFlipper) findViewById(R.id.flipper);
flipper.setOnTouchListener(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
2 뷰플리퍼 객체에 터치
이벤트 리스너 설정
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
params.leftMargin = 50;
3 상단의 버튼들 객체 생성
indexButtons = new ImageView[countIndexes];
Continued..
5. 뷰플리퍼 사용하기
- 53 -
뷰플리퍼 화면을 위한 클래스 정의 (계속)
views = new TextView[countIndexes];
for(int i = 0; i < countIndexes; i++) {
indexButtons[i] = new ImageView(context);
if (i == currentIndex) {
indexButtons[i].setImageResource(R.drawable.green);
} else {
indexButtons[i].setImageResource(R.drawable.white);
}
4 각 화면의 텍스트뷰들
객체 생성
indexButtons[i].setPadding(10, 10, 10, 10);
buttonLayout.addView(indexButtons[i], params);
TextView curView = new TextView(context);
curView.setText("View #" + i);
curView.setTextColor(Color.RED);
curView.setTextSize(32);
views[i] = curView;
Continued..
5. 뷰플리퍼 사용하기
- 54 -
뷰플리퍼 화면을 위한 클래스 정의 (계속)
flipper.addView(views[i]);
5 플리퍼에 뷰 추가
}
}
private void updateIndexes() {
for(int i = 0; i < countIndexes; i++) {
if (i == currentIndex) {
indexButtons[i].setImageResource(R.drawable.green);
} else {
indexButtons[i].setImageResource(R.drawable.white);
}
}
}
public boolean onTouch(View v, MotionEvent event) {
if(v != flipper) return false;
if(event.getAction() == MotionEvent.ACTION_DOWN) {
downX = event.getX();
} else if(event.getAction() == MotionEvent.ACTION_UP){
upX = event.getX();
if( upX < downX ) {
5. 뷰플리퍼 사용하기
Continued..
- 55 -
뷰플리퍼 화면을 위한 클래스 정의 (계속)
flipper.setInAnimation(AnimationUtils.loadAnimation(getContext(),
R.anim.wallpaper_open_enter));
flipper.setOutAnimation(AnimationUtils.loadAnimation(getContext(),
6 뷰플리퍼에 애니메이션
설정
R.anim.wallpaper_open_exit));
if (currentIndex < (countIndexes-1)) {
flipper.showNext();
currentIndex++;
7 다음 화면을 보기 위한
showNext() 메소드 호출
updateIndexes();
}
} else if (upX > downX){
flipper.setInAnimation(AnimationUtils.loadAnimation(getContext(),
R.anim.push_right_in));
flipper.setOutAnimation(AnimationUtils.loadAnimation(getContext(),
R.anim.push_right_out));
if (currentIndex > 0) {
Continued..
5. 뷰플리퍼 사용하기
- 56 -
뷰플리퍼 화면을 위한 클래스 정의 (계속)
flipper.showPrevious();
8 이전 화면을 보기 위한
showPrevious() 메소드
호출
currentIndex--;
updateIndexes();
}
}
}
return true;
}
}
5. 뷰플리퍼 사용하기
- 57 -
메인 액티비티 만들기
...
public class MainActivity extends Activity {
ScreenViewFlipper flipper;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.match_parent,
ViewGroup.LayoutParams.match_parent);
flipper = new ScreenViewFlipper(this);
setContentView(flipper, params);
}
}
5. 뷰플리퍼 사용하기
- 58 -
실행 화면
[뷰플리퍼로 전환되는 화면의 인덱스를 상단의 버튼으로 표시하는 경우]
5. 뷰플리퍼 사용하기
- 59 -
둘째 마당 – CH3. 다양한 위젯과 이벤트 활용하기
6.
프로그레스바와 시크바 사용하기
프로그레스바 사용하기
• 여러 가지 화면을 구성하고 그 안에 다양한 위젯을 사용하는데 있어서 대화상자처럼
중간 중간 상태 정보를 보여주는 가장 좋은 방법 중 하나임
• 막대 모양
- 작업의 진행 정도를 알려줄 수 있도록 막대 모양으로 표시함
- style 속성의 값을 “?android:attr/progressBarStyleHorizontal"로 설정함
• 원 모양
- 작업이 진행 중임을 알려줌
- 원 모양으로 된 프로그레스바가 반복적으로 표시됨
6. 프로그레스바와 시크바 사용하기
- 61 -
프로그레스바 사용 메소드
• 진행률이 변경되면 progress 속성으로
[Code]
설정되었던 값을 바꾸면 되는데, 자바 코드
void setProgress (int progress)
상에서 프로그레스바의 현재값을 바꾸는
void incrementProgressBy (int diff)
대표적인 메소드들은 다음과 같음
[Code]
requestWindowFeature(Window.FEATURE_PROGRESS);
6. 프로그레스바와 시크바 사용하기
- 62 -
프로그레스바 사용하기 예제
프로그레스바 사용하기
예제
-프로그레스바로 진행상태 보여주기
메인 액티비티의
XML 레이아웃 정의
-메인 액티비티 레이아웃 정의
6. 프로그레스바와 시크바 사용하기
메인 액티비티 코드 작성
-프로그레스바 사용 코드 넣기
- 63 -
레이아웃 만들기
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:id="@+id/progressBar01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminateOnly="false"
android:minHeight="20dp"
android:maxHeight="20dp"
android:max="100"
/>
6. 프로그레스바와 시크바 사용하기
- 64 -
1
프로그레스바 정의
메인 액티비티 만들기
public static final int PROGRESS_DIALOG = 1001;
ProgressDialog progressDialog;
프로그레스 대화상자 객체 선언
1
…
public void onCreate(Bundle savedInstanceState) {
…
ProgressBar proBar = (ProgressBar) findViewById(R.id.progressBar01);
proBar.setIndeterminate(false);
proBar.setMax(100);
proBar.setProgress(80);
2
btnShow.setOnClickListener(new OnClickListener() {
프로그레스바 객체 참조 후
최대값과 현재값 설정
public void onClick(View v) {
showDialog(PROGRESS_DIALOG);
}
});
6. 프로그레스바와 시크바 사용하기
Continued..
- 65 -
메인 액티비티 만들기 (계속)
btnClose.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (progressDialog != null) {
progressDialog.dismiss();
3
프로그레스 대화상자 없애기
}
}
});
}
public Dialog onCreateDialog(int id) {
4
대화상자 생성 시 호출되는 메소드
switch (id) {
case (PROGRESS_DIALOG):
progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setMessage("데이터를 확인하는 중입니다.");
return progressDialog;
}
return null;
}
}
6. 프로그레스바와 시크바 사용하기
- 66 -
5
프로그레스 대화상자 객체 생성
실행 화면
6. 프로그레스바와 시크바 사용하기
- 67 -
시크바 사용하기
• 시크바(SeekBar)는 프로그레스바를 확장하여 만들어진 것임
• 프로그레스바의 속성을 가지고 있으면서도 사용자가 값을 조정할 수 있도록 해 줌
[Code]
void onStartTrackingTouch (SeekBar seekBar)
void onStopTrackingTouch (SeekBar seekBar)
void onProgressChanged (SeekBar seekBar, int progress,
boolean fromUser)
6. 프로그레스바와 시크바 사용하기
- 68 -
시크바 사용하기 예제
시크바 사용하기
예제
-시크바로 화면밝기 조절 기능 구현
메인 액티비티의
XML 레이아웃 정의
-메인 액티비티 레이아웃 정의
6. 프로그레스바와 시크바 사용하기
메인 액티비티 코드 작성
-시크바 사용 코드 넣기
- 69 -
레이아웃 만들기
<LinearLayout
android:id="@+id/panel01"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
1
시크바가 들어 있는 레이아웃
android:padding="10dp"
android:gravity="center_horizontal"
android:visibility="gone"
>
<SeekBar
android:id="@+id/seekbar01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
2
android:progress="100"
android:max="100"
/>
6. 프로그레스바와 시크바 사용하기
- 70 -
시크바 정의
메인 액티비티 만들기
public class MainActivity extends Activity {
private View panel;
private SeekBar seekbar;
private TextView text01;
private int brightness = 50;
1
시크바 객체
2
기본 밝기값
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
panel = findViewById(R.id.panel01);
text01 = (TextView) findViewById(R.id.text01);
seekbar = (SeekBar) findViewById(R.id.seekbar01);
Button showBtn = (Button) findViewById(R.id.showBtn);
showBtn.setOnClickListener(new View.OnClickListener() {
3
public void onClick(View v) {
시크바 보이기 메소드 호출
showPanel();
}
});
6. 프로그레스바와 시크바 사용하기
Continued..
- 71 -
메인 액티비티 만들기 (계속)
seekbar.setOnSeekBarChangeListener(new MyOnSeekBarChangeListener());
4
시크바에 리스너 설정
}
private void showPanel() {
Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate_left);
seekbar.setProgress(this.brightness);
panel.setVisibility(View.VISIBLE);
panel.startAnimation(animation);
5
레이아웃에 애니메이션 설정
}
private void setBrightness(int value) {
if (value < 10) {
value = 10;
} else if (value > 100) {
6
화면 밝기 설정 메소드
value = 100;
}
brightness = value;
Continued..
6. 프로그레스바와 시크바 사용하기
- 72 -
메인 액티비티 만들기 (계속)
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = (float) value / 100;
7
getWindow().setAttributes(params);
윈도우 매니저를 이용해
밝기 설정
}
private void hidePanel() {
Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate_right);
panel.startAnimation(animation);
8
panel.setVisibility(View.GONE);
패널 감추기
}
class MyOnSeekBarChangeListener implements OnSeekBarChangeListener {
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
setBrightness(progress);
Continued..
6. 프로그레스바와 시크바 사용하기
- 73 -
메인 액티비티 만들기 (계속)
text01.setText("밝기 수준 : " + progress);
9
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
hidePanel();
}
}
}
6. 프로그레스바와 시크바 사용하기
- 74 -
텍스트에 표시
실행 화면
6. 프로그레스바와 시크바 사용하기
- 75 -
둘째 마당 – CH3. 다양한 위젯과 이벤트 활용하기
7.
메뉴와 탭 사용하기
안드로이드의 메뉴
• [메뉴] 버튼은 안드로이드가 아이폰과 다른 특징을 보여주는 것 중의 하나
• [메뉴] 버튼을 누르면 숨어있던 메뉴가 보이게 되는데 이 메뉴를 애플리케이션에서 구현할 때는
옵션 메뉴(Option Menu)라고 부름
• 옵션 메뉴를 비롯해 안드로이드에서 제공하는 메뉴는 크게 두 가지임
옵션 메뉴
- 하드웨어 [메뉴] 버튼을 눌렀을 때 나타나는 메뉴로 각각의 화면마다 설정된 주요 메뉴임
- 옵션 메뉴는 최대 6개까지의 메뉴 아이템을 포함할 수 있으며,
그 이상의 메뉴 아이템을 추가하면 "More"라는 메뉴 아이템으로 표시됨
컨텍스트 메뉴
- 화면을 길게 누르면 나타나는 메뉴로 텍스트뷰의 편집 상태를 바꾸거나 할 때 사용하는 메뉴임
- 뷰에 설정하여 나타나게 할 수 있음
7. 메뉴와 탭 사용하기
- 77 -
옵션 메뉴와 액션바를 이용한 메뉴
• 동일한 옵션 메뉴가 안드로이드 버전에 따라 다른 형태로 보이게 됨
• 최근 버전에서는 옵션 메뉴가 상단의 액션바로 통합되어 있음
• 액션바를 이용해 다양한 메뉴 기능을 사용할 수 있음
7. 메뉴와 탭 사용하기
- 78 -
메뉴 사용 방식의 기본
• onCreateOptionsMenu()와 onCreateContextMenu() 메소드 재정의
• 메뉴 선택 시의 이벤트 처리
 컨텍스트 메뉴의 아이템 선택 : onContextItemSelected() 호출
 onOptionsItemSelected() 메소드와 onContextItemSelected() 메소드는 모두
applyMenuChoice() 메소드로 위임되어 상위 클래스로 전달됨
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return (applyMenuChoice(item) || super.onOptionsItemSelected(item));
}
@Override
public boolean onContextItemSelected(MenuItem item) {
return (applyMenuChoice(item) || super.onContextItemSelected(item));
}
[Reference]
void Activity.registerForContextMenu (View view)
7. 메뉴와 탭 사용하기
- 79 -
메뉴 추가하기 예제
메뉴 추가하기 예제
-로그인 화면에 메뉴 추가하기
-메뉴 이벤트 처리하기
메인 액티비티 코드 작성
메인 액티비티 코드 작성
-메인 액티비티 코드에서 메뉴
-메인 액티비티 코드에서 메뉴
추가
이벤트 처리 코드 추가
7. 메뉴와 탭 사용하기
- 80 -
메인 액티비티 코드 만들기
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
1 옵션 메뉴가 만들어질 때
자동 호출되는 메소드
addOptionMenuItems(menu);
return true;
}
private void addOptionMenuItems(Menu menu) {
2 옵션 메뉴에 메뉴 아이템
추가
int base = Menu.FIRST;
MenuItem item01 = menu.add(base, base, Menu.NONE,"Settings");
MenuItem item02 = menu.add(base, base+1, Menu.NONE,"About");
item01.setIcon(R.drawable.settings_icon);
item02.setIcon(R.drawable.about_icon);
}
Continued..
7. 메뉴와 탭 사용하기
- 81 -
메인 액티비티 코드 만들기 (계속)
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == 1) {
4 옵션 메뉴를 눌렀을 때의
이벤트 처리
Intent intent = new Intent(getBaseContext(), SettingsActivity.class);
startActivityForResult(intent, REQUEST_CODE_SETTINGS);
5 설정 화면 띄우기
} else if (item.getItemId() == 2) {
Intent intent = new Intent(getBaseContext(), AboutDialog.class);
startActivityForResult(intent, REQUEST_CODE_ABOUT);
}
return true;
}
}
7. 메뉴와 탭 사용하기
- 82 -
6 정보 화면 띄우기
실행 화면
7. 메뉴와 탭 사용하기
- 83 -
액션바 첫번째 예제
액션바 첫번째 예제
-액션바에 메뉴 추가하기
- 이벤트 처리하기
메인 액티비티 코드 작성
- 메인 액티비티 코드에서
액션바 추가
7. 메뉴와 탭 사용하기
- 84 -
메인 액티비티 코드 만들기
...
abar = getActionBar();
액션바 참조
1
...
Button button01 = (Button) findViewById(R.id.button01);
button01.setOnClickListener(new OnClickListener()
public void onClick(View v)
2
디스플레이 옵션 설정
abar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME|
ActionBar.DISPLAY_USE_LOGO|
ActionBar.DISPLAY_HOME_AS_UP);
);
Continued..
7. 메뉴와 탭 사용하기
- 85 -
액션바에 검색 기능 넣기 예제
액션바 첫번째 예제
-액션바에 메뉴 추가하기
- 이벤트 처리하기
XML 작성
- XML 레이아웃 작성
- 메뉴 XML 설정
7. 메뉴와 탭 사용하기
메인 액티비티 코드 작성
- 메인 액티비티 코드에서
액션바 추가
- 86 -
레이아웃 만들기
<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="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/text01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="검색 :"
android:textSize="16dp"
android:textColor="#ffad8745" />
<EditText
android:id="@+id/edit01"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:inputType="text"
android:imeActionId="1337"
android:imeOptions="actionDone"
/>
</LinearLayout>
7. 메뉴와 탭 사용하기
Continued..
- 87 -
메뉴 설정하기
<item android:id="@+id/menu_search"
android:title="@string/menu_search"
android:icon="@drawable/menu_search"
android:orderInCategory="102"
android:showAsAction="always|withText"
android:actionLayout="@layout/search_layout" />
7. 메뉴와 탭 사용하기
Continued..
- 88 -
메인 액티비티 코드 만들기
...
public boolean onCreateOptionsMenu(Menu menu)
getMenuInflater().inflate(R.menu.activity_main, menu);
View v = menu.findItem(R.id.menu_search).getActionView();
edit01 = (EditText) v.findViewById(R.id.edit01);
if (edit01 != null)
edit01.setOnEditorActionListener(onSearchListener);
return true;
...
Continued..
7. 메뉴와 탭 사용하기
- 89 -
액션바를 탭과 함께 보여주기 예제
액션바 세번째 예제
- 액션바에 탭 추가하기
- 프래그먼트 만들기
메인 액티비티 코드 작성
- 메인 액티비티 코드에서
액션바에 탭 기능 추가
프래그먼트 작성
- 프래그먼트 XML 레이아웃
작성
- 프래그먼트 코드 작성
7. 메뉴와 탭 사용하기
- 90 -
메인 액티비티에서 액션바 코드 만들기
...
ActionBar abar = getActionBar();
abar.setNavigationMode( ActionBar.NAVIGATION_MODE_TABS );
Tab tab01 = abar.newTab();
tab01.setText("상품 #1");
tab01.setTabListener(new ProductTabListener(this, Fragment01.class.getName()));
abar.addTab(tab01);
...
7. 메뉴와 탭 사용하기
Continued..
- 91 -
프래그먼트 코드 작성
public class Fragment01 extends Fragment
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState )
return inflater.inflate( R.layout.frag01, container, false );
Continued..
- 92 -
프래그먼트 XML 작성
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/text01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
android:text="제품 내용 01"
... />
</RelativeLayout>
7. 메뉴와 탭 사용하기
- 93 -
둘째 마당 – CH3. 다양한 위젯과 이벤트 활용하기
8.
키패드 설정하기
하드웨어 키보드와 소프트 키보드
•
IMF(Input Method Framework) – 입력 도구 프레임워크
- 기본 개념 : 현재 사용자가 선택한 입력 방법과 애플리케이션 간의 상호작용을 IMF가 조절
- 프레임워크의 기본 목적 : 안드로이드가 다양한 하드웨어 단말과 소프트웨어에 사용되면서
사용자 애플리케이션에 필요한 좀 더 좋은 입력 기술 제공
- 적용 예
• 실제 키보드와 버추얼 키보드
• 음성 인식
• 필기 인식
• 등등…
8. 키패드 설정하기
- 95 -
키패드 설정하기
• 키패드와 관련된 기능은 InputMethodManager 객체를 이용해 사용 가능함
• 이 객체는 시스템 서비스이므로 getSystemService() 메소드를 이용해 참조한 후 다음과 같은 메소드를
이용해 키패드를 열거나 닫을 수 있음
boolean showSoftInput(View view, int flags)
boolean hideSoftInputFromWindow(IBinder windowToken, int flags [,
ResultReceiver resultReceiver ])
8. 키패드 설정하기
- 96 -
입력될 데이터의 타입 지정
• 텍스트뷰에 입력되는 데이터의 타입 지정 방법
- XML과 자바 코드에서 아래와 같은 속성과 메소드 사용 가능
android:inputType=“...”
editTextBox.setRawInputType(int)
• 아래는 첫글자가 대문자 입력으로 되도록 설정한 예
<EditText
android:id="@+id/editTextBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10px"
android:textSize="18sp"
android:inputType="text|textCapWords" />
8. 키패드 설정하기
- 97 -
숫자/패스워드/이메일로 입력 설정
android:inputType="number|numberSigned|numberDecimal"
1. 키보드는 숫자만 입력할 수 있도록 설정됨
2. 일반적으로 다른 숫자 이외의 키들은 보이긴 하지만
사용할 수 없음
3. 사용 가능한 키만 입력됨
4. number|numberSigned 는 숫자만 입력됨
5. numberDecimal 는 실수만 입력됨
• 패스워드로 입력 설정
android:inputType=“textPassword"
• 이메일로 입력 설정
android:inputType=“textEmailAddress"
8. 키패드 설정하기
- 98 -
대표적인 inputType 속성값
inputType 속성값
number
설명
- 숫자
numberSigned
- 0보다 큰 숫자
numberDecimal
- 정수
text
textPassword
textEmailAddress
phone
- 텍스트
- 패스워드로 표시
- 이메일로 표시
- 전화번호로 표시
time
- 시간
date
- 날짜
8. 키패드 설정하기
[inputType을 textPassword, number, textEmailAddress로 지정한 경우]
- 99 -
참고 문헌
[ References]
• 기본 서적
2013, 정재곤, “Do it! 안드로이드 앱 프로그래밍(개정판)”, 이지스퍼블리싱(주)
• Android Website
http://www.android.com/
• Google Developer’s Conference
http://code.google.com/events/io/
• Android SDK Documentation
References
- 100 -