6. 구성요소에 활력 불어넣기
1. 블록에디터를 오픈하고 좌측에 위치한 사용자블록(My Blocks)탭을 선택하면 디자이너창에서 작업한 라벨, 원형컬러버튼, 수평배열, 제거용리스크피커, 데이터베이스(TinyDB), 클록 및 통보자(Notifier1) 등에 각각 대응하는 복수의 드로워(Drawer)가 나타난다. 이외에도, 나중에 설명하는 바와 같이 변수블록 등을 정의할 때에 자동생성되는 블록을 저장하는 사용자정의(My Definitions)드로워가 나타난다.
2. 메모를 다이내믹하게 임시저장하기 위해 사용하는 변수와 저장된 메모를 삭제하기 위해 사용하는 인덱스 및 색을 감마보정하기 위한 변수에 대해 설명한다.
2-1. 우선, 메모를 다이내믹하게 임시저장하기 위해 사용하는 변수에 대해 설명한다.
블록에디터의 내장블록(Built-In)탭을 선택하고 정의(Definition)드로워를 열고 변수(def variable)블록을 선택하여 작업영역으로 드래그하고, 이 블록에 기재된 디폴트명(variable)을 더블 클릭하여 NoteList로 정정하여 기재한다. 또한, 리스트(Lists)드로워를 선택하여 열고 리스트만들기블록(call make a list item)을 선택하여 작업영역으로 드래그하고, 아래 스크린샷과 같이, 상기 변수블록에 조합한다.
참고 사항: 리스트만들기 블록(call make a list item)의 소켓(item)은 빈공간으로 놓아 둠으로써, 나중에 설명하는 노우트텍스트박스(NoteTextBox)에 사용자가 메모내용을 기록하고 아이콘(연필과 메모장이 그려져 있는 아이콘)을 터치하면 상기 아이템(메모내용)이 생성된다.
2-2. 소형 데이터베이스(TinyDB)에 저장된 데이터를 삭제하기 위해, 변수를 사용하여 임시 저장소인 인덱스를 만들고 인덱스의 초기값을 0으로 한다.
구체적으로는, 블록에디터의 내장블록(Built-In) 탭을 선택하고 정의(Definition)드로워를 열고 변수(def variable)블록을 선택하여 작업영역으로 드래그하고, 이 블록에 기재된 디폴트명(variable)을 더블 클릭하여 removeIndex로 정정하여 기재한다. 또한, 수학(Math)드로워를 열고 숫자블록(number 123)을 선택하여 작업영역으로 드래그하고, 숫자(123)을 더블클릭하여0으로 정정한다. 제거용 인덱스(removeIndex)의 소켓에 숫자블록(number 0)을 플러그인한다. 그 결과의 스크린샷은 다음과 같다.
2-3. 다음에는, 원형컬러아이콘의 색과 노우트리스트라벨(NoteListLabel)의 백경색을 유사하게 하기 위해 컬러조정을 위한 변수로서 불투명도(Opacity)로 하고, 완전 불투명한 값을 초기치로서 255로 설정한다.
구제적으로는, 블록에디터의 내장블록(Built-In)탭을 클릭하고 정의(Definition)드로워를 선택하여 열고 변수(def variable)블록을 선택하여 작업영역으로 드래그하고, 이 블록에 기재된 디폴트명(variable)을 더블클릭하여 Opacity로 정정한다. 또한 수학(Math)드로워를 열고 숫자블록(number 123)을 선택하여 작업영역으로 드래그하고, 숫자(123)을 더블클릭하여 255로 정정한다. 컬러의 투명도를 변경하는 불투명도의 소켓에 숫자블록(number 255)을 플러그인한다. 그 결과의 스크린샷은 다음과 같다.
3. 동일한 절차를 계속 사용하여야 하는 경우에는 절차블록(procedure)을 사용하면 블록의 조합이 간편하게 된다. 즉, 절차블록은 매개변수화하여 사용하면 블록의 조합이 간편하게 된다.
3-1. 블록에디터의 내장블록(Built-In)탭을 선택하고 정의(Definition)드로워를 열고 절차블록(procedure)을 선택하여 작업영역으로 드래그하고, 이 블록에 기재된 디폴트명(procedure)을 더블 클릭하여 displayNotes로 정정하면, 사용자블록(My Blocks)탭의 사용자 정의(My Definitions)드로워안에 자동으로 절차호출블록(call displayNotes)이 생성된다.
참고 사항: 이 절차호출블록은 필요에 따라 다른 블록에 추가할 수 있으므로 상당히 편리하다.
3-2. 라벨(NoteListlabel)에 기록된 텍스트를 모두 삭제하기 위해 다음의 스크린과 같이 블록을 조합한다.
참고 사항: 다음의 메모를 기록을 편리하게 하기 위해서 라벨에 기록된 텍스트를 모두 삭제한다.
3-3. 다음에, 노우트리스트(NoteList)에 임시 저장된 각 아이템(item)마다 퍼이취블록(foreach)내에 있는 기능블록(표시되지 않음)을 반복적으로 실행하기 위해 퍼이취블록(foreach)을 사용한다.
참고 사항: 퍼이취블록(foreach)은 단일의 리스트에 대해서만 반복적으로 사용할 수 있고, 화일블록(while)은 다수의 리스트에 대해서 반복적으로 사용할 수 있다. 퍼이취블록(foreach)의 조합은 간단하여 화일블록(while)에 비해서 버그가 발생할 가능성이 적다. 따라서, 동일한 단일의 리스트인 경우에는 퍼이취블록(foreach)을 주로 사용한다.
3-4. 상기 퍼이취블록(foreach)에서 반복하여 실행할 블록조합으로서 노우트리스트라벨의 텍스트(NoteListLabel.Text), 줄바꿈(백슬래시앤:\n) 및 메모기록(value item)으로 이루어진 한 그룹의 텍스트를 아이템(예를 들면 메모기록)마다 반복적으로 라벨의 텍스트(NoteListLabel.Text)에 설정(기록)한다.
참고 사항: 처음 시작하는 아이템인 경우에는 노우트리스트라벨의 텍스트(NoteListLabel.Text)는 공백 상태가 된다. 처음이후의 아이템인 경우에는 노우트리스트라벨의 텍스트(NoteListLabel.Text)는 이전의 모든 아이템에 대한 텍스트를 포함한다.
3-5. 이상과 같이 전체적으로 조합한 절차블록의 스크린샷은 다음과 같다.
4. 노우트텍스트박스(NoteTextBox)에 메모하고 연필과 메모장이 그려있는 아이콘을 터치하면,버튼클릭이벤트가 발생하고 이 이벤트시에 호출되는 버튼클릭이벤트핸들러의 사용에 대해서 설명한다.
4-1. 상기 버튼클릭이벤트핸들러의 블록은 다음과 같다.
4-2. 노우트텍스트박스에 기재된 메모(NoteTextBox.Text), 줄바꿈(text \n) 및 기록시간(call Clock1.FormatDateTime instant, call Clock1.Now) 등을 한 그룹의 텍스트(즉,단일의 아이템)로서 노우트리스트(NoteList)에 추가되는 블록을 조합하여 상기 버튼클릭이벤트핸들러에 기능을 부여한다.
참고 사항: 기록시간을 나타내기 위해 인비지블한 구성요소인 클록(Clock)을 사용한다.
4-3. 다음의 메모를 편리하게 기재하기 위해 텍스트박스의 텍스트를 공백상태로 설정한다.
4-4. 상기한 절차블록(displayNotes)을 호출하는 블록(call displayNotes)을 추가하여 조합한다. 즉, 리스트에 있는 아이템전체(메모전체)에 대한 텍스트를 라벨(NoteListLabel)에 나타내는 절차블록을 호출한다.
4-5. 안드로이드폰 내부에 있는 소형 데이터베이스의 스토어밸류(call TinyDB1.StoreValue tag valueToStore)에, notes(text notes)를 태그로 사용하여 노우트리스트(global NoteList)의 값(메모내용)이 저장된다. 즉, 소형 데이터베이스에 저장될 때에는 한쌍의 태그와 값(tag-value pairs)으로 저장된다.
참고 사항: 안드로이폰자체의 데이터베이스를 이용하기 위해 인비지블한 구성요소인 소형 데이터베이스블록(TinyDB)을 사용한다.
4-6. 이상 설명한 블록의 조합은 다음의 스크린샷과 같이 구성된다.
5. 다음은, 기록한 메모를 제거하기 위해 제거용 리스트피커를 사용하는 방법에 대해 설명한다. 휴지통 아이콘을 터치하면, 제거용 리스트피커에 이벤트가 발생하여 제거항목의 리스트가 나타난다. 이 제거항목을 피크(선택)하기 전후를 구분하여 블록을 구성한다.
5-1. 제거용리스트피커의 피크전블록을 사용하여, 제거할 메모리스트의 아이템을 선택하기전에 노우트리스트전체를 제거용리스트피커의 구성요소로 설정한다. 구체적인 설명은 다음과 같다.
5-1-1. 블록에디터의 사용자 블록(My Blocks)탭을 선택하고 리스트제거용 피커(RemoveListPicker)드로워를 열고 제거용리스트피커의 피크전블록(when RemoveListPicker.BeforePicking do)을 선택하여 작업영역으로 드래그한다.
5-1-2 노우트리스트를 제거용리스트피커의 구성요소로 설정한다.
5-1-3. 노우트리스트(NoteList)의 아이템을 선택하기 전에 노우트리스트를 제거용리스트피커의 구성요소로 설정하는 블록조합의 스크린 샷은 다음과 같다.
5-2. 노우트리스트에서 터치한 아이템의 위치에 대응하여 설정된 제거용 인덱스에 의거하여 노우트리스트에서 아이템을 제거한다. 구체적인 설명은 다음과 같다.
5-2-1. 블록에디터의 사용자 블록(My Blocks)탭을 선택하고 리스트제거용 피커(RemoveListPicker)드로워를 열고 리스트제거용피커의 피크후블록(when RemoveListPicker.AfterPicking do)을 선택하여 작업영역으로 드래그한다.
5-2-2. 노우트리스트(NoteList)에서 선택한 아이템(RemoveListPicker.Selection)의 위치(positon in list)를 제거인덱스(set global removeIndex to)로 설정한다.
5-2-3. 노우트리스트(NoteList)에서 제거인덱스(removeIndex)에 의거하여 노우트리스트에서 선택된 아이템(call remove list item list index)을 삭제한다.
참고 사항: 변수(variable)를 사용하여 제거인덱스블록(def removeIndex)의 생성시에, 전역 제거인덱스(global removeIndex)와 전역 제거설정인덱스(set global removeIndex to)는 자동으로 생성된다.
5-2-4. 상기 절차블록(displayNotes)을 호출하는 블록(call displayNotes)을 추가하여 조합한다. 즉, 상기 설명한 바와 같이 아이템이 제거된 노우트리스트의 아이템전체(메모전체)가 라벨(NoteListLabel)에 나타나는 절자블록을 호출한다.
다음에, 안드로이드폰 내부에 있는 소형 데이터베이스의 스토어밸류(call TinyDB1.StoreValue tag valueToStore)에, notes(text notes)를 태그로 사용하여 노우트리스트(global NoteList)의 값을 저장한다. 즉, 소형 데이터베이스에 저장될 때에는 한 쌍의 태그와 값(tag-value pairs)으로 저장된다.
참고 사항: 상기에서 설명한 버튼클릭이벤트에서 사용한 태그의 텍스트와 동일한 텍스트를 사용하여야 한다. 당연한 이야기이지만 실수로 태그의 텍스트가 서로 다른 경우에는 소형 데이터베이스에서 저장하는 장소와 삭제하는 장소가 다르게 되는 버그로 되어 지워지지 않는다.
이상 설명한 블록의 조합은 다음의 스크린 샷과 같이 구성된다.
참고 사항: 안드로이드폰의 내부에 있는 소형 데이터베이스(TinyDB)를 사용하는 경우, 앱을 종료한 후 다시 시작할 때에 값이 제대로 저장되어 있는 지의 여부를 테스트하기 위해서는 실제로 apk 파일을 안드로이드폰에 다운로드한 다음 실행하여야 실제로 동작된다. 앱인벤터를 애뮬레이터나 안드로이드폰에 직접 연결하여 라이브 테스트를 하는 경우 소형 데이터베이스(TinyDB)의 저장여부를 테스트할 수 없다.
6. 컬러버튼(원형 컬러 아이콘)을 터치하여 컬러버튼의 이미지색이 라벨의 배경색으로 나타내고 이 컬러에서 사용자가 입력한 메모의 글씨가 선명하게 나타나도록 조정한다.
컬러버튼의 배경색을 라벨의 배경색으로 옮기는 것은 지금까지 배운 내용으로 충분히 블록을 조합할 수 있다. 그러나, 컬러버튼의 이미지색을 라벨의 배경색으로 나타내는 블록조합은 실제로 곤란하다. 따라서, 수동으로 컬러를 맞추기 위해서는 시간을 요하는 시행착오의 작업이 필요하다.
6-1. 첫번째 원형아이콘은 청색이다. 문제는 아이콘의 청색과 앱인벤터에서 기본으로 제공하는 청색이 서로 다르게 나타난다. 원형 아이콘의 청색에 근접한 청색을 나타내기 위해 앱인벤터의 청색에 완전불투명도 x 100을 가산하여 원형아이콘의 청색에 가깝게 한다.
또한, 이 청색바탕에 글자가 선명하게 나타내기 위해 앱인벤터의 백색을 라벨의텍스트의 컬러로 사용한다. 이 결과의 블록조합의 스크린 샷은 다음과 같다.
참고 사항: 전역 불투명도(global Opacity)는, 변수(variable)를 사용하여 불투명도블록(def Opacity)의 생성시에 자동으로 생성된다.
6-2. 두번째 원형아이콘은 초록색이다. 이 색도 상기한 청색과 마찬가지의 방식으로 형성한다. 원형 아이콘의 초록색에 근접한 초록색을 나타내기 위해 앱인벤터의 청색에 완전불투명도x 215를 가산하여 원형아이콘의 초록색에 가깝게 한다.
또한, 이 청색바탕에 글자가 선명하게 나타내기 위해 앱인벤터의 시안과 마젠타의 혼합색을 라벨의 텍스트컬러로 사용한다. 이 결과의 블록조합의 스크린 샷은 다음과 같다.
6-3. 세번째 원형아이콘은 오렌지색이다. 원형 아이콘의 오렌지색은 앱인벤터의 오렌지색과 거의 비슷하여 앱인벤터에서 기본으로 제공하는 색을 그대로 사용한다.
또한, 이 오렌지색바탕에 글자가 선명하게 나타내기 위해 앱인벤터의 청색과 백색의 혼합색을 라벨의 텍스트컬러로 사용한다. 이 결과의 블록조합의 스크린 샷은 다음과 같다.
6-4. 네번째 원형아이콘은 적색이다. 이 색도 상기한 청색과 마찬가지의 방식을 사용하여 해결한다. 원형 아이콘의 적색에 근접한 적색을 나타내기 위해 앱인벤터의 적색에 완전불투명도 x 0.02를 가산하여 원형아이콘의 적색에 가깝게 한다.
또한, 이 적색바탕에 글자가 선명하게 나타내기 위해 앱인벤터의 백색을 라벨의텍스트컬러로 사용한다. 이 결과의 블록조합의 스크린 샷은 다음과 같다.
7. 예제를 실행할 때의 스크린의 초기화에 대해 설명한다.
7-1. 스크린의 초기화 이벤트핸들러는 다음의 스크린 샷과 같다.
7-2. 태그(text notes)를 사용하여 소형 데이터베이스의 겟밸류(call TinyDB1.GetValue tag)를 노우트리스트(set global NoteList to)에 임시 저장한다.
7-3. 노우트리스트에 아이템(이미 기록된 메모)이 없는 경우를 나타내는 조건블록이다.
7-4. 소켓(item)이 공백인 리스트만들기(call make a list item)를 노우트리스트(set global NoteList to)의 소켓(to)에 플러그인한다. 이 경우는 앱을 처음 실행한 경우이거나 이미 실행한 경우로서 기록된 메모를 모두 지운 경우에 해당한다.
7-5. 다음에, 상기 절차블록(displayNotes)을 호출하는 블록(call displayNotes)을 추가하여 조합한다. 즉, 리스트에 있는 아이템전체(메모전체)가 라벨(NoteListLabel)에 나타내는 절자블록을 호출한다.
7-6. 청색과 백색을 디폴트값으로서 초기화면의 라벨의 배경색 및 메모의 텍스트의 색으로 사용한다.
7-7. 사용자블록(My Blocks)탭의 통보자(Notifier1)드로워를 열고 통보자의 경고알림호출블록(call Notifier1.ShowAlert notice)을 선택하여 작업영역으로 드래그하고, 내장블록(Built-In)탭의 텍스트(Text)드로워를 열고 텍스트블록(text)을 선택하여 작업영역으로 드래그한다. 텍스블록(text)에, 알림문구로서 “메모한 다음 위의 연필과 메모장이 그려진 아이콘을 터치하세요.”를 복사하여 붙여 넣는다. 다음에, 경고알림호출블록(call Notifier1.ShowAlert notice)의 소켓(notice)에 상기 텍스트블록(text)을 조합한다.
7-8. 스크린의 초기화면을 위한 이벤트핸들러의 스크린샷은 다음과 같다.
8. 지금까지의 설명한 블록을 종합한 3개의 스크린샷을 이하 나타낸다.
안녕하세요! appinventor2로 올려두신 자료 실습중인 학생입니다ㅎㅎㅎ
답글삭제앱인벤터2에는 text block중에 make text항목이 없어서 우왕자왕하는 중입니다ㅜㅜ 어떤걸로 대체가능한건가요?