Presentation is loading. Please wait.

Presentation is loading. Please wait.

○ 본 강의 자료는 이지스퍼블리싱(주)에서 제공하는 강의 교안입니다.

Similar presentations


Presentation on theme: "○ 본 강의 자료는 이지스퍼블리싱(주)에서 제공하는 강의 교안입니다."— Presentation transcript:

1 ○ 본 강의 자료는 이지스퍼블리싱(주)에서 제공하는 강의 교안입니다.
○ 본 강의 교안은 아래 출판 서적의 내용을 기준으로 구성되었습니다. 또한 다수의 기타 서적이나 사이트를 참조하였습니다. 레퍼런스를 참조하십시오. 2015, 정재곤, “Do it! 안드로이드 앱 프로그래밍(개정2판)”, 이지스퍼블리싱(주) - 강의 교안에 사용된 화면 캡쳐나 실습 자료의 경우에는 문서 업데이트에 따라 변경될 수 있습니다.

2 선택위젯의 사용과 커스텀뷰 만들기 둘째 마당 - Chapter 04 Do It! 안드로이드 앱 프로그래밍 Feb. 2015
개정 2판 – 롤리팝, 안드로이드 스튜디오 Feb. 2015 ○ 본 강의 자료는 이지스퍼블리싱(주)에서 제공하는 강의 교안입니다. ○ 본 강의 교안은 아래 출판 서적의 내용을 기준으로 구성되었습니다. 또한 다수의 기타 서적이나 사이트를 참조하였습니다. 레퍼런스를 참조하십시오. 2015, 정재곤, “Do it! 안드로이드 앱 프로그래밍(개정2판)”, 이지스퍼블리싱(주) - 강의 교안에 사용된 화면 캡쳐나 실습 자료의 경우에는 문서 업데이트에 따라 변경될 수 있습니다. 이지스퍼블리싱(주) 제공 강의 교안 저자 : 정재곤

3

4 아이콘이 들어간 리스트가 포함된 화면을 만들 때는 어떻게 하나요?
이번 장에서는 무엇을 다룰까요? 아이콘이 들어간 리스트가 포함된 화면을 만들 때는 어떻게 하나요? 나인패치 이미지에 대해 알아볼까요? 이미지로 보여지는 비트맵 버튼을 직접 만들어 볼까요? 리스트뷰가 포함된 화면을 만들어 볼까요? 콤보박스처럼 사용되는 스피너가 포함된 화면을 만들어 볼까요? 사진을 선택할 때 사용할 수 있는 갤러리를 사용해 볼까요? 테이블 모양으로 보여줄 수 있는 그리드뷰를 사용해 볼까요? 여러 개의 위젯이 들어있는 복합 위젯을 직접 만들어 볼까요? 달력 모양의 월별 캘린더를 만들어 볼까요? 두 손가락으로 이미지를 다루는 멀티 터치 이미지 뷰어를 만들어 볼까요?

5 이번 장에서는 무엇을 다룰까요?

6 강의 주제 및 목차 대표적인 선택 위젯의 이해와 실습 강의 주제 나인패치 이미지 그리드뷰 사용하기 목 차 비트맵 버튼 만들기
1 나인패치 이미지 6 그리드뷰 사용하기 목 차 2 비트맵 버튼 만들기 7 복합위젯 만들기 3 리스트뷰 사용하기 8 월별 캘린더 만들기 4 스피너 사용하기 9 멀티터치 이미지뷰어 만들기 5 갤러리 사용하기

7 둘째 마당 – CH4. 선택 위젯의 사용과 커스텀뷰 만들기
1. 나인패치 이미지

8 나인패치(Nine Patch) 이미지란? 이미지가 늘어나거나 줄어들 때 생기는 이미지 왜곡을 해결하는 방법을 정의한 것
서로 다른 해상도를 가진 여러 단말에 dp 단위로 뷰의 크기를 맞추다 보면 이미지 크기가 자동 조절되면서 왜곡되는 현상 발생  나인패치 이미지로 해결 [이미지의 크기에 따른 원본 이미지의 왜곡] [이미지의 크기를 늘릴 때 왜곡되는 영역] 1. 나인패치 이미지

9 나인패치 이미지 예제 나인패치 이미지 예제 메인 액티비티의 XML 레이아웃 메인 액티비티의 XML 레이아웃
일반 이미지와 나인패치 이미지 비교 레이아웃에 여러 개의 버튼 추가 메인 액티비티의 XML 레이아웃 메인 액티비티의 XML 레이아웃 일반 버튼 추가 나인패치 버튼 추가 1. 나인패치 이미지

10 XML 레이아웃 조정 일반 이미지를 배경으로 사용하는 버튼과 나인패치 이미지를 배경으로 사용하는 버튼 추가 <Button
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Small" android:textColor="#ffffffff" /> 1 일반 이미지를 배경으로 만든 작은 버튼 정의 1. 나인패치 이미지

11 [일반 이미지와 나인패치 이미지를 적용한 버튼 모양 비교]
실행 화면 일반 이미지를 배경으로 사용하는 버튼은 모서리 부분의 이미지 깨짐 현상 발생 나인패치 이미지를 배경으로 사용하는 버튼은 크게 이상하게 보이지 않음 [Reference] void setBackgroundColor (int color) void setBackgroundDrawable (Drawable d) void setBackgroundResource (int resid) [일반 이미지와 나인패치 이미지를 적용한 버튼 모양 비교] 1. 나인패치 이미지

12 둘째 마당 – CH4. 선택 위젯의 사용과 커스텀뷰 만들기
2. 비트맵 버튼 만들기

13 비트맵 버튼 만들기 비트맵 버튼을 직접 만들어 normal일 경우와 clicked일 경우의 이미지를 표시
나인패치 이미지를 적용하는 대표적인 경우가 바로 버튼인데 이렇게 배경 부분을 이미지로 지정하여 만든 버튼은 아무리 눌러도 이미지의 변화가 없어 사용자가 버튼을 눌렀는지 안 눌렀는지 알 수 없다는 단점이 있음 비트맵 이미지를 이용해 버튼의 상태를 표시하려면 버튼이 눌렸을 때와 떼어졌을 때를 이벤트로 구분하여 처리함 [Reference] public void onMeasure (int widthMeasureSpec, int heightMeasureSpec) public void onDraw(Canvas canvas) [Reference] void setMeasuredDimension (int measuredWidth, int measuredHeight) 2. 비트맵 버튼 만들기

14 뷰 위에 그래픽을 그리는 과정 뷰에 그래픽이 그려질 때 onDraw() 메소드 호출됨
다시 그리기는 invalidate() 메소드 사용 2. 비트맵 버튼 만들기

15 비트맵 버튼 만들기 예제 비트맵 버튼 만들기 예제 버튼을 상속한 XML 레이아웃에 추가 새로운 클래스 정의
이미지를 보여주는 비트맵 버튼 버튼을 상속한 새로운 클래스 정의 XML 레이아웃에 추가 새로운 버튼 클래스 정의 새로운 버튼 태그를 XML 레이아웃에 추가 메인 액티비티 코드 작성 메인 액티비티 코드에서 참조하여 사용 2. 비트맵 버튼 만들기

16 초기화 메소드를 정의하는 코드로 배경 이미지 설정과 텍스트를 위한 페인트 객체 생성
새로운 버튼 클래스 정의 터치 이벤트에 따라 배경 이미지를 바꾸어주는 버튼 클래스 정의 public TitleButton(Context context, AttributeSet atts) { super(context, atts); this.context = context; init(); } public void init() { setBackgroundResource(R.drawable.title_button); paint = new Paint(); paint.setColor(defaultColor); paint.setAntiAlias(true); paint.setTextScaleX(defaultScaleX); paint.setTextSize(defaultSize); paint.setTypeface(defaultTypeface); 1 초기화 메소드를 정의하는 코드로 배경 이미지 설정과 텍스트를 위한 페인트 객체 생성 Continued.. 2. 비트맵 버튼 만들기

17 터치 이벤트를 처리하여 버튼이 눌렸을 때 토스트 메시지 표시
새로운 버튼 클래스 정의 (계속) public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); int action = event.getAction(); switch (action) { case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_DOWN: Toast.makeText(context, titleText, Toast.LENGTH_SHORT).show(); } invalidate(); return true; 2 터치 이벤트를 처리하여 버튼이 눌렸을 때 토스트 메시지 표시 Continued.. 2. 비트맵 버튼 만들기

18 뷰가 화면에 그려질 때 호출되는 onDraw() 메소드 다시 정의
새로운 버튼 클래스 정의 (계속) public void onDraw(Canvas canvas) { super.onDraw(canvas); int curWidth = getWidth(); int curHeight = getHeight(); if (paintChanged) { paint.setColor(defaultColor); paint.setTextScaleX(defaultScaleX); paint.setTextSize(defaultSize); paint.setTypeface(defaultTypeface); } Rect bounds = new Rect(); paint.getTextBounds(titleText, 0, titleText.length(), bounds); float textWidth = ((float)curWidth - bounds.width())/2.0F; float textHeight = ((float)(curHeight-4) + bounds.height())/2.0F-1.0F; 4 뷰가 화면에 그려질 때 호출되는 onDraw() 메소드 다시 정의 5 텍스트의 크기 계산 Continued.. 2. 비트맵 버튼 만들기

19 새로운 버튼 클래스 정의 (계속) canvas.drawText(titleText, textWidth, textHeight, paint); } ... public void setDefaultColor(int defaultColor) { this.defaultColor = defaultColor; paintChanged = true; 6 캔버스 객체를 이용해 텍스트 그리기 7 색상 값 설정 메소드 정의 2. 비트맵 버튼 만들기

20 {(버튼의 폭 + 높이값) - (텍스트의 폭 + 높이값)}/2
버튼 중앙에 텍스트를 그리는 계산 {(버튼의 폭 + 높이값) - (텍스트의 폭 + 높이값)}/2 새로 정의한 뷰 자체의 크기는 getWidth()와 getHeight() 메소드를 이용해 가져올 수 있으므로 버튼의 중앙에 텍스트를 그려주기 위해 버튼의 폭과 높이값에서 텍스트의 폭과 높이값을 뺀 후 절반으로 나누는 방식으로 텍스트의 위치를 조정함 2. 비트맵 버튼 만들기

21 레이아웃 만들기 <org.androidtown.ui.TitleButton android:id="@+id/titleBtn"
android:layout_width="match_parent" android:layout_height=“22dp" android:layout_marginBottom=“4dp" /> <org.androidtown.ui.TitleBitmapButton android:layout_width=“20dp" android:layout_height=“40dp" android:layout_alignParentLeft="true" android:layout_marginTop="4dp" android:layout_marginLeft="4dp" 1 타이틀 영역을 보여주는 버튼 추가 2 타이틀 영역 안에 작은 버튼 추가 2. 비트맵 버튼 만들기

22 [[비트맵] 버튼을 이용한 상단 타이틀 표시]
메인 액티비티 코드 만들기 arrowLeftBtn.setBitmapResource(R.drawable.arrow_left, R.drawable.arrow_left_clicked); arrowLeftBtn.setOnClickListener(new OnClickListener() { public void onClick(View v) { finish(); } [[비트맵] 버튼을 이용한 상단 타이틀 표시] 2. 비트맵 버튼 만들기

23 Selector를 이용하는 방법 Selector를 이용해 버튼의 상태에 따라 이미지를 바꾸어 주는 방법도 적용 가능
normal 상태와 selected 상태를 구분하여 XML로 정의 후 background 속성으로 적용 <Button android:layout_width="46dp" android:layout_height="74dp" android:layout_alignParentLeft="true" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" /> <?xml version="1.0" encoding="UTF-8"?> <selector xmlns:android=" <item android:state_focused="true" android:state_pressed="false" /> android:state_pressed="true" android:state_focused="false" </selector> 2. 비트맵 버튼 만들기

24 둘째 마당 – CH4. 선택 위젯의 사용과 커스텀뷰 만들기
3. 리스트뷰 사용하기

25 왜 굳이 선택위젯이라는 이름으로 구분할까? 안드로이드에서는 여러 아이템 중의 하나를 선택하는 선택위젯은 별도의 패턴을 사용함
여러 개의 아이템 중에서 하나를 선택하는 방식의 선택 위젯은 어댑터를 사용하여야 함 이 어댑터에서 데이터를 관리하도록 해야 할 뿐만 아니라 화면에 보여지는 뷰도 어댑터의 getView() 메소드에서 결정함 선택위젯의 가장 큰 특징은 원본 데이터를 위젯에 직접 설정하지 않고 어댑터라는 클래스를 사용하도록 되어 있다는 점으로 이 패턴을 잘 기억해 두어야 함 [선택 위젯과 어댑터] 3. 리스트뷰 사용하기

26 대표적인 선택 위젯 안드로이드에서 제공하는 대표적인 선택 위젯들은 그 사용방법을 잘 알아두어야 함 3. 리스트뷰 사용하기

27 리스트뷰로 보여줄 때 해야 할 일들 (1) 아이템을 위한 XML 레이아웃 정의하기 (2) 아이템을 위한 뷰 정의하기
- 리스트뷰에 들어갈 각 아이템을 하나의 뷰로 정의. 이 뷰는 여러 개의 뷰를 담고 있는 뷰그룹이어야 함 (3) 어댑터 정의하기 - 데이터 관리 역할을 하는 어댑터 클래스를 만들고 그 안에 각 아이템으로 표시할 뷰를 리턴하는 getView() 메소드를 정의함 (4) 리스트뷰 정의하기 - 화면에 보여줄 리스트뷰를 만들고 그 안에 데이터가 선택되었을 때 호출될 리스너 객체를 정의함 3. 리스트뷰 사용하기

28 리스트뷰 사용하기 예제 리스트뷰 사용하기 예제 아이템의 XML 레이아웃 한 아이템의 데이터를 넣을 클래스 어댑터 클래스 정의
아이콘이 들어 있는 리스트뷰의 아이템 정의 리스트뷰의 한 아이템을 선택했을 때 토스트 표시 아이템의 XML 레이아웃 한 아이템의 데이터를 넣을 클래스 한 아이템으로 보여질 뷰의 XML 레이아웃 정의 한 아이템의 데이터를 넣을 클래스 정의 어댑터 클래스 정의 리스트뷰를 사용하는 메인 액티비티 코드 작성 리스트뷰 선택 이벤트 처리 코드 작성 리스트뷰를 보여주는 역할을 하는 어댑터 클래스 정의 리스트뷰를 사용하는 메인 액티비티 코드 작성 한 아이템을 선택했을 때의 이벤트 처리 3. 리스트뷰 사용하기

29 [리스트뷰의 한 아이템이 갖는 레이아웃의 예]
한 아이템으로 보여줄 XML 레이아웃 정의 선택위젯에서 각각의 아이템은 동일한 레이아웃을 가진 뷰가 반복적으로 보여짐 각각의 아이템을 위한 XML 레이아웃이 필요함 [리스트뷰의 한 아이템이 갖는 레이아웃의 예] <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > Continued.. 3. 리스트뷰 사용하기

30 한 아이템으로 보여줄 XML 레이아웃 정의 (계속)
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="8dip" android:layout_gravity="center_vertical" /> <LinearLayout android:orientation="vertical" android:layout_alignParentLeft="true" > 1 왼쪽에 보이는 이미지뷰 정의 Continued.. 3. 리스트뷰 사용하기

31 한 아이템으로 보여줄 XML 레이아웃 정의 (계속)
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:textSize=“12dp" android:padding=“4dp" /> <RelativeLayout > 2 첫 번째 줄의 텍스트뷰 정의 3 두 번째 줄을 표시할 상대 레이아웃 정의 Continued.. 3. 리스트뷰 사용하기

32 한 아이템으로 보여줄 XML 레이아웃 정의 (계속)
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" /> android:layout_alignParentRight="true" android:textColor="#ccf88107" android:textSize=“14dp" android:textStyle="bold" android:paddingRight="4dp" </RelativeLayout> </LinearLayout> 4 텍스트뷰 정의 5 두 번째 줄의 오른쪽에 있는 텍스트뷰 정의 3. 리스트뷰 사용하기

33 한 아이템으로 보여줄 뷰 정의 어댑터의 getView() 메소드에서 리턴해 줄 뷰를 별도의 클래스로 정의하여 사용
public class IconTextView extends LinearLayout { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.listitem, this, true); mIcon = (ImageView) findViewById(R.id.iconItem); mIcon.setImageDrawable(aItem.getIcon()); mText01 = (TextView) findViewById(R.id.dataItem01); mText01.setText(aItem.getData(0)); mText02 = (TextView) findViewById(R.id.dataItem02); mText02.setText(aItem.getData(1)); mText03 = (TextView) findViewById(R.id.dataItem03); mText03.setText(aItem.getData(2)); } 1 아이템의 모양을 구성한 XML 레이아웃을 인플레이터를 이용해 메모리 객체화 2 레이아웃에 정의된 이미지뷰 객체 참조 3 레이아웃에 정의된 텍스트뷰 객체 중에 첫 번째 것 참조 3. 리스트뷰 사용하기

34 한 아이템으로 보여줄 데이터 클래스 정의 각각의 아이템을 위한 데이터도 별도의 클래스로 정의하여 사용
public class IconTextItem { private Drawable mIcon; private String[] mData; public IconTextItem(Drawable icon, String[] obj) { mIcon = icon; mData = obj; } 1 리스트뷰의 한 아이템에 표시할 데이터를 담고 있을 클래스 정의 2 Drawable 타입의 변수와 문자열 타입의 배열 변수 선언 3 Drawable 객체와 문자열 타입의 배열을 파라미터로 전달받는 생성자 3. 리스트뷰 사용하기

35 새로운 어댑터 클래스 정의 public class IconTextListAdapter extends BaseAdapter {
private Context mContext; private List<IconTextItem> mItems = new ArrayList<IconTextItem>(); public IconTextListAdapter(Context context) { mContext = context; } public int getCount() { return mItems.size(); public Object getItem(int position) { return mItems.get(position); 1 BaseAdapter를 상속하여 새로운 어댑터 클래스 정의 2 각 아이템의 데이터를 담고 있는 IconTextItem 객체를 저장할 ArrayList 객체 생성 3 전체 아이템의 개수를 리턴하는 메소드 정의 Continued.. 3. 리스트뷰 사용하기

36 새로운 어댑터 클래스 정의 (계속) public View getView(int position, View convertView, ViewGroup parent) { IconTextView itemView; if (convertView == null) { itemView = new IconTextView(mContext); } else { itemView = (IconTextView) convertView; } itemView.setIcon(mItems.get(position).getIcon()); itemView.setText(0, mItems.get(position).getData(0)); itemView.setText(1, mItems.get(position).getData(1)); itemView.setText(2, mItems.get(position).getData(2)); return itemView; 4 아이템에 표시할 뷰 리턴하는 메소드 정의 3. 리스트뷰 사용하기

37 getView() 메소드 [Reference]
public View getView (int position, View convertView, ViewGroup parent) 첫 번째 파라미터 - 아이템의 인덱스를 의미하는 것으로 리스트뷰에서 보일 아이템의 위치 정보라 할 수 있음. 0부터 시작하여 아이템의 개수만큼 파라미터로 전달됨 두 번째 파라미터 - 현재 인덱스에 해당하는 뷰 객체를 의미하는데 안드로이드에서는 선택 위젯이 데이터가 많아 스크롤될 때 뷰를 재활용하는 메커니즘을 가지고 있어 한 번 만들어진 뷰가 화면 상에 그대로 다시 보일 수 있도록 되어 있음. 따라서 이 뷰가 널값이 아니면 재활용 가능함 세 번째 파라미터 - 부모 컨테이너 객체임 3. 리스트뷰 사용하기

38 메인 액티비티 코드 만들기 list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView parent,View v,int position, long id) { IconTextItem curItem = (IconTextItem) adapter.getItem(position); String[] curData = curItem.getData(); Toast.makeText(getApplicationContext(), "Selected : " + curData[0], Toast.LENGTH.SHORT).show(); } }); 리스트뷰에 어댑터 객체 설정 아이템을 클릭했을 때 토스트 메시지를 보여주도록 리스너 설정 3. 리스트뷰 사용하기

39 실행 화면 3. 리스트뷰 사용하기

40 둘째 마당 – CH4. 선택 위젯의 사용과 커스텀뷰 만들기
스피너 사용하기

41 스피너 사용하기 예제 스피너 사용하기 예제 메인 액티비티의 메인 액티비티 코드 작성 XML 레이아웃
콤보박스처럼 선택할 수 있는 스피너 사용 XML 레이아웃에 정의한 스피너 참조 메인 액티비티의 XML 레이아웃 메인 액티비티 코드 작성 스피너를 포함하는 메인 화면의 XML 레이아웃 정의 스피너 객체를 참조하여 설정 4. 스피너 사용하기

42 XML 레이아웃 만들기 <Spinner> 태그를 사용하여 레이아웃에 추가 <Spinner
android:layout_width="match_parent" android:layout_height="wrap_content" /> 1 스피너 정의 4. 스피너 사용하기

43 스피너에 표시될 아이템들의 데이터를 배열로 정의
메인 액티비티 코드 만들기 안드로이드에서 미리 만들어 제공하는 어댑터를 사용할 수 있음 String[] items = { "mike", "angel", "crow", "john", "ginnie", "sally", "cohen", "rice" }; selection = (TextView) findViewById(R.id.selection); Spinner spinner = (Spinner) findViewById(R.id.spinner); spinner.setOnItemSelectedListener(this); 1 스피너에 표시될 아이템들의 데이터를 배열로 정의 Continued.. 4. 스피너 사용하기

44 ArrayAdapter를 이용해 어댑터 객체 생성 스피너의 아이템이 선택되었을 때 처리하는 메소드 정의
메인 액티비티 코드 만들기 (계속) ArrayAdapter<String> adapter = new ArrayAdapter<String>( this, android.R.layout.simple_spinner_item, items); adapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); } public void onItemSelected(AdapterView<?> parent, View v, int position, long id) { selection.setText(items[position]); public void onNothingSelected(AdapterView<?> parent) { selection.setText(""); 2 ArrayAdapter를 이용해 어댑터 객체 생성 3 스피너에 어댑터 설정 4 스피너의 아이템이 선택되었을 때 처리하는 메소드 정의 4. 스피너 사용하기

45 ArrayAdapter의 사용 [Reference]
public ArrayAdapter (Context context, int textViewResourceId, T[] objects) 첫 번째 파라미터는 Context 객체이므로 액티비티인 this를 전달하면 됨 두 번째 파라미터는 뷰를 초기화할 때 사용되는 XML 레이아웃의 리소스 ID 값으로 이 코드에서는 android.R.layout.simple_spinner_item을 전달하였음 세 번째 파라미터는 아이템으로 보일 문자열 데이터들의 배열임 4. 스피너 사용하기

46 하나의 문자열을 보여주는 간단한 리스트뷰 사용
리스트뷰의 경우에도 안드로이드에서 미리 제공하는 어댑터 사용 가능 package org.androidtown.ui.spinner; ... public class MainActivity extends ListActivity { TextView selection; String[] items = { "mike", "angel", "crow", "john", "ginnie", "sally", "cohen", "rice" }; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); 1 리스트에 표시될 아이템들의 데이터를 배열로 정의 Continued.. 4. 스피너 사용하기

47 하나의 문자열을 보여주는 간단한 리스트뷰 사용 (계속)
setListAdapter(new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, items)); selection = (TextView)findViewById(R.id.selection); } protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); String text = " position:" + position + " " + items[position]; selection.setText(text); 2 ArrayAdapter를 이용해 어댑터 객체를 생성한 후 리스트에 설정 3 리스트의 아이템이 선택되었을 때 처리하는 메소드 정의 [리스트뷰에 단순 문자열만 표시한 경우] 4. 스피너 사용하기

48 둘째 마당 – CH4. 선택 위젯의 사용과 커스텀뷰 만들기
5. 갤러리 사용하기

49 갤러리 사용하기 예제 갤러리 사용하기 예제 메인 액티비티의 메인 액티비티 코드 작성 XML 레이아웃
콤보박스처럼 선택할 수 있는 스피너 사용 XML 레이아웃에 정의한 스피너 참조 메인 액티비티의 XML 레이아웃 메인 액티비티 코드 작성 갤러리를 포함하는 메인 화면의 XML 레이아웃 정의 갤러리 객체를 참조하여 설정 어댑터 클래스 정의 이미지뷰를 위한 액티비티 정의 갤러리를 위한 어댑터 클래스 정의 갤러리의 아이템 선택 시 보여줄 액티비티 정의 5. 갤러리 사용하기

50 레이아웃 만들기 갤러리(Gallery)는 사진을 나열해서 볼 수 있도록 하는 간단한 위젯
롤리팝 버전에서는 뷰페이저 사용을 권장하나 갤러리만의 특성이 있음 갤러리는 <Gallery> 태그를 이용해 XML 레이아웃에 추가할 수 있음 <Gallery android:layout_width="match_parent" android:layout_height="match_parent" android:verticalSpacing="10dp" android:horizontalSpacing="10dp" /> 5. 갤러리 사용하기

51 갤러리 객체에 ImageAdapter 객체 설정
메인 액티비티 코드 만들기 앨범에 있는 사진을 갤러리로 보여주기 위해 내용 제공자 사용 private void init() { String[] img = { MediaStore.Images.Thumbnails._ID }; imageCursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, img, null, null, MediaStore.Images.Thumbnails.IMAGE_ID + ""); imageColumnIndex = imageCursor.getColumnIndexOrThrow( MediaStore.Images.Thumbnails._ID); count = imageCursor.getCount(); gallery = (Gallery) findViewById(R.id.gallery); gallery.setAdapter(new ImageAdapter(getApplicationContext())); gallery.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView parent,View v,int position, long id) { System.gc(); String[] proj = { MediaStore.Images.Media.DATA }; 1 앨범 사진들에 대한 썸네일 이미지를 쿼리하여 Cursor 객체로 받음 2 갤러리 객체에 ImageAdapter 객체 설정 3 갤러리의 아이템을 클릭했을 때의 리스너 설정 Continued.. 5. 갤러리 사용하기

52 메인 액티비티 코드 만들기 (계속) actualImageCursor = managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj, null, null, null); actualImageColumnIndex = actualImageCursor.getColumnIndexOrThrow( MediaStore.Images.Media.DATA); actualImageCursor.moveToPosition(position); String filename = actualImageCursor.getString(actualImageColumnIndex); System.gc(); Intent intent = new Intent(getApplicationContext(), OriginalPictureView.class); intent.putExtra("filename", filename); startActivity(intent); } }); 4 앨범에 있는 원본 이미지를 쿼리하여 Cursor 객체로 받음 5 이미지를 보기 위한 액티비티 띄우기 Continued.. 5. 갤러리 사용하기

53 어댑터에서 리턴할 전체 아이템의 개수는 썸네일 이미지의 개수로 함
메인 액티비티 코드 만들기 (계속) public class ImageAdapter extends BaseAdapter { private Context mContext; public ImageAdapter(Context c) { mContext = c; } public int getCount() { return count; public Object getItem(int position) { return position; public long getItemId(int position) { 6 ImageAdapter 클래스 정의 7 어댑터에서 리턴할 전체 아이템의 개수는 썸네일 이미지의 개수로 함 Continued.. 5. 갤러리 사용하기

54 아이템으로 보일 뷰 객체를 리턴하는 getView() 메소드 정의
메인 액티비티 코드 만들기 (계속) public View getView(int position,View convertView,ViewGroup parent) { System.gc(); ImageView imgView = new ImageView(mContext.getApplicationContext()); if (convertView == null) { imageCursor.moveToPosition(position); int id = imageCursor.getInt(imageColumnIndex); imgView.setImageURI(Uri.withAppendedPath( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, ""+id)); imgView.setScaleType(ImageView.ScaleType.FIT_XY); imgView.setLayoutParams(new Gallery.LayoutParams(136, 88)); } else { imgView = (ImageView) convertView; } return imgView; 8 아이템으로 보일 뷰 객체를 리턴하는 getView() 메소드 정의 9 썸네일 이미지를 이미지뷰에 설정 5. 갤러리 사용하기

55 이미지를 보기 위한 액티비티의 레이아웃 갤러리에서 선택한 이미지를 보기 위한 액티비티의 레이아웃 정의 [Reference]
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI MediaStore.Images.Media.EXTERNAL_CONTENT_URI <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView /> </LinearLayout> 1 이미지뷰 정의 Continued.. 5. 갤러리 사용하기

56 이미지를 메모리로 로딩할 때의 축소 비율을 1/2로 지정
이미지를 보기 위한 액티비티 코드 메인 액티비티로부터 이미지에 대한 정보를 전달받아 비트맵 객체로 로딩 후 설정 private void processIntent() { System.gc(); Intent intent = getIntent(); Bundle extras = intent.getExtras(); filename = extras.getString("filename"); BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; Bitmap bitmap = BitmapFactory.decodeFile(filename, options); imgView.setImageBitmap(bitmap); } 1 메인 액티비티로부터 전달받은 인텐트 처리 2 이미지를 메모리로 로딩할 때의 축소 비율을 1/2로 지정 3 이미지 파일을 읽어 들여 비트맵 객체로 만듦 4 이미지뷰에 비트맵 객체 설정 5. 갤러리 사용하기

57 실행 화면 5. 갤러리 사용하기

58 둘째 마당 – CH4. 선택 위젯의 사용과 커스텀뷰 만들기
6. 그리드뷰 사용하기

59 그리드뷰 사용하기 예제 그리드뷰 사용하기 예제 어댑터 클래스 정의 메인 액티비티 코드 작성
테이블 형태로 보여주는 데이터를 관리할 어댑터 정의 테이블 모양의 뷰 생성 어댑터 클래스 정의 메인 액티비티 코드 작성 그리드뷰를 위한 어댑터 클래스 정의 그리드뷰와 어댑터를 이용해 화면에 표시 6. 그리드뷰 사용하기

60 어댑터 클래스 정의 테이블 모양으로 데이터를 보여주기 위해 그리드뷰 위젯을 사용 PC 또는 웹에서 많이 사용하는 것임
테이블(Table) 형태로 데이터를 보여주는 위젯 package org.androidtown.ui.gridview; ... public class DataAdapter extends BaseAdapter { Context mContext; Continued.. 6. 그리드뷰 사용하기

61 어댑터 클래스 정의 (계속) private MTable mTable; ...
public DataAdapter(Context context) { super(); mContext = context; } public DataAdapter(Context context, MTable table) { setTable(table); public int getNumColumns() { if (mTable == null) { return 0; return mTable.countColumn; 1 가상 테이블 객체 선언 2 테이블의 칼럼 개수 정보 확인 Continued.. 6. 그리드뷰 사용하기

62 전체 아이템의 개수 확인 (칼럼 수 * 레코드 수) 어댑터에서 사용되는 getView() 메소드 정의
어댑터 클래스 정의 (계속) public int getCount() { if (mTable == null) { return 0; } return (mTable.count()+1) * mTable.countColumn; public View getView(int position, View view, ViewGroup group) { Log.d("DataAdapter", "getView(" + position + ") called."); return null; 3 전체 아이템의 개수 확인 (칼럼 수 * 레코드 수) 4 어댑터에서 사용되는 getView() 메소드 정의 Continued.. 6. 그리드뷰 사용하기

63 position 값을 이용해 행과 열의 인덱스 값 계산
어댑터 클래스 정의 (계속) int rowIndex = position / mTable.countColumn; int columnIndex = position % mTable.countColumn; Log.d("DataAdapter", "Index : " + rowIndex + ", " + columnIndex); ... if (position < mTable.countColumn) { itemView.setText(mTable.columns[columnIndex].name); } else { Object item = ""; try { item = mTable.getCell(rowIndex-1, columnIndex); } catch(Exception ex) { ex.printStackTrace(); } itemView.setText(item.toString()); return container; 5 position 값을 이용해 행과 열의 인덱스 값 계산 6 position 값에 해당하는 셀의 값 확인 Continued.. 6. 그리드뷰 사용하기

64 getCount() 리턴 값 = 칼럼 개수 * 레코드의 개수 행과 열의 인덱스를 계산하여 새로 정의한 리스너 호출
전체 아이템 개수 계산 getCount() 리턴 값 = 칼럼 개수 * 레코드의 개수 public void onItemClick(AdapterView parent,View v,int position, long id) { if (selectionListener == null) { return; } int countColumn = 0; if (adapter != null) { if (adapter.getTable() != null) { countColumn = adapter.getTable().countColumn; int rowIndex = -1; int columnIndex = -1; if (countColumn > 0) { rowIndex = position / countColumn; columnIndex = position % countColumn; selectionListener.onDataSelected(parent, v, rowIndex, columnIndex, id); 4 행과 열의 인덱스를 계산하여 새로 정의한 리스너 호출 6. 그리드뷰 사용하기

65 새로 정의한 DataGridView 객체 생성 새로 정의한 DataAdapter 객체 생성
메인 액티비티 코드 만들기 grid = new DataGridView(this); grid.setColumnWidth(100); adapter = new DataAdapter(this); MTable table = null; try { table = createSampleTable(); } catch(MTableException ex) { ex.printStackTrace(); } adapter.setTable(table); grid.setAdapter(adapter); 1 새로 정의한 DataGridView 객체 생성 2 새로 정의한 DataAdapter 객체 생성 3 어댑터에 가상 테이블 객체 설정 Continued.. 6. 그리드뷰 사용하기

66 둘째 마당 – CH4. 선택 위젯의 사용과 커스텀뷰 만들기
7. 복합위젯 만들기

67 복합위젯 만들기 예제 복합위젯 만들기 예제 새로운 클래스를 위한 XML 레이아웃 정의 레이아웃을 상속하여 새로운 클래스 정의
여러 개의 뷰를 포함하는 복합 위젯 새로운 클래스를 위한 XML 레이아웃 정의 레이아웃을 상속하여 새로운 클래스 정의 여러 개의 뷰를 포함하는 새로운 클래스를 위한 레이아웃 정의 여러 개의 뷰를 포함하는 새로운 클래스 정의 메인 액티비티를 위한 XML 레이아웃 정의 메인 액티비티 코드 작성 새로운 클래스 태그 추가 메인 액티비티 코드에서 참조하여 사용 7. 복합위젯 만들기

68 복합위젯 만들기 복합 위젯은 여러 개의 뷰를 조합하여 만든 새로운 위젯
뷰그룹에 여러 개의 뷰를 넣은 후 이벤트 처리 실무에 많이 사용하는 위젯 만들기 방법 날짜와 시간을 함께 선택할 수 있는 DateTimePicker 예제 DatePicker와 TimePicker를 같이 포함한 복합 위젯 7. 복합위젯 만들기

69 날짜/시간 선택기능 위젯 날짜와 시간 설정 위젯 리스너 설정 TimePicker 와 TimePickerDialog
- DatePicker와 TimePicker가 제공되며 대화상자로는 DatePickerDialog 와 TimePickerDialog 제공 - DatePicker 와 DatePickerDialog 를 사용할 때는 시작 일자를 지정할 수 있으며, 그 포맷은 연, 월, 일 (year, month, day) 이 됨. - 월 단위 값은 0부터 11까지 이며 각각 1월부터 12월까지를 표시함 (January –December) 리스너 설정 - 각각의 위젯을 사용자가 선택하면 OnDateChangedListener 또는 OnDateSetListener 콜백 객체가 호출됨. TimePicker 와 TimePickerDialog - 초기 시간을 지정할 수 있으며 그 형태는 0부터 23까지의 시간 (hour :0 - 23) 과 0부터 59까지의 3분(minute : )이 됨. - 선택할 수 있는 값들이 12 시간 모드(AM/PM 토글)인지 또는 24시간 모드인지 지정할 수 있음. - 사용자가 새로운 시간을 선택하면 OnTimeChangedListener 또는OnTimeSetListener 콜백 객체가 호출됨. 7. 복합위젯 만들기

70 시간 선택 위젯을 보일지 여부를 결정하는 체크박스 정의
레이아웃 만들기 <DatePicker android:layout_width="wrap_content" android:layout_height="wrap_content" /> <CheckBox android:text="시간 보이기" <TimePicker 1 날짜 선택 위젯 정의 2 시간 선택 위젯을 보일지 여부를 결정하는 체크박스 정의 3 시간 선택 위젯 정의 7. 복합위젯 만들기

71 레이아웃을 상속한 새로운 클래스 정의 public class DateTimePicker extends LinearLayout { public DateTimePicker(Context context, AttributeSet attrs){ super(context, attrs); LayoutInflater inflater = (LayoutInflater)context.getSystemService (Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.datetimepicker, this, true); Continued.. 7. 복합위젯 만들기

72 레이아웃을 상속한 새로운 클래스 정의 (계속)
timePicker = (TimePicker)findViewById(R.id.timePicker); timePicker.setOnTimeChangedListener(new OnTimeChangedListener() { public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { if(onDateTimeChangedListener != null) { onDateTimeChangedListener.onDateTimeChanged( DateTimePicker.this, datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth(), hourOfDay, minute); } }); Continued.. 7. 복합위젯 만들기

73 레이아웃을 상속한 새로운 클래스 정의 (계속)
public void setOnDateTimeChangedListener(OnDateTimeChangedListener onDateTimeChangedListener) { this.onDateTimeChangedListener = onDateTimeChangedListener; } public void updateDateTime(int year, int monthOfYear, int dayOfMonth, int currentHour, int currentMinute){ datePicker.updateDate(year, monthOfYear, dayOfMonth); timePicker.setCurrentHour(currentHour); timePicker.setCurrentMinute(currentMinute); public void updateDate(int year, int monthOfYear, int dayOfMonth){ ... 5 새로운 리스너 객체 설정 메소드 정의 7. 복합위젯 만들기

74 변경된 날짜와 시간 값을 표시하는 텍스트뷰 추가 새로 정의한 DateTimePicker 뷰 사용을 위해 추가
XML 레이아웃 만들기 <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" > <TextView android:layout_width="match_parent" /> <org.androidtown.ui.composite.DateTimePicker </LinearLayout> 1 변경된 날짜와 시간 값을 표시하는 텍스트뷰 추가 2 새로 정의한 DateTimePicker 뷰 사용을 위해 추가 7. 복합위젯 만들기

75 메인 액티비티 코드 만들기 package org.androidtown.ui.composite; ...
public class MainActivity extends Activity { final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분"); public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final TextView text01 = (TextView)findViewById(R.id.text01); final DateTimePicker dateTimePicker = (DateTimePicker)findViewById(R.id.dateTimePicker); Continued.. 7. 복합위젯 만들기

76 DateTimePicker 객체에 리스너 설정하여 날짜나 시간이 변경될 때마다 텍스트에 표시
메인 액티비티 코드 만들기 (계속) dateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { public void onDateTimeChanged(DateTimePicker view, int year, int monthOfYear, int dayOfYear, int hourOfDay, int minute) { Calendar calendar = Calendar.getInstance(); calendar.set(year, monthOfYear, dayOfYear, hourOfDay, minute); text01.setText(dateFormat.format(calendar.getTime())); } }); calendar.set(dateTimePicker.getYear(), dateTimePicker.getMonth(), dateTimePicker.getDayOfMonth(), dateTimePicker.getCurrentHour(), dateTimePicker.getCurrentMinute()); 1 DateTimePicker 객체에 리스너 설정하여 날짜나 시간이 변경될 때마다 텍스트에 표시 2 텍스트에 현재 날짜와 시간 정보 표시 7. 복합위젯 만들기

77 실행 화면 7. 복합위젯 만들기

78 둘째 마당 – CH4. 선택 위젯의 사용과 커스텀뷰 만들기
8. 월별 캘린더 만들기

79 월별 캘린더 만들기 월별 캘린더는 격자 형태로 그리드뷰를 사용하는 가장 대표적인 뷰
선택 위젯이므로 어댑터를 이용해 7X6 형태의 격자 모양 구성 Date와 Calendar 클래스를 이용해 선택한 월의 정보 확인 1일이 시작되는 요일을 확인하고 끝나는 일수를 확인하는 등의 계산 작업 필요 8. 월별 캘린더 만들기

80 월별 캘린더 만들기 예제 월별 캘린더 만들기 예제 메인 액티비티를 위한 어댑터 클래스 정의 XML 레이아웃 정의
달력 형태로 보여주는 화면 어댑터 클래스 정의 메인 액티비티를 위한 XML 레이아웃 정의 그리드뷰를 위한 어댑터 클래스 정의 그리드뷰 추가 메인 액티비티 코드 작성 메인 액티비티 코드에서 참조하여 사용 8. 월별 캘린더 만들기

81 레이아웃 만들기 <org.androidtown.calendar.month.CalendarMonthView
새로 정의한 월별 캘린더 뷰 추가 <org.androidtown.calendar.month.CalendarMonthView android:layout_width="match_parent" android:layout_height="match_parent" /> 8. 월별 캘린더 만들기

82 그리드뷰를 상속한 새로운 클래스 정의 package org.androidtown.calendar.month;
public class CalendarMonthView extends GridView { private OnDataSelectionListener selectionListener; CalendarMonthAdapter adapter; public CalendarMonthView(Context context) { super(context); init(); } public CalendarMonthView(Context context, AttributeSet attrs) { super(context, attrs); 1 그리드뷰를 상속하여 클래스 정의 Continued.. 8. 월별 캘린더 만들기

83 그리드뷰를 상속한 새로운 클래스 정의 (계속)
private void init() { setBackgroundColor(Color.GRAY); setVerticalSpacing(1); setHorizontalSpacing(1); setStretchMode(GridView.STRETCH_COLUMN_WIDTH); setNumColumns(7); setOnItemClickListener(new OnItemClickAdapter()); } ... 2 뷰를 초기화하는 메소드를 만들고 그 안에서 칼럼의 개수 설정 8. 월별 캘린더 만들기

84 어댑터 클래스 정의 package org.androidtown.calendar.month; ...
public class CalendarMonthAdapter extends BaseAdapter { public CalendarMonthAdapter(Context context) { super(); mContext = context; init(); } public CalendarMonthAdapter(Context context, AttributeSet attrs) { 1 BaseAdapter를 상속하여 새로운 어댑터 정의 Continued.. 8. 월별 캘린더 만들기

85 어댑터 클래스 정의 (계속) public View getView(int position, View convertView, ViewGroup parent) { MonthItemView itemView; if (convertView == null) { itemView = new MonthItemView(mContext); } else { itemView = (MonthItemView) convertView; } GridView.LayoutParams params = new GridView.LayoutParams( GridView.LayoutParams.MATCH_PARENT, 70); int rowIndex = position / countColumn; int columnIndex = position % countColumn; Continued.. 8. 월별 캘린더 만들기

86 둘째 마당 – CH4. 선택 위젯의 사용과 커스텀뷰 만들기
9. 멀티터치 이미지뷰어 만들기

87 멀티터치 이벤트 처리하기 – X, Y 좌표 [API] public final int getPointerCount ()
public final float getX(int pointerIndex) public final float getY(int pointerIndex) 첫 번째 메소드인 getPointerCount()는 몇 개의 손가락이 터치되었는지를 알 수 있도록 해주는 것 이벤트 처리에 자주 사용되는 getX()와 getY() 메소드는 손가락이 하나일 때 X와 Y의 좌표값을 가져오지만 getX(int pointerIndex)와 getY(int pointerIndex) 메소드는 여러 개의 손가락이 터치되었을 때 각각의 손가락이 가지는 인덱스의 값을 이용해 좌표값을 확인할 수 있도록 함 9. 멀티터치 이미지뷰어 만들기

88 멀티터치 이미지뷰어 예제 멀티터치 이미지뷰어 만들기 예제 새로운 뷰 클래스 정의 메인 액티비티 코드 작성
멀티터치로 이미지를 조작하는 기능 새로운 뷰 클래스 정의 메인 액티비티 코드 작성 멀티터치 이벤트를 처리하는 새로운 뷰 클래스 정의 메인 액티비티 코드에서 참조하여 사용 9. 멀티터치 이미지뷰어 만들기

89 새로운 뷰 클래스 정의 public class ImageDisplayView extends View implements OnTouchListener { protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (w > 0 && h > 0) { newImage(w, h); redraw(); } protected void onDraw(Canvas canvas) { if (mBitmap != null) { canvas.drawBitmap(mBitmap, 0, 0, null); ... public boolean onTouch(View v, MotionEvent ev) { final int action = ev.getAction(); 1 뷰를 상속하면서 OnTouchListener 인터페이스를 구현하는 클래스 정의 2 뷰가 초기화되고 나서 화면에 보이기 전 크기가 정해지면 호출되는 메소드 안에서 메모리 상에 새로운 비트맵 객체 생성 3 뷰가 화면에 그려지는 메소드 안에서 메모리 상의 비트맵 객체 그리기 4 뷰를 터치할 때 호출되는 메소드 다시 정의 Continued.. 9. 멀티터치 이미지뷰어 만들기

90 터치했을 때 몇 개의 손가락으로 터치하는지 개수 확인
새로운 뷰 클래스 정의 (계속) int pointerCount = ev.getPointerCount(); Log.d(TAG, "Pointer Count : " + pointerCount); switch (action) { case MotionEvent.ACTION_DOWN: if (pointerCount == 1) { float curX = ev.getX(); float curY = ev.getY(); startX = curX; startY = curY; } else if (pointerCount == 2) { oldDistance = 0.0F; isScrolling = true; } return true; 5 터치했을 때 몇 개의 손가락으로 터치하는지 개수 확인 6 손가락으로 눌렀을 때의 기능 추가 Continued.. 9. 멀티터치 이미지뷰어 만들기

91 새로운 뷰 클래스 정의 (계속) case MotionEvent.ACTION_MOVE:
if (pointerCount == 1) { if (isScrolling) { return true; } float curX = ev.getX(); float curY = ev.getY(); if (startX == 0.0F) { startX = curX; startY = curY; float offsetX = startX - curX; float offsetY = startY - curY; if (oldPointerCount == 2) { } else { Log.d(TAG, "ACTION_MOVE : " + offsetX + ", " + offsetY); if (totalScaleRatio > 1.0F) { 7 손가락으로 움직일 때의 기능 추가 Continued.. 9. 멀티터치 이미지뷰어 만들기

92 한 손가락으로 움직이고 있을 때는 moveImage() 메소드 호출
새로운 뷰 클래스 정의 (계속) moveImage(-offsetX, -offsetY); } startX = curX; startY = curY; } else if (pointerCount == 2) { float x1 = ev.getX(0); float y1 = ev.getY(0); float x2 = ev.getX(1); float y2 = ev.getY(1); float dx = x1 - x2; float dy = y1 - y2; float distance = FloatMath.sqrt(dx * dx + dy * dy); float outScaleRatio = 0.0F; if (oldDistance == 0.0F) { oldDistance = distance; break; 8 한 손가락으로 움직이고 있을 때는 moveImage() 메소드 호출 Continued.. 9. 멀티터치 이미지뷰어 만들기

93 두 손가락으로 움직이고 있을 때는 scaleImage() 메소드 호출
새로운 뷰 클래스 정의 (계속) scaleImage(outScaleRatio); } oldDistance = distance; oldPointerCount = pointerCount; break; case MotionEvent.ACTION_UP: if (pointerCount == 1) { float curX = ev.getX(); float curY = ev.getY(); float offsetX = startX - curX; float offsetY = startY - curY; if (oldPointerCount == 2) { } else { moveImage(-offsetX, -offsetY); 9 두 손가락으로 움직이고 있을 때는 scaleImage() 메소드 호출 10 손가락을 떼었을 때의 기능 추가 Continued.. 9. 멀티터치 이미지뷰어 만들기

94 새로운 뷰 클래스 정의 (계속) } else { isScrolling = false; } return true;
private void scaleImage(float inScaleRatio) { Log.d(TAG, "scaleImage() called : " + inScaleRatio); mMatrix.postScale(inScaleRatio, inScaleRatio, bitmapCenterX, bitmapCenterY); mMatrix.postRotate(0); totalScaleRatio = totalScaleRatio * inScaleRatio; redraw(); 11 매트릭스 객체를 이용해 이미지 크기 변경 Continued.. 9. 멀티터치 이미지뷰어 만들기

95 새로운 뷰 클래스 정의 (계속) private void moveImage(float offsetX, float offsetY) { Log.d(TAG, "moveImage() called : " + offsetX + ", " + offsetY); mMatrix.postTranslate(offsetX, offsetY); redraw(); } 12 매트릭스 객체를 이용해 이미지 이동 9. 멀티터치 이미지뷰어 만들기

96 postScale() 메소드 [API] public boolean postScale (float sx, float sy, float px, float py) public boolean postTranslate (float dx, float dy) public boolean postRotate (float degrees) postScale() 메소드를 이용하면 비트맵 이미지를 확대 또는 축소할 수 있으며, 첫 번째 파라미터는 X축을 기준으로 확대하는 비율, 두 번째 파라미터는 Y축을 기준으로 확대하는 비율을 의미함 세 번째와 네 번째 파라미터는 확대 또는 축소할 때 기준이 되는 위치가 되는데 일반적으로는 비트맵 이미지의 중심점을 지정함 postTranslate() 메소드는 비트맵 이미지를 이동시킬 때 사용함 postRotate() 메소드는 비트맵 이미지를 회전시킬 때 사용함 9. 멀티터치 이미지뷰어 만들기

97 XML 레이아웃에 정의한 리니어 레이아웃 객체 참조
메인 액티비티 코드 만들기 package org.androidtown.events.multitouch; ... public class MainActivity extends Activity { LinearLayout viewerContainer; ImageDisplayView displayView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } private void init() { viewerContainer = (LinearLayout) findViewById(R.id.viewerContainer); Bitmap sourceBitmap = loadImage(); if (sourceBitmap != null) { 1 XML 레이아웃에 정의한 리니어 레이아웃 객체 참조 Continued.. 9. 멀티터치 이미지뷰어 만들기

98 메인 액티비티 코드 만들기 (계속) displayView = new ImageDisplayView(this);
displayView.setImageData(sourceBitmap); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); viewerContainer.addView(displayView, params); } private Bitmap loadImage() { Resources res = getResources(); Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.beach); return bitmap; 2 새로 정의한 ImageDisplayView 객체 생성 3 addView()를 이용해 리니어 레이아웃 객체에 ImageDisplayView 객체 추가 9. 멀티터치 이미지뷰어 만들기

99 실행 화면 9. 멀티터치 이미지뷰어 만들기

100 디버깅 메시지 확인하기 [두 손가락으로 터치할 때의 좌표값 디버깅] 9. 멀티터치 이미지뷰어 만들기

101 참고 문헌 [ References] References 기본 서적
2015, 정재곤, “Do it! 안드로이드 앱 프로그래밍(개정2판)”, 이지스퍼블리싱(주) Android Website Google Developer’s Conference Android SDK Documentation References


Download ppt "○ 본 강의 자료는 이지스퍼블리싱(주)에서 제공하는 강의 교안입니다."

Similar presentations


Ads by Google