System.out.println("Hello, World");


TextView의 디폴트 버퍼 타입은 normal이므로 스팬을 배치할려면 buffertype 속성을 spannable로 지정해야 한다. EditText의 디폴트 버퍼 타입은 편집을 지원하는 editable이므로 별 지정이 없어도 스팬을 배치할 수 있다.


위와 같이 XML을 설정해준다.



실행하게 되면 위와 같은 화면처럼 출력된다. 

이제 이것들을 bufferType을 이용하여 다 잘라낼것이다.




위 코딩 내용중 1~7까지는 기울임, 8 ~ 11까지는 빨간색 배경, 12 ~17까지는 밑줄 속성을 부여한다.


에디트 스팬에는 다양한 플래그를 지정하였다. 플래그는 SPAN_앞쪽확장여부_뒤쪽확장여부 식으로 되어 있는데 스팬의 경계 부분에 새 문자가 입력 될때 스팬의 확장 여부를 제정한다. 

EXCLUSIVE이면 확장되지 않고 INCLUSIVE이면 확장된다. 


espan.setSpan(new StyleSpan(Typeface.ITALIC), 1, 7,

Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);


ITALIC체는 둘다 제외이므로 앞뒤로 새 문자를 삽입해도 기울임 속성이 적용되지 않는다. 


espan.setSpan(new BackgroundColorSpan(0xffff0000), 8, 11,

Spannable.SPAN_INCLUSIVE_INCLUSIVE);


RED는 둘다 포함이므로 앞뒤로 새 문자를 삽입할때 빨간색으로 삽입된다. 


espan.setSpan(new UnderlineSpan(), 12, 17,

Spannable.SPAN_EXCLUSIVE_INCLUSIVE);


UnderLine은  앞은 미포함이고 뒤에는 포함이므로 뒤에는 밑줄이 적용된다.



BufferType

 buffertype 속성

설명 

 NORMAL

normal 

단순한 문자열이며 읽기 전용이다. 

SPANNABLE 

spannable 

문자열에 부가 정보를 같이 기록한다. 

EDITABLE 

editable 

편집 가능한 문자열이다. 


setSpan 메서드는 문자열의 start와 end 오프셋 사이에 스팬 정보를 설정한다. 설정 대상 정보의 종류가 워낙 많고 사용자가 정의할 수 도 있기 때문에 서식 인수는 Object 타입으로 받는다. 



Posted by 김마농



200자 정도되는 소스코드. 


Posted by 김마농




일단 각각 버튼들에게 컨텍스트메뉴를 등록한다고 정의해준다. 


사용자가 위젯들을 롱 클릭하면 onCreateContextMenu 메서드가 호출되며 두 번째 인수로 롱클릭한 뷰가 전달된다. 


커스텀뷰는 onCreateContextMenu를 재정의하여 컨텍스트 메뉴를 직접 생성하며 MyImage는 자신의 메서드에서 이미지 회전, 크기 변경 등 이미지 관리에 대한 메뉴항목을 추가한다. 컨텍스트 메뉴는 직접 생성하더라도 선택시의 동작은 직접 처리할 수 없으며 액티비티의 onContextItemSelected 메서드에서 한꺼번에 수행하여야 한다.






Posted by 김마농

레이아웃을 통해 버튼을 만들어주고 

menu.xml을 이용하여 각각 메뉴버튼을 만들어주고 라디오버튼과 체크박스를 만들어준다. 

라디오 버튼은 그룹으로 묶어서 한 항목이 선택되었을떄 다른 항목을 선택할 경우 그 항목만 체크된다. 

체크박스는 체크했을경우와 체크안했을경우가 나타난다.






위와 같은 소스로 실행하게 되면 


   


   



위와 같이 실행된다. 



Posted by 김마농



화면에 짜장, 짬뽕, 기타 메뉴를 만들어준다. 

짜장과 짬뽕을 선택하면 토스트 메시지로 저장해둔 메시지가 출력되고, 기타를 선택하면 다른 팝업창이 출력되어 우동과 만두를 선택하라고 한다. 

그 항목중 한개를 선택하면 메시지가 토스트된다.






메뉴를 XML로 만들어서도 사용할 수 있다.

XML로 메뉴를 만들면 개발과정도 편리할 뿐만 아니라 국제화에도 유리하므로 이후 메뉴를 디자인할때는

가급적이면 XML로 정의하는 것이 유리하다.






Posted by 김마농

타이머 처리를 위해 Handler 클래스를 사용한다. 핸들러는 스레드간의 메시지 통신을 위한 장치로서 sendMessage 메서드나 유사 메서드로 특정 핸들러에게 메시지를 보낼수 있다. 핸들러는 스레드의 경계를 넘어설수 있는 범용적인 통신 장치이며 제대로 사용할려면 꽤 많은 것을 알아야 하지만 한 스레드내에서 간단하게 타이머로도 쓸수 있다.


mHandler가 핸들러이며 handleMessage에서 value값을 1 증가 시켜 텍스트뷰로 호출한다. sendEmptyMessageDelayed 메서드로 1초간의 지연시간을 두어 1초후에 호출되도록 한다.



다음은 핸들러가 하는 일이 복잡하지 않고 코드가 단순하다면 굳이 외부에 둘 필요 없이 onCreate 메서드 안에서 지역적으로 초기화 시키는 것도 가능하다. 이벤트 리스너를 onCreate에서 생성 및 초기화하는 것과 마찬가지이다.



핸들러 초기화문이 onCreate에 작성되어 있으며 최초 빈 메시지를 보내는 문장과 나란히 둘수 있어 좀더 간단해보인다. 

핸들러가 자신을 재귀호출하면 무한히 반복되지만 일정 조건이 만족되면 재호출을 중지 할 수도 있다.


핸들러로도 타이머 흉내를 낼 수 있지만 익숙해지면 오히여 융통성이 있다. 중간에 타이머를 멈추거나 주기를 바꾸는 것도 가능하지만 스레드 간의 통신을 위해 제공되는 클래스라 원래의 용도와는 조금 맞지 않는 면이 있기 때문에 CountDownTimer 클래스를 활용하는 것이다.




위의 소스는 객체를 생성하자마자 시작하며 10초동안 1초 간격으로 나누어 작업한다. 

value가 5가 되면 cancel이 되도록 명령을 했지만 무슨 이유인지 작동안하고 10초까지 카운트한다. 




Posted by 김마농

버튼은 클릭이외에도 롱클릭이라는 이벤트를 받는다. 롱클릭은 버튼을 일정한 시간동안 계속 누르고 있는 동작이며 터치를 떼지 않고 계속 누르고 있으면 롱클릭 이벤트가 발생한다. 

다음은 버튼과 롱클릭 버튼을 2개 모두 활용한 모습이다. 

XML에서 각각 버튼에 mOnClick이라는 OnClick을 주었고, 이 버튼을 찾아서 setonLongListener를 해준다.



Posted by 김마농

보통 버튼에 리스너를 추가하여 작업하지만 소스가 지저분해진다. 

하지만 버튼에 클릭했을때 어떤 동작을 수행할지 추가해주면 소스도 깨끗해지고 간편해진다.




하지만 속성을 통한 핸들러 연결은 클릭 이벤트에 대해서만 예외적으로만 적용되는 것이므로 다른 이벤트에는 사용할 수 없다.

 또 SDK1.6버전에서 추가된 기능이라 다른 버전에서는 실행되지 않을 수 있다.

Posted by 김마농


버튼 2개를 통해 Text뷰를 찾아가서 문자열을 변경한다. 


비슷한 코드가 반복되면 통합하는것이 리팩토링의 기초이다. 다행히 안드로이드는 하나의 리스너를 여러 뷰에 대해 등록하는 것을 허용한다.

한 객체를 두 번 사용하려면 이름이 필수적이므로 익명 클래스의 임시 객체를 생성하는 방법은 쓸 수 없다.



핸들러가 하나로 통합되었다는 면에서는 바람직하지만 액티비티를 리스너로 사용한다는 점은 다소 부담스럽다. 최상위의 액티비티는 그대로 두고 

별도의 리스너 객체를 멤버로 선언한후 이 멤버를 리스너로 사용하는 것이 좀 더 깔끔하다. 






Posted by 김마농


키 액션을 통해 mX, mY의 값에 변화를 주어 원이 이동시키게끔 만들어준다. 



Posted by 김마농