Download presentation
Presentation is loading. Please wait.
Published byFarida Hardja Modified 5년 전
1
Ch 4. 선택 위젯의 사용과 커스텀뷰 만들기 Assignment #1 04 – 1, 2) 08학번 정보과학과 유재윤
04 – 3, 4) 09학번 정보과학과 최태환 04 – 5, 6) 07학번 정보과학과 전영훈 04 – 7, 8, 9) 09학번 정보과학과 박문기
2
순서 04_7 복합위젯(View) 04_8 월별 캘린더 04_9 멀티터치 이미지 뷰어
3
복합위젯(View) 두 개 이상의 View를 하나의 View로 통합하여 한 클래스 안에서 이벤트 처리를 일괄적으로 처리할 수 있도록 하는 기능 여러 개의 View를 합친 통합 View를 만들어본다. 이 복합 View의 이벤트를 처리하는 클래스 정의해본다.
4
각각의 위젯(뷰)을 따로 구현하고 이벤트 처리도 각 위젯마다 처리해도 상관없다. -> 불편함
여러 개의 뷰를 하나의 클래스로 정의하여 이벤트 처리를 하나의 클래스에서 처리할 수 있도록 구현해본다. 각각의 위젯을 따로 구현하면서 이벤트 처리도 따로 해줘도 됩니다. 그러나 이렇게 하면 많은 뷰를 사용하는데 나중에는 유지관리하기가 불편합니다. 이를 해소하기 위해서 하나의 xml에 선언해놓은 View들을 하나의 객체로 선언할 수 있도록 처리하여 쓸 수 있도록 합니다. 이렇게 복합위젯으로 구현해놓으면 애플리케이션 구성이 쉬워지고 자주 사용하는 뷰의 묶음의 재사용성도 높아지는 장점이 있습니다.
5
날짜, 시간 설정 위젯 -> DateTimePicker View
DatePicker – 날짜를 설정하는 위젯 Time Picker – 시간을 설정하는 위젯 CheckBox – 항목을 설정하는 위젯 여기서 통합할 각각의 View를 소개하겠습니다. DatePicker, TimePicker, CheckBox 세개입니다. -> 각각소개
6
Datetimepicker.xml 날짜 선택 위젯 시간 선택 위젯
실제로 앞에서 액티비티를 정의할 때 처럼 새 액티비티를 띄우기 위해 레이아웃을 선언한게 아니고 복합위젯을 만들기위해 여러가지 뷰를 선언해놓습니다. 이것은 앞에 레이아웃 클래스에서 묶어주는 작업을 합니다. 시간 선택 위젯
7
DataTimePicker.java 날짜, 시간선택 위젯 부분
새로운 뷰를 정의하기 위해 LinearLayout을 상속받아서 새로운 DataTimePicker 클래스를 정의합니다. 앞에 선언한 뷰들이 LinearLayout형식이기 때문에 똑같은 레이아웃을 상속받습니다. Public interface~ : 이벤트를 처리하기 위한 인터페이스를 정의합니다. DatePicker와 TimePicker를 하나로 묶은 형태이기 때문에 리스너 인터페이스를 새로 정의해줍니다. 리스너 클래스 이름은 저렇게 똑같이 선언해줍니다. DatePicker – 날짜를 선택할 수 있게 해주는 메소드 정의 TimePicker – 시간을 선택할 수 있게 해주는 메소드 정의 새로운 복합 위젯을 생성하기 위해서 Context를 생성자로 넘겨주고 메소드를 선언합니다. 여기서 Context가 하는 일은 커스텀뷰나 다른 클래스에서 xml리소스를 접근, 공유하기 위해 사용합니다. 이로써 앞에 xml에서 정의한 뷰에 대한 리소스 및 시스템 레퍼런스를 접근할 수 있고 값을 넣어줄 수 있습니다.(this선언으로 xml을 받아옵니다.)
8
DataTimePicker.java 복합 뷰에 대한 초기값과 이벤트처리를 정의하는 부분입니다.
Xml파일에서 각 뷰들에게 넘겨줄 속성을 지정해 줄 때 AttributeSet메소드를 사용하여 새로 정의해줍니다. 여기서 우리는 새로운 뷰를 만들기 때문에 여러 개의 뷰에 값을 넘겨줄 속성을 attr.xml에 선언하여 저장하고 프로그램 실행 시에 이 정보를 읽어서 뷰에 초기화 해줍니다. xml레이아웃 인플레이션부분. Xml안의 아이템들(여러가지 뷰)을 실제 클래스 안에서 초기화 하고 바꿔주는 작업을 하기 위해 이 기능을 사용합니다. 이 기능으로 xml파일을 inflater에 객체화 시키면 클래스 안에서 초기값을 설정하고 변경할 수 있습니다. 현재는 API버전업이되면서 이 방식은 사라지고 style클래스로 대체됩니다. 레이아웃을 화면에 출력하기 위해서 앞에서 본 datetimepicker.xml의 뷰 정보를 얻어오는 작업을 합니다. 2. 시간 정보를 참조하는 부분입니다. Calendar 클래스를 사용하여 년, 월, 일 시간, 분 정보를 변수에 리턴해줍니다. 3. 날짜 선택위젯 부분입니다. datePicker.init() 현재 년도, 달, 일 그리고 추가적인 이벤트를 처리를 해주는 메소드를 선언합니다. 그리고 이벤트 처리를 할 리스너는 앞에서 구현한 새로운 리스너 인터페이스를 사용하여 이벤트 처리를 하도록 합니다.
9
DataTimePicker.java 여기서 현재 시간의 정보가 timePicker에서 처리할 시간과 분을 초기화됩니다. timePicker 클래스에 초기화 되게 됩니다. 위와 같이 DatePicker 이벤트처리방식과 같이 사용자가 새로운 시간을 선택하면 다시 호출하는 방식으로 이벤트 처리가 되어있습니다. 또한 위에서 새로정의한 리스너 인터페이스를 datePicker부분과 같이 써주고 있습니다. -> 여기서 알 수 있는 부분은 두개의 뷰의 이벤트 처리를 하는데 각각 다른인터페이스를 사용하지 않고 하나의 인터페이스로 정의하여 이벤트를 처리할 수 있다는 것을 알 수 있습니다. 체크박스 이벤트 처리 부분입니다. CheckBox클래스를 불러와서 만일 체크가 되면 다시 맨 밑에 부분에 setEnable(enableTimeCheckBox.isChecked())이 1로 셋이되고 바로 밑에 setVisibility부분에 값을 넘겨줘서 timePicker를 표시하여 보여줍니다.
10
Activity_main.xml 3. 복합위젯을 불러오는 부분입니다.(MainActivity.xml)
DateTimePicker View을 불러오기 위해서 이와 같이 앞에서 복합위젯으로 구현한 클래스를 xml레이아웃에 새로 태그를 추가해줍니다. 이렇게 앞에서 구현한 복합위젯을 쓸 수 있고 이렇게 복합적인 위젯이 하나의 위젯으로 표현되게 됩니다. -> 이렇게 자주 쓰는 위젯들은 하나의 커스텀뷰로 만들어서 재사용률을 늘릴 수 있어서 편리합니다.
11
MainActivity.java MainActivity.java부분
simpleDateFormat dateformat = 부분 – 년, 월, 일, 시간을 표시해주는 간단한 클래스. 밑에부분 복합위젯으로 구현한 클래스를 불러와서 MainActivity에 띄어줍니다. 그리고 Calendar 객체를 불러와서 앞에서 정의한 새로운 리스너에 있는 정보를 초기화 받아서 Calendar.set(year, monthOfyear, dayOfYear, hourOfDay, minute)처럼 넣어주고 달력에 표시해 줍니다.
12
월별 캘린더 만들기 그리드뷰(GridView) 형식의 월별 캘린더를 만들어본다.
그리드뷰(GridView)를 상속받아 새로운 View를 만들어본다. 각각 기능을 처리하는 여러 클래스들을 정의하여 메인 엑티비티에서 객체로 불 러와 사용해본다.
13
그리드뷰(GridView) 형식의 월(月)을 넘길 수 있는 달력.
사용자가 선택한 일(日)을 표시해 주는 기능
14
Activity_main.xml <Activity_main.xml 부분>
월을 선택하기 위한 버튼 부분과 달력의 현재 달과 년도를 표시해주는 TextView입니다. 다음 직접 GridView를 상속받아서 새로 형성한 View를 이렇게 달력 형식으로 보여줍니다. 여기서는 분명 그리드뷰를 사용하지 않았는데 어떻게 저렇게 그리드뷰 방식의 달력을 표시해주는건가. 이게 핵심포인트입니다. 그리드뷰를 클래스에 상속받아서 새로운 뷰를 생성하는 커스텀뷰입니다.
15
CalendarMonthView.java 실제 뷰의 모양을 형성하는 클래스부분 CalendarMonthView.java부분.
앞에 사진에서 본 그리드뷰 방식의 달력의 뷰를 정의하는 부분입니다. 전체적인 그리드뷰 달력의 모양 속성을 지정하는 부분입니다. 1. 앞에서 복합위젯에서 보다 시피 GridView를 상속받아서 새로운 뷰를 정의합니다 2. 이 뷰를 정의하기 위해 기본적으로 필요한 Android의 레퍼런스의 기본기능과 모양 속성을 초기화 받아 정의해서 띄어줍니다. 3. 모양 속성은 아래와 같이 정의 가로 7칸으로 정의하고 셀간의 간격을 설정하는 부분이고 각 그리드의 너비공간은 열의 개수를 고려해서 균등하게 뻗어준다고 설정합니다. Column을 설정하고 이벤트 처리를 할 리스너도 설정해줍니다.
16
뷰의 초기값, 이벤트값등을 처리해주는 클래스 부분
CalendarMonthAdapter.java 뷰의 초기값, 이벤트값등을 처리해주는 클래스 부분 CalendarMonthAdapter.java부분 실제로 뷰의 전체적인 기능을 서브클래스들로부터 받아서 정의해주는 클래스입니다. 실제 뷰 기능처리의 메인 클래스라고 할 수 있는 부분입니다. BaseAdapter 클래스를 상속받아서 구현합니다. 우리는 그리드뷰를 이용하여 달력을 만들기 때문에 그리드뷰의 상위 클래스인 BaseAdapter를 상속받습니다. Init()부분에서 배열 객체를 생성하는데 이 배열도 클래스로 정의해서 만들어줍니다. MonthItem배열 객체에는 한 개월의 일별 데이터를 담을 수 있도록 구현을 해줍니다. 해당 월에 대한 정보에 대한 메소드를 정의하고 선언해줍니다. Public void setPreviousMonth(), setNextMonth()부분에서는 Calendar객체의 인터페이스를 이용하여 달에 -1, 1을 더해주는 식으로 버튼을 누르면 다음달 또는 이전달이 표시되도록 구현. resetDayNumbers 메소드에서 실제 당 월의 일별 데이터를 계산하는 부분입니다. 한번 살펴보겠습니다.
17
CalendarMonthAdapter.java 실제 여기서 매 월마다의 달력 일 수를 계산하여 MonthItem객체에 저장해주는 작업을 합니다. 여기서 getFirstDay메소드, getMonthLastDay메소드를 사용하여 그 달의 일 수를 계산하고 초기화해주는 메소드입니다.
18
getCount, getItem, getItemID, getView
CalendarMonthAdapter.java getCount, getItem, getItemID, getView BaseAdapter를 상속 받을 때 필수로 선언 해줘야하는 부분입니다. 열의 개수는 7개, 그리드뷰의 공간 개수를 Column*Low(행 곱하기 열)방식으로 선언해주고 getItem()메소드는 그리드뷰의 포지션에 해당하는 위치에 담을 데이터 요소를 리턴시켜줍니다. getItemId()메소드는 그리드 뷰의 각 공간에 대한 위치 정보를 포함합니다. 저게 기본 정의 형식입니다. 중요한 부분은 getView메소드 부분입니다. 다음 슬라이드에서 설명하겠습니다.
19
CalendarMonthAdapter.java 여기서 출력하고자 하는 View를 메소드형식으로 생성하고 만들어서 View객체로 리턴하는 부분입니다. 첫번째는 그리드뷰의 순서값을 매개변수로 받고, 두번째로는 이전에 생성된 View. 즉 convertView를 넘겨줍니다. 이 ConvertView는 안드로이드가 사용자의 편의성을 위해 제공되는 객체입니다. 이전에 안드로이드에 불러온 뷰에 대한 정보를 저장하는 객체입니다. 만일 다음 월을 보다가 이전 월을 보는데 또 다시 뷰를 선언해서 생성하면 메모리 낭비가 되는데 이를 막기위해서 전에 불러왔던 뷰에 대한 정보를 재 사용할 때 사용하는 객체입니다. 그리고 세번째 부분은 getView에 의해서 접근할 View입니다. 여기서는 기본값인 ViewGroup parent객체를 넘겨줍니다. 이로써 그리드 구조를 접근하고 보여줄 수 있습니다. 실제 이 클래스가 객체화 되어서 기본 액티비티에 태그되어 선언되고 MainActivity에서 사용됩니다. 밑에는 GridView.LayoutParams params로 GridView.LayoutParams.Match_PARENT로 개체속성을 지정해주는 작업을 합니다. 2. 실제로 달력 표시용 GridView의 가로, 세로 개수를 계산하여 지정해주고 실제로 그려주고 칸 속성을 각각 이런식으로 지정해줍니다. setItem()에는 날짜 정보가 들어가고, LayoutParams는 그리드뷰 칸의 각 속성 크기 조정, setPadding.은 각 그리드뷰 칸 마다의 여유공간입니다. (왼쪽, 위, 오른쪽, 아래) - pixel 3. 선택한 요일 배경 색을 지정해서 표시해줍니다. 사용자가 그 달일을 누르면 노란색으로 박스가 색칠 되게 구현합니다.
20
MainActivity.java 뷰 사용 선언 달력에 사용할 데이터가 담겨있는 객체 선언 달력 뷰에 리스너 설정
앞에서 구현한 하위 클래스들과 그 하위클래스를 모아서 구현한 CalendarMonthAdapter클래스와 CalendarMonthView클래스를 이제 MainActivity에 객체로 불러와서 사용합니다. 캘린더뷰 객체 참조 선언합니다. 앞에서 구현한 CalendarMonthAdapter클래스를 선언하고 캘린더 뷰에 사용할 어댑터 객체(즉 정보를 넣어줄 객체)를 설정해줍니다. 달력뷰를 누르면 노란색으로 표시를 하기위한 리스너도 설정해주고 역시 이 리스너 설정에도 앞에서 구현한 CalendarMonthAdapter객체를 사용합니다. 이전 달, 다음 달 버튼을 누르면 처리할 이벤트도 정의해줍니다. 역시 CalendarMonthAdapter객체를 사용하여 이벤트 처리합니다.
21
멀티터치 이미지 뷰어 만들기 멀티터치를 이용하여 이미지 사이즈를 확대/축소 할 수 있는 이미지 뷰어 만들 어보기
멀티터치 작동 원리를 파악해보고 구현해본다. 이미지 확대 축소기능 원리를 알아보고 구현해본다.
22
기본 이미지 표시에 그치지 않고 확대 축소기능을 제공.
멀티터치에 사용하는 메소드인 getPointerCount(), getX(int pointerIndex), getY(int pointerIndex) 를 알아본다. 이미지 확대 축소 메소드인 postScale, postTranslate를 알아본다.
23
Activity_main.xml Xml부분입니다. 기본 리니어 레이아웃 하나를 만들어주고 클래스에서 참조할 아이디를 viewerContainer로 할당해줍니다. viewerContainer객체를 클래스에서 새로 정의하여 옆에 화면과 같이 만들어주게 됩니다.
24
ImageDisplayView.java ImageDisplayView.java부분. 이미지의 확대, 축소 이벤트를 구현하기 위한 클래스입니다. View를 상속받고(이미지를 보여주기 위해) OnTouchListener 인터페이스를 구현합니다. onSizeChanged 메소드에서 비트맵 이미지를 초기화합니다. (뒤에서 설명하겠지만 newImage 메소드 redraw 메소드에서 이미지 속성 정보를 받아서 처리) newImage메소드로 메모리에 비트맵 이미지를 올려놓습니다. 왜냐하면 터치 이벤트에 따라서 이미지를 이동, 확대/축소하는 처리를 계속 해줘야하므로 계속 다시 그려줘야하기 때문에 메모리 상에 올려놓습니다. 실제 이미지를 그려서 표시하는 부분은 onDraw메소드로 구현하고 메모리에 만들어둔 비트맵 이미지를 화면에 보여주는 ‘더블버퍼링 방식'을 사용합니다. 더블버퍼링 : 확대/축소 시 다시 그릴 때 깜빡이는 현상을 막기 위해 이 방식을 사용 -> 책의 뒤 내용이므로 간단하게 설명.
25
ImageDisplayView.java 실제 확대/축소, 이동 이벤트를 처리하는 부분입니다.
onTouch()메소드부분입니다. 이 부분에서 여러가지 android메소드를 사용하여 사이즈 조절, 이동이벤트를 구현합니다. <터치한 손가락 개수 확인 > ev.getPointerCount()부분에서 손가락을 몇번 눌렀는지 정보를 카운팅 합니다. 한 손가락이면 1, 두 손가락이면 2를 반환합니다. 만일 한 손가락이면 손가락이 올려진 좌표의 x, y좌표를 저장합니다. <ACTION_MOVE> 움직였을 때 이벤트를 처리하는 부분입니다. 움직이는 좌표값을 넘겨받아서 offset, offsetY에 값을 저장하고 moveImage메소드로 넘겨줍니다. <moveImage 메소드> 이 부분에서 postTranslate라는 이미지 이동을 처리해주는 메소드에 offset값을 넘겨져서 이미지의 위치값을 바꿔주게 됩니다. mMatrix는 Matrix라는 메소드인데 이미지는 여러 픽셀이 모아져 있는 형태고 이 픽셀들을 행과 열로 구성된 하나의매트릭스로 인식하여 이동된 좌표값이 적용된 이미지를 mMatrix에 저장을 해줍니다. Redraw()메소드에서 이 저장된 matrix값을 참조하여 다시 이미지를 그려주게 됩니다.(이동된 위치로)
26
ImageDisplayView.java <만일 두 손가락으로 확대 축소 이벤트를 했을 떄>
두 손가락의 각자의 좌표를 입력받아서 상대적인 거리를 계산해줍니다. 축소, 확대를 하는 조건이 만족되면 scaleImage()메소드를 호출하게 됩니다. 호출하여 앞에 이동하는 메소드와 같이 메트릭스 연산을 하고 다시 그려주게 됩니다.
27
MainActivity.java 메인 엑티비티 부분
Activity_main.xml부분의 LinearLayout을 불러오고 앞에서 구현한 ImageDisplayView뷰 클래스를 선언하고 init()로 초기화 합니다. Init()표시하는 형식을 viewContainer뷰에 ImageDisplayView뷰를 더해서 선언합니다.
28
프로그램 구현해보기 기존 SearchApp 프로그램에 달력을 표시, 표시해제 하는 뷰를 생성한다.
CheckView, DatePicker 뷰를 사용하되 두 개의 뷰를 하나의 뷰로 만드는 복합 위젯을 구현해본다.
30
복합위젯으로 구현
31
MainActivity.java
32
ShowCalendar.java
Similar presentations