'Android > 대세는 허니컴' 카테고리의 다른 글
[팁]리스트뷰로 왔을때 선택하기 (0) | 2011.09.15 |
---|---|
[펌]허니컴 관련 Drop and Drop (HoneyComb) (0) | 2011.08.26 |
허니컴 관련 추천 블로그 (0) | 2011.08.13 |
[펌:커니의 안드로이드] (0) | 2011.08.05 |
[펌:커니의 안드로이드]허니컴의 바뀐 액션바 기초 #1 (0) | 2011.08.05 |
[팁]리스트뷰로 왔을때 선택하기 (0) | 2011.09.15 |
---|---|
[펌]허니컴 관련 Drop and Drop (HoneyComb) (0) | 2011.08.26 |
허니컴 관련 추천 블로그 (0) | 2011.08.13 |
[펌:커니의 안드로이드] (0) | 2011.08.05 |
[펌:커니의 안드로이드]허니컴의 바뀐 액션바 기초 #1 (0) | 2011.08.05 |
허니콤 관련 PT 자료 (0) | 2011.11.21 |
---|---|
[펌]허니컴 관련 Drop and Drop (HoneyComb) (0) | 2011.08.26 |
허니컴 관련 추천 블로그 (0) | 2011.08.13 |
[펌:커니의 안드로이드] (0) | 2011.08.05 |
[펌:커니의 안드로이드]허니컴의 바뀐 액션바 기초 #1 (0) | 2011.08.05 |
If you are thinking about developing an Android tablet app, one of the most exciting things has got to be the drag and drop capabilities that were added to Android as part of Honeycomb. No wait a minute, aren't there a lot more interesting features than drag and drop in Honeycomb? There are definitely a lot of great features, but drag and drop is one of the most interesting in my opinion. It's a perfect fit for tablets, where you can have this nice big graphical objects to drag and drop. I think it really challenges mobile designers and developers to rethink our interaction models. If you read through that tutorial I just linked to, you will learn about many of the intricacies of drag and drop Android style. I thought I'd provide an even simpler example for those of you who prefer the Cliff Notes versions of things.
First we will start with a simple UI, a 2x2 grid with a cute little image that we will drag and drop around this grid. Here is what it looks like:
I used a simple TableLayout for this, along with some basic border background Drawables. Here's the XML for it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 |
< TableLayout android:layout_width = "match_parent" android:layout_height = "match_parent" > < TableRow > < LinearLayout android:layout_width = "640px" android:layout_height = "345px" android:id = "@+id/topLeft" android:background = "@drawable/border" > < ImageView android:id = "@+id/droid" android:src = "@drawable/bugdroid" android:layout_width = "150px" android:layout_height = "150px" /> </ LinearLayout > < LinearLayout android:layout_width = "640px" android:layout_height = "345px" android:id = "@+id/topRight" android:background = "@drawable/border2" /> </ TableRow > < TableRow > < LinearLayout android:layout_width = "640px" android:layout_height = "345px" android:id = "@+id/bottomLeft" android:background = "@drawable/border2" /> < LinearLayout android:layout_width = "640px" android:layout_height = "345px" android:id = "@+id/bottomRight" android:background = "@drawable/border" /> </ TableRow > </ TableLayout > |
Nothing special so far. All of the magic happens in the code. Here's the basics of the Activity that uses this XML.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 |
public class DndActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.grid); View droid = findViewById(R.id.droid); droid.setOnLongClickListener( new OnLongClickListener(){ @Override public boolean onLongClick(View v) { ClipData data = ClipData.newPlainText( "foo" , "bar" ); DragShadowBuilder shadowBuilder = new DragShadowBuilder(); v.startDrag(data, shadowBuilder, v, 0 ); return true ; } }); findViewById(R.id.topLeft).setOnDragListener( new BoxDragListener()); findViewById(R.id.bottomLeft).setOnDragListener( new BoxDragListener()); findViewById(R.id.topRight).setOnDragListener( new BoxDragListener()); findViewById(R.id.bottomRight).setOnDragListener( new BoxDragListener()); } } |
Here we just set the contentView, then we get a handle on the droid image. We set its onLongClickListener. I think the long click will become the de facto way to initiate drag and drop in Android apps. You could use some other event of course, but long click feels right. The key thing we need to do to initiate drag and drop is invoke the startDrag method. To do that, we have to create a ClipData object and DragShadowBuilder. You can use the ClipData to put all kinds of interesting data/metadata that will be passed around to the drop zones (Views) in your app. In this case I didn't need anything fancy, so I put something minimal and arbitrary. For the DragShadowBuilder, you might want to do something fancy to make the dragging look cool. I used a default one and it doesn't do much at all. You also need to set a "localData" object. This can be anything. Since my local data is the image itself, I chose to pass the ImageView that will be passed in to the onLongClick method. Now you can call startDrag. Finally, make sure you return true to let the OS know that drag and drop is a go.
Next in the code you will see that for each of the cells in my table, I have set an OnDragListener object. I've set this to a new instance of BoxDragListener for each of the cells. This is an inner class of DndActivity:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 |
class BoxDragListener implements OnDragListener{ boolean insideOfMe = false ; Drawable border = null ; Drawable redBorder = getResources().getDrawable(R.drawable.border3); @Override public boolean onDrag(View self, DragEvent event) { if (event.getAction() == DragEvent.ACTION_DRAG_STARTED){ border = self.getBackground(); self.setBackgroundDrawable(redBorder); } else if (event.getAction() == DragEvent.ACTION_DRAG_ENTERED){ insideOfMe = true ; } else if (event.getAction() == DragEvent.ACTION_DRAG_EXITED){ insideOfMe = false ; } else if (event.getAction() == DragEvent.ACTION_DROP){ if (insideOfMe){ View view = (View) event.getLocalState(); ViewGroup owner = (ViewGroup) view.getParent(); owner.removeView(view); LinearLayout container = (LinearLayout) self; container.addView(view); } } else if (event.getAction() == DragEvent.ACTION_DRAG_ENDED){ self.setBackgroundDrawable(border); } return true ; } } |
This guy will get a stream of DragEvents fired at its onDrag method. You can determine what kind of DragEvent it is by calling getAction on the event. The first one you will get is an ACTION_DRAG_STARTED event. For this we want to change the border of our cell to red to let the user know that they can drop the image in this cell. Here's what that looks like:
Next we want to keep track if the user's finger has entered into a drop zone. So we look for the ACTION_DRAG_ENTERED and toggle a local boolean. Similarly, we look for ACTION_DRAG_EXITED in case the user changed their mind and picked a different zone to drop the image into. Next we look for the ACTION_DROP. If the object is inside our drop zone, then we update the UI by removing it from its previous parent and adding it to the drop zone. Finally, we listen for ACTION_DRAG_ENDED to know when the drag and dropping is finished. We then restore the borders to their original color. That's it!
Update: The code above will not draw a shadow when you drag the image around the screen. There is a very easy way to get a shadow and that is to pass the View to it the DragShadowBuilder constructor, i.e. new DragShadowBuilder(v); in the above code. That will cause the image in the sample app to be used as the shadow. Be careful using this technique though. If the View that you are dragging is big/complex, then you might take a performance hit (UI becomes sluggish.) In that case you might want to subclass DragShadowBuilder and override its onDragShadow method to draw something simpler for the shadow. I've been playing around with this and StackViews however, and it has worked great with no need to subclass DragShadowBuilder. Be sure to set the android:hardwareAccelerated="true" attribute in your AndroidManifest.xml either on the Activity or the whole Application
허니콤 관련 PT 자료 (0) | 2011.11.21 |
---|---|
[팁]리스트뷰로 왔을때 선택하기 (0) | 2011.09.15 |
허니컴 관련 추천 블로그 (0) | 2011.08.13 |
[펌:커니의 안드로이드] (0) | 2011.08.05 |
[펌:커니의 안드로이드]허니컴의 바뀐 액션바 기초 #1 (0) | 2011.08.05 |
[팁]리스트뷰로 왔을때 선택하기 (0) | 2011.09.15 |
---|---|
[펌]허니컴 관련 Drop and Drop (HoneyComb) (0) | 2011.08.26 |
[펌:커니의 안드로이드] (0) | 2011.08.05 |
[펌:커니의 안드로이드]허니컴의 바뀐 액션바 기초 #1 (0) | 2011.08.05 |
[펌]The Android 3.0 Fragments API (0) | 2011.08.04 |
애플리케이션 흐름을 알려주는 액션바의 요소들
API
public abstract void setDisplayHomeAsUpEnabled (boolean showHomeAsUp)
액션바 아이콘을 업 네비게이션 형태로 표시합니다.
API
public abstract void setNavigationMode(int mode)
액션바의 네비게이션 모드를 설정합니다.
API
public abstract void addTab(ActionBar.Tab)
액션바에 탭을 추가합니다.
액션바 모습 변경하기
API
public abstract void setDisplayUseLogoEnabled(boolean enabled)
액션바의 로고 표시유무를 설정합니다.
API
public abstract void setDisplayShowTitleEnabled(boolean enabled)
액션바에 표시되는 제목의 표시유무를 설정합니다.
[팁]리스트뷰로 왔을때 선택하기 (0) | 2011.09.15 |
---|---|
[펌]허니컴 관련 Drop and Drop (HoneyComb) (0) | 2011.08.26 |
허니컴 관련 추천 블로그 (0) | 2011.08.13 |
[펌:커니의 안드로이드]허니컴의 바뀐 액션바 기초 #1 (0) | 2011.08.05 |
[펌]The Android 3.0 Fragments API (0) | 2011.08.04 |
액션바를 표시하려면?
액션바와 메뉴(OptionsMenu), 그리고 액션 아이템(Action item)
1.
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
2.
<
menu
xmlns:android
=
"http://schemas.android.com/apk/res/android"
>
3.
<
item
android:id
=
"@+id/menu_add"
4.
android:icon
=
"@drawable/ic_menu_save"
5.
android:title
=
"@string/menu_save"
6.
android:showAsAction
=
"ifRoom|withText"
/>
7.
</
menu
>
액션바 감 잡아보기
01.
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
02.
<
menu
xmlns:android
=
"http://schemas.android.com/apk/res/android"
>
03.
<
item
04.
android:showAsAction
=
"ifRoom|withText"
05.
android:id
=
"@+id/item1"
06.
android:icon
=
"@android:drawable/ic_menu_add"
07.
android:title
=
"Add"
08.
/>
09.
<
item
10.
android:id
=
"@+id/item2"
11.
android:showAsAction
=
"always"
12.
android:title
=
"Action item with icon"
13.
android:icon
=
"@android:drawable/ic_menu_search"
14.
/>
15.
<
item
16.
android:title
=
"Normal item"
17.
android:id
=
"@+id/item3"
18.
/>
19.
</
menu
>
01.
@Override
02.
public
boolean
onCreateOptionsMenu(Menu menu) {
03.
getMenuInflater().inflate(R.menu.menu, menu);
04.
return
true
;
05.
}
06.
@Override
07.
public
boolean
onOptionsItemSelected(MenuItem item) {
08.
String text =
null
;
09.
10.
switch
(item.getItemId()){
11.
case
android.R.id.home:
12.
text =
"Application icon"
;
13.
break
;
14.
15.
case
R.id.item1:
16.
text =
"Action item, with text, displayed if room exists"
;
17.
break
;
18.
19.
case
R.id.item2:
20.
text =
"Action item, icon only, always displayed"
;
21.
break
;
22.
23.
case
R.id.item3:
24.
text =
"Normal menu item"
;
25.
break
;
26.
27.
default
:
28.
return
false
;
29.
}
30.
Toast.makeText(
this
, text, Toast.LENGTH_SHORT).show();
31.
return
true
;
32.
}
[팁]리스트뷰로 왔을때 선택하기 (0) | 2011.09.15 |
---|---|
[펌]허니컴 관련 Drop and Drop (HoneyComb) (0) | 2011.08.26 |
허니컴 관련 추천 블로그 (0) | 2011.08.13 |
[펌:커니의 안드로이드] (0) | 2011.08.05 |
[펌]The Android 3.0 Fragments API (0) | 2011.08.04 |
The Android 3.0 Fragments API[이 포스트는 안드로이드 개발에 핵심적인 역할을 담당하는, 소프트웨어 엔지니어 Dianne Hackborn 에 의해 작성되었습니다. - Tim Bray]원문: http://android-developers.blogspot.com/2011/02/android-30-fragments-api.html
안드로이드 3.0 의 주요 목표 중 하나는, 개발자들이 보다 쉽게 다양한 해상도를 지원하는 어플리케이션을 작성할 수 있도록 만들어 주는 것 입니다. 다양한 해상도를 지원하는 어플리케이션을 개발 할 수 있도록, 지금까지 안드로이드 플랫폼에서는 다음과 같은 기능을 지원해 주고 있었습니다.
레이아웃 메니저와 화면 크기에 따라 유연하게 동작하는 리소스 선택 시스템은 '개발자들이 다양한 크기의 안드로이드 디바이스에서 자연스럽게 동작하는 어플리케이션을 만들 수 있게 하자' 는 원대한 목표하에서 구현되었습니다. 그리고 결과적으로, 다행스럽게도 기존에 개발된 많은 어플리케이션이 최근 새롭게 발표된 10인치 크기의 타블렛용 OS 인 허니콤 상에서 별다른 문제 없이 '잘' 동작하는 것으로 확인되고 있습니다. 하지만, 허니콤이 공개되고 타블렛을 위해 UI 요소에 많은 변화가 생김에 따라, 안드로이드 개발팀은 '만일 기존 어플리케이션이 10인치의 타블렛을 위해 고안된 새로운 UI 요소들을 손 쉽게 활용 할 수 있다면 여러가지 추가적인 장점을 누릴 수 있지 않을까' 고민하게 되었습니다. 그 결과, Fragment 클래스가 추가되었습니다. Introducing the Fragment
어플리케이션 개발자는 안드로이드 3.0 에서 새롭게 추가된 Fragment 클래스를 이용하여 어플리케이션의 UI 를 보다 상황에 따라 변경하거나 조절할 수 있습니다. Fragment 는 별도의 UI 와 생명주기를 갖는 독립된 어플리케이션 컴포넌트입니다. 따라서, 여러분은 특정 디바이스 혹은 스크린 해상도에 따라서, 여러 개의 Fragment 를 조합하거나 재배치 하는 방식으로 원하는 UI 를 손쉽게 구성할 수 있습니다.
다시말해, Fragment 는 미니 엑티비티라고 생각하실 수 있습니다. 일반적인 엑티비티와는 다르게, 반드시 실재 엑티비티에 포함되어 동작해야 되긴 하지만 말이지요. 안드로이드 개발팀은 Fragment 관련 기능을 추가하면서, 어플리케이션 개발자들이 엑티비티를 사용할 때 겪게 되는 일반적인 불편함에 대해 다시 살펴보고 이를 해결할 수 있는 방안을 검토했으며, 그 결과 개발된 Fragment API 는 그저 다양한 해상도나 화면 모드에 따라 UI 를 변경하는 기능 이상의 역할을 수행 할 수 있습니다.
Getting started
Fragment 에 대한 여러분의 궁금증을 달래기 위해, 이를 활용하여 화면 모드에 따라서 UI 가 완전히 변화되는 어플리케이션을 만들기 위한 샘플 코드를 설명해 볼까 합니다. 우선, 화면이 랜드스케이프(가로) 모드일 때, 화면 왼쪽에 아이템 목록이 표시되고, 오른편에는 선택된 아이템의 상세 정보가 표시되는 레이아웃을 디자인 해 보도록 하겠습니다.
이런 엑티비티를 위한 코드는 별 다를게 없습니다. 그저, onCreate() 시점에 setContentView() 메서드를 호출하여, 아래의 레이아웃 코드를 설정해주면 됩니다.
레이아웃 코드를 살펴 보시면, 새롭게 추가된 <fragment> 태그를 확인 할 수 있습니다. 이 태그를 사용하면 프레임워크에서 자동적으로 Fragment 인스턴스를 생성하고, 생성된 Fragment 인스턴스를 엑티비티 View 계층 구조 안에 삽입합니다. 여기서 사용된 Fragment 는 ListFragment 를 상속받아 작성되었으며 아이템 목록을 관리하고 화면상에 출력합니다.
구현 내용을 살펴보시면, UI 레이아웃 상에, 선택된 아이템의 상세 정보를 표시할 수 있는 'details' 라는 ID 의 View 가 존재하는지 여부에 따라, 상세 정보를 현재 엑티비티 내에서 모두 표현할지, 아니면 별도의 엑티비티를 호출하여 표현할지 구분되어 구현되어있음을 확인 하실 수 있습니다. 또, Fragment 인스턴스의 정보는 프레임워크 내에서 자동으로 저장 관리되기 때문에, newInstance() 메서드를 통해 생성된 DetailsFragment 인스턴스를 별다른 관리 없이 FragmentManager 의 findFragmentById 메서드를 통해 재활용해 사용하고 있습니다.
선택된 아이템 상세 정보를 표현하기 위한 Details첫 화면을 위해서 DetailsFragment 는 주어진 문자열을 TextView 로 출력하는 역할을 수행합니다. 다음과 같이 간단하게 구현할 수 있습니다.
이제, 추가로 화면이 포트레이트 (세로) 모드일 때를 위한 새로운 UI 를 구성해 보겠습니다. 새로 모드의 경우, 두 개의 Fragment 를 나란히 배치할 공간이 부족하니, 이 경우에는 오직 아이템 목록만을 보여주고, 사용자가 아이템을 클릭하면 별도의 엑티비티에서 상세 정보를 보여주고자 합니다.
사실 이 작업은, 지금까지 작성해둔 코드를 활용하면, 포트레이트 모드를 위하여 아래와 같은 레이아웃을 선언하면 끝입니다.
위 구현내용을 살펴보시면 알 수 있듯이, TitleFragment 는 아이템 상세 정보를 표시하기 위한 'details' ID 를 갖는 View 가 없는 경우 단지 아이템 목록만을 표시하고, 여러분 하나의 아이템을 선택할 때, 해당 아이템의 상세 정보를 담은 새로운 엑티비티를 표시하게 될 것 입니다.
이미 상세 정보를 출력하기 위해 DetailsFragment 를 구현하였기 때문에, 새로운 엑티비티도 손쉽게 작성할 수 있습니다.
작업이 완료되었습니다. 우리는 새로운 Fragment API 를 이용하여, 화면 모드가 변함에 따라 UI 플로우가 완전히 변경되는 온전한 어플리케이션 예제를 만들었습니다.
지금까지 예제를 통해 Fragment 를 활용하여 UI 를 변경할 수 있는 한 가지 방법을 설명했습니다. 여러분의 어플리케이션 디자인에 따라서, 다양한 방식으로 이를 활용할 수도 있습니다. 예를 들어, 여러분은 전체 어플리케이션을 하나의 엑티비티에 담고, 엑티비티의 상태가 변함에 따라 내부 Fragment 의 구조만을 변경하는 방식으로 어플리케이션을 작성할 수도 있을 것 입니다. 이런경우, Fragment 가 자체적으로 'back-stack' 을 유지하고 있다는 사실이 큰 도움이 될 것 입니다.
Fragment 와 FragmentManager API 에 관한 보다 상세한 정보는 안드로이드 3.0 SDK 문서에서 살펴보시거나, 리소스 항목 아래에 있는 ApiDemos 를 참조해 보셔도 좋습니다. 안드로이드 개발팀은 자유롭게 변환되는 UI 플로우, Fragment 다이얼로그, 리스트, 메뉴 생성, 엑티비티 인스턴스간에 Fragment 인스턴스를 유지하기, 'back-stack' 등등 다양한 예제 코드를 마련해 두었습니다.
Fragmentation for all!
안드로이드 3.0 기반의 태블릿 용 어플리케이션 개발자들은 새로운 Fragment API 를 이용하여, 큰 화면에 따른 다양한 UI 설계 문제를 보다 잘 처리하실 수 있을 것 입니다. 거기에 덧붙여 만일에, Fragment 를 잘 활용한다면, 향후 등장할 새로운 안드로이드 디바이스 - 휴대폰, TV 등등 에 맞추어 여러분의 어플리케이션 UI 를 쉽게 변경할 수 있을 것 입니다.
하지만, 바로 오늘 이 순간에는 많은 개발자들이 현재 존재하는 휴대폰 용 어플리케이션을 작성하고 있으며, 해당 어플리케이션이 타블렛 상에서는 보다 향상된 UI 요소를 활용할 수 있으면 얼마나 좋을까... 하고 생각하고 계실 것 입니다. 현재 Fragment API 가 오직 안드로이드 3.0 에서만 지원되고 있다는 사실을 생각해보면, 이는 참으로 안타까운 일 입니다.
이런 문제를 해결하기 위하여, 안드로이드 개발팀은 이 포스트에서 이야기한 Fragment API 를 기존의 안드로이드 플랫폼에서도 활용 할 수 있도록 Static 라이브러리 형태로 제공할 예정입니다. 현재 계획으로는 1.6 이후의 모든 플랫폼을 지원하고자 하며, 사실 여러분이 이 포스트에서 사용된 코드는 바로 그러한 Static 라이브러리를 활용하여 작성되었습니다. 눈치가 빠른 분들이라면 스크린샷으로도 확인하실 수 있었겠지요. 현재, 우리의 목표는 Static 라이브러리에서 제공하는 API 와 안드로이드 3.0 플랫폼에서 제공하는 API 를 최대한 동일하게 만드는 것이며, 여러분이 지금 즉시 Fragment API 를 활용하고, 향후 안드로이드 3.0 을 사용하실 때도, 기존 어플리케이션 코드를 거의 변경하지 않고 적용할 수 있도록 만들고자 합니다.
Fragment API 를 위한 Static 라이브러리를 제공하는 날짜가 아직 확정되지는 않았지만, 생각보다 이른 시간내에 공개할 것이라고는 말씀드릴 수 있습니다. 그 사이에 여러분은 안드로이드 3.0 SDK 를 이용하여 Fragment API 를 어떤식으로 활용할 수 있는지 테스트해보실 수 있으며, 그 노력은 결코 헛되지 않을 것 입니다. |
[팁]리스트뷰로 왔을때 선택하기 (0) | 2011.09.15 |
---|---|
[펌]허니컴 관련 Drop and Drop (HoneyComb) (0) | 2011.08.26 |
허니컴 관련 추천 블로그 (0) | 2011.08.13 |
[펌:커니의 안드로이드] (0) | 2011.08.05 |
[펌:커니의 안드로이드]허니컴의 바뀐 액션바 기초 #1 (0) | 2011.08.05 |