**대다수의 GUI Programming의 방식
=> 디자인을 위한 파일, 디자인을 동적으로 제어하는 파일을 pair로 제공하는 경우가 많음
- 디자인 하는 파일에 직접 코드를 작성할 수 있는 방법과 컴포넌트를 드래그 앤 드랍 배치후 조정하는 방식 제공
**LinearLayout
=> View를 수직, 수평 방향으로 배치하는 레이아웃
**RelativeLayout
=> 위젯과 부모와의 위치 또는 위젯끼리의 관계를 이용하여 배치하는 레이아웃
- 첫번째 위젯은 부모와의 관계로 배치하고 두번째 위젯 부터는 다른 위젯과의 관계를 이용하여 배치
- 자바코드에서 사용하지 않는 위젯이라도 다른 위젯과의 관계를 위해서 ID를 설정
=> 레이아웃도 위에서 아래로 읽기 때문에 기준이 되는 위젯을 먼저 생성
<RelativeLayout>
<View android:id="@+id/a"/>
<View android:layout_above="@+id/a"/> //이 View는 a의 위에 생성
</RelativeLayout>
=> layout_로 시작하는 속성으로 배치
- left 대신에 start를 사용할 수 있음 : toLeftOf대신에 toStartOf가 가능
- right 대신에 end를 사용할 수 있음
=> to 대신에 align으로 시작하면 맞춤을 설정
=> alignParent로 시작하면 부모 뷰를 기준으로 맞춤 설정
1. layout 파일 수정
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!--부모뷰의 오른쪽 끝에 배치 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="기준!"
android:textSize="15sp"
android:id="@+id/base"
android:layout_alignParentRight="true"/>
<!--base라는 id를 가진 뷰의 왼쪽에 배치 -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="왼쪽"
android:layout_toLeftOf="@id/base"/>
</RelativeLayout>
**FrameLayout
=> 하위 뷰를 무조건 왼쪽 상단을 기준으로 배치
=> 2개 이상의 하위뷰를 배치하면 겹쳐서 출력
=> 실행중에 addView나 removeView를 이용해서 하위를 추가하거나 삭제 할 수 있음
=> 하위 뷰의 출력속성을 조절해서 보이거나 보이지 않게 할 수 있음
- visibility라는 속성을 이용하고 View 클래스의 상수로 설정
1. FrameLayout으로 이미지 뷰와 버튼을 배치
1) 출력할 이미지를 res/drawable 에 복사
2) 레이아웃 파일을 수정
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".FrameUse">
<!— 이미지 뷰를 화면에 가득차게 배치 —>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/tigers"
android:adjustViewBounds="true"/>
<!— 버튼 추가 —>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="해태 타이거즈"
android:textSize="30sp"/>
</FrameLayout>
**TableLayout
=>테이블을 만들어서 배치하는 레이아웃
=> TableRow 태그를 이용하여 행을 생성하고 그 안에 위젯을 배치
=> 행의 높이는 무조건 wrap_content
=> 너비는 무조건 match_parent
- 하나의 셀에 하나의 view만 배치 가능
- 하나지만 Layout을 배치하면 여러개의 위젯 가능
=> 각셀에 배치되는 위젯의 높이와 너비를 설정하지 않음
**GridLayout
=> 테이블 구조로 뷰를 배치
=> layout_columnSpan이나 layout_rowSpan 속성을 이용해서 여러개의 열, 행을 합쳐 하나의 셀 생성 가능
1. 계산기 모양 : LinearLayout과 GridLayout, TableLayout 사용
<?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=".Calculator"
android:orientation="vertical">
<!-- weight는 비율을 가지고 크기를 결정
gravity는 내용물의 맞춤 -->
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="0"
android:textSize="30dp"
android:gravity="bottom|right"/>
<!--하단의 버튼 영역-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- 숫자 영역을 만들어 줄 레이아웃 -->
<TableLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3">
<TableRow>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:text="7"
android:paddingTop="27dp"
android:paddingBottom="27dp"
/>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:text="8"
android:paddingTop="27dp"
android:paddingBottom="27dp"
/>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:text="9"
android:paddingTop="27dp"
android:paddingBottom="27dp"
/>
</TableRow>
<TableRow>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:text="4"
android:paddingTop="27dp"
android:paddingBottom="27dp"
/>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:text="5"
android:paddingTop="27dp"
android:paddingBottom="27dp"
/>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:text="6"
android:paddingTop="27dp"
android:paddingBottom="27dp"
/>
</TableRow>
<TableRow>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:text="1"
android:paddingTop="27dp"
android:paddingBottom="27dp"
/>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:text="2"
android:paddingTop="27dp"
android:paddingBottom="27dp"
/>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:text="3"
android:paddingTop="27dp"
android:paddingBottom="27dp"
/>
</TableRow>
<TableRow>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:text="."
android:paddingTop="27dp"
android:paddingBottom="27dp"
/>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:text="0"
android:paddingTop="27dp"
android:paddingBottom="27dp"
/>
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:text="-"
android:paddingTop="27dp"
android:paddingBottom="27dp"
/>
</TableRow>
</TableLayout>
<!-- 연산자 버튼을 배치시킬 레이아웃 -->
<GridLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:text="C"
android:paddingTop="18dp"
android:paddingBottom="18dp"/>
<Button
android:text="/"
android:paddingTop="18dp"
android:paddingBottom="18dp"/>
<Button
android:text="*"
android:paddingTop="18dp"
android:paddingBottom="18dp"/>
<Button
android:text="+"
android:paddingTop="21dp"
android:paddingBottom="21dp"/>
<Button
android:text="-"
android:paddingTop="18dp"
android:paddingBottom="18dp"/>
<Button
android:text="="
android:paddingTop="18dp"
android:paddingBottom="18dp"/>
</GridLayout>
</LinearLayout>
</LinearLayout>
**ConstraintLayout
=> RelativeLayout 처럼 다른 위젯과의 관계를 이용해서 배치하는 옵션이 조금더 다양하고 parent의 위치를 기준으로 배치
=> Margin의 옵션이 다양 : 일반 Margin외에 goneMargin으로 뷰가 사라졌을 때의 마진을 별도로 설정
**ScrollView
=> 자식뷰가 부모 뷰보다 큰 경우 그냥 배치시 부모뷰의 영역을 넘어선 부분은 출력되지 않음
- 스크롤이 가능한 뷰를 만들고 그 안에 자식뷰를 추가해야 함
- ScrollView는 하나의 자식 뷰만 가짐(여러가지를 보여주고 싶으면 Layout으로 묶어서 표현)
=> 수직 방향의 스크롤이 가능한 뷰이고 좌우 스크롤이 가능한 View는 HorizontalScrollView
=> ListView, MapView, WebView등은 ScrollView의 하위클래스라서 기본적으로 스크롤이 구현되어 있음
- 이 클래스들은 재사용 가능한 Deque 자료구조를 이용
**LinearLayout과 FrameLayout을 이용해서 버튼을 누르면 화면에 출력되는 내용을 변경
=> View를 변경하여 화면 전환
=> 버튼을 3개 배치하고 3개의 화면을 전환
1. 실행가능한 레이아웃을 추가(OverlappingProject)
2. 레이아웃 수정
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="btn1"/>
<Button
android:id="@+id/btn2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="btn2"/>
<Button
android:id="@+id/btn3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="btn3"/>
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/page1"
android:orientation="horizontal"
android:background="#ff0000">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/page2"
android:orientation="horizontal"
android:background="#00ff00">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/page3"
android:orientation="horizontal"
android:background="#0000ff">
</LinearLayout>
</FrameLayout>
</LinearLayout>
3. Activity.java 파일에 인스턴스 변수 선언
Button btn1, btn2, btn3;
LinearLayout page1, page2, page3;
4. Activity.java 파일의 onCreate메소드에 작성
//뷰 찾아오기
btn1 = (Button)findViewById(R.id.btn1);
btn2 = (Button)findViewById(R.id.btn2);
btn3 = (Button)findViewById(R.id.btn3);
page1 = (LinearLayout)findViewById(R.id.page1);
page2 = (LinearLayout)findViewById(R.id.page2);
page3 = (LinearLayout)findViewById(R.id.page3);
//버튼 이벤트 처리
btn1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
//page1만 출력하고 나머지는 숨기기
page1.setVisibility(View.VISIBLE);
page2.setVisibility(View.INVISIBLE);
page3.setVisibility(View.INVISIBLE);
}
});
//버튼 이벤트 처리
btn2.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
//page1만 출력하고 나머지는 숨기기
page1.setVisibility(View.INVISIBLE);
page2.setVisibility(View.VISIBLE);
page3.setVisibility(View.INVISIBLE);
}
});
//버튼 이벤트 처리
btn3.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
//page1만 출력하고 나머지는 숨기기
page1.setVisibility(View.INVISIBLE);
page2.setVisibility(View.INVISIBLE);
page3.setVisibility(View.VISIBLE);
}
});
**TabHost
=> 탭을 만들기 위한 레이아웃
1. 3개의 구조
- TabHost : 탭 전체 영역
- TabWidget : 탭 버튼 영역
- FrameLayout : 탭 버튼을 눌렀을 때 보여질 영역
2. 생성
=> TabHost를 이용하여 전체 영역을 생성
=> tabHost 영역 안에 LinearLayout을 이용하여 TabWidget영역을 생성하고 FrameLayout을 생성
=> java 코드에서 TabHost.TabSpec을 생성해서 아이콘 모양을 생성하고 출력할 영역을 지정하여 사용
3. 실습 - 3개의 화면을 가진 탭을 설정
<?xml version="1.0" encoding="utf-8"?>
<TabHost
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/host"
tools:context=".TabUse">
<!-- 탭 위젯 영역과 콘텐츠 영역의 위치를 설정 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 탭 위젯 영역 -->
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@android:id/tabcontent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TAB ONE"
android:textSize="30dp"
android:id="@+id/tab1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TAB TWO"
android:textSize="30dp"
android:id="@+id/tab2"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TAB THREE"
android:textSize="30dp"
android:id="@+id/tab3"/>
</FrameLayout>
</LinearLayout>
</TabHost>
**SlidingDrawer
=> 핸들을 터치하면 다른 뷰가 펼쳐지듯 아래에서 위로 출력되는 레이아웃
=> handle 속성에 터치할 핸들을 지정하고 content 속성에 펼쳐질 뷰를 설정
=> SlidingDrawer를 만들면 처음에 핸들만 출력되고 핸들을 누르면 content가 출력되고, 출력상태에서 누르면 content가 사라짐
- 별도의 코드 없이 layout으로 생성
=> 최근에는 이러한 작업을 Dialog를 이용하는 것을 권장
1. 실행가능한 Activity 생성
2. layout 수정
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".SlidingUse">
<SlidingDrawer
android:layout_width="match_parent"
android:layout_height="match_parent"
android:handle="@+id/handle"
android:content="@+id/content">
<ImageView
android:layout_width="88dp"
android:layout_height="44dp"
android:src="@drawable/up"
android:id="@id/handle"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box"
android:id="@id/content"/>
</SlidingDrawer>
</LinearLayout>
**사용자 알림
=> 사용자에게 특수한 상황 발생을 알리는 방법
- 진동
- 소리(시스템 사운드, 사용자 사운드)
- 텍스트(토스트, 스낵바, 대화상자) : 토스트, 스낵바는 시스템 종속적, 대화상자는 애플리케이션 종속
-> 토스트, 스낵바는 애플리케이션이 종료되어도 출력 가능, 대화상자는 애플리케이션과 같이 종료됨
**진동
=> 진동을 사용하려면 퍼미션이 필요
1. 퍼미션 설정시 manifest.xml 파일에서 application 태그 외부에 설정
=> 진동은 <uses-permission android:name="android.permission.VIBRATE"/>
2. 진동설정
1) 1번만 사용
=> Vibrator 변수 = (Vibrator)getSystemService(VIBRATOR_SERVICE);
- 변수.vibrate(진동시간); //시간은 1/1000초 단위
2) 여러번 사용(변수.vibrate(long[], int count);)
=> 첫번째 매개변수는 대기시간과 진동시간의 배열
- 짝수개로 대입되는데 홀수번째가 대기시간, 짝수번째가 진동시간
=> 두번째 매개변수는 진동 횟수
**소리
1. 안드로이드에 내장된 사운드
- Uri 변수 = RingtoneManager.getDefaultUri(RingtoneManage.TYPE_NOTIFICATION);
//NOTIFICATION 대신 ALARM이나 RINGTONE 사용가능
- Ringtone 링톤 = RingtoneManager.getRingtone(getApplicationContext(), 변수);
링톤.play();
=> 안드로이드에서 getApplicationContext()는 시작하는 Activity의 참조를 리턴
모든 Activity에서 저 메소드를 호출하면 시작하는 Activity의 참조를 얻어낼수 있음
2. 사용자 사운드
=> 사운드를 raw 디렉토리에 저장하여 resource로 만듬
- MediaPlayer 미디어플레이어 = MediaPlayer.create(Context context, R.raw.사운드ID);
- 미디어 플레이어.start();
=> Context(=문맥) : 데이터를 저장하고 있는 것을 Context라고 하는데 그림그릴때는 그리기 위한 정보를 저장한 것을 Context라고 함
- 안드로이드에서 화면에 무엇을 출력하고자 하면 반드시 Context정보가 있어야 함
- Activity가 Context를 구현한 클래스
- Context 대신에 Activity를 대입해주면 됨
**사운드 실습
1. 사운드 파일을 저장할 raw디렉토리를 res 디렉토리에 생성
=> 안드로이드에서 기본적인 리소스(이미지, 레이아웃, 색상, 스타일, 문자열, 배열등)를 제외한 이진파일은 raw라는 디렉토리에 배치
2. raw 디렉토리에 효과음으로 사용할 사운드 파일을 복사
=> buttoneffect.wav
3. 진동을 사용하기 위한 권한을 설정
=> manifest.xml 파일에서 application 태그 외부에 작성
<!-- 진동 사용을 위한 권한 설정 -->
<uses-permission android:name="android.permission.VIBRATE"/>
4. 실행가능한 Activity 추가
5. 레이아웃을 수정
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="진동"
android:id="@+id/btnVibrate"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="시스템 사운드"
android:id="@+id/btnSysSound"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="사용 사운드"
android:id="@+id/btnUseSound"/>
</LinearLayout>
6. Activity.java 파일의 onCreate 에 작성
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//버튼 3개 찾아오기
Button btnVibrate = (Button)findViewById(R.id.btnVibrate);
Button btnSysSound = (Button)findViewById(R.id.btnSysSound);
Button btnUseSound = (Button)findViewById(R.id.btnUseSound);
btnVibrate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Vibrator vibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(3000);
}
});
btnSysSound.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Uri s1 = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
//getApplicationContext()는 애플리케이션의 시작 Activity의 참조를 리턴해주는 메소드
Ringtone ringtone = RingtoneManager.getRingtone(getApplicationContext(), s1);
ringtone.play();
}
});
btnUseSound.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MediaPlayer player = MediaPlayer.create(MainActivity.this, R.raw.buttoneffect);
player.start();
}
});
}
}
Tip
1. GUI Programming 공부
=> 정수 계산기 -> 소수 계산기 -> 괄호 계산기
2. 문자열을 정수로 변환하는 알고리즘
String str = "123";
int result = 0;
for(int i=0; i<str.length; i+=1){
char ch = str.charAt(i);
result = result * 10 + (ch-48);
}
'수업 정리' 카테고리의 다른 글
72일차 수업정리(Android - Timer, Animation, LandScope) (0) | 2020.07.17 |
---|---|
71일차 수업정리(Android - Toast, Dialog, EventHandling) (0) | 2020.07.16 |
69일차 수업정리(Lambda, Android Interface) (0) | 2020.07.14 |
68일차 수업 정리(Android 구조 및 화면 출력) (0) | 2020.07.13 |
67일차 수업정리(텍스트 파일보고 다시 정리) (0) | 2020.07.10 |