Introducing Fragments


Published on

Published in: Technology, News & Politics
1 Like
  • Be the first to comment

No Downloads
Total Views
On Slideshare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Starting from Android 1.6 and up developers can divide the Activities of their applications into subcomponents called Fragments. Fragments -- can be added, removed, replaced, and animated inside an Activity dynamically -- are modular and reusable across multiple Activities. Here we’ve got the updated version of the contacts app showing the list of contacts in a fragment on the left and the details of the selected contact in a fragment on the right.
  • Figure out what you want your fragments to look like on different size screens and different orientations on those screens. Take advantage of the qualifiers for size and layout. Think about your use-cases. Tablet experience is very different than smartphone experience
  • So this my dual pane application build against Android 3.0. Two layouts (landscape and portrait) each with two panes.
  • In each case we start with 2 fragments inside an activity. As I mentioned earlier, fragments cannot live outside an Activity. When you run your application the main activity will load the main resource file (main.xml) that defines the layout for the entire application. You then attach fragments together with findFragmentId(). In this case we are attaching the detail fragment to the listFragment.
  • So how do you get this with Honeycomb. This is a pretty broad brush list but it should point you in the right direction. For each fragment you’ll need to create a new class. You can do this inside one java file or create separate java files for each class. You need to import (as well as FragmentManager). The fragments extend the Fragment class instead of the Activity class. Then add your lifecycle calls. Next you should create resource files for each fragment defining the layout for that fragment. You’ll add the fragments to the application by adding the fragment tag to the applications XML file. Remember to give it an ID. Lastly you’ll update your main Activity by first importing the fragment package. You then load the application UI with findViewById() – same as you’ve always done. To communicate with the fragment you’ll call findFragmentById() and give it the ID you defined for that fragment. In our example we daisy chain the fragments so the listFragment communicates with the content fragment with a call to findFragmentId() from the list.
  • So this is what your Android project would look like after you’re done creating a dual pane layout with fragments using Android 3.0. You’ll have your main activity along with 2 or more fragments. In your resource folder you’ll have a layout for landscape and portrait (if you want it to look differently). Your layout for the application as a whole is still defined in your main.xml and each fragment then has their UI defined in their own XML files. The difference in layouts between landscape and portrait is mainly the direction the fragments are displayed in.
  • So lets walk through the code. The file is your activity. I’ve defined FragmentsHCDemo to extend Activity. In the onCreate() I call setContentView() with the activities layout file. This loads the resource file that contains the <fragment> definitions. The fragments are instantiated as soon as the activity loads the layout.
  • The layout file itself has a LinearLayout as it’s container and 2 <fragment> tags, each one defining the class name of the fragment as well as the properties of the fragment. This is the layout file for the landscape mode so I need to specify the orientation to be horizontal. Otherwise the LinearLayout defaults to top-to-bottom. So take a look at the properties for the first fragment – my list fragment. It has an id, followed by a layout_width (which in landscape mode is 200dp) and layout_height (which is set to match the parent).
  • If we look at the portrait version of that layout file there are a few things that change. First the orientation is now vertical (or top-to-bottom). The width and height of the list also need to be reversed. If I had left it alone the list would have expanded to fill the parent and there would be no room for the detail fragment.
  • There are 2 fragment files. This is the listFragment. As you can see we need to extend the ListFragment. There’s also a new set of lifecycle calls for fragments, one of which is onActivityCreated(). This is called after the main activity has completed it’s onCreate() call. In here we create a list adapter the same way you would inside an activity. Along with that list adapter you need a callback to handle selecting each list item which we’ve done with onListItemClick(). This is where you need to attach to your detail fragment. Each time we select something from the list a call is made to findFragmentById() and we pass in the id of the detail fragment that was defined in the main.xml file. Once we’ve located it, we then call into the detail fragment to update the image.
  • Then if we look at the detail fragment, you are extending a Fragment, calling one of the other new lifecycle calls for fragments – onCreateView(), inflating the layout for that detail fragment, and setting the initial image. Below that is the routine to update the image every time a list item is selected. You are passing in the position of the selected list item, locating the appropriate drawable, and setting the ImageView to that drawable.
  • The layout files for each of the fragments is pretty straightforward. The listFragment only defines the textView for the items in the list. The detail fragment uses a FrameLayout as it’s container and defines an ImageView to hold the images.
  • So you’ve got this big screen and you want to take advantage of it with fragments. You can use the same views and viewgroups in a fragment that you use in an Activity. You don’t have to use a listFragment; you can have two fragments side-by-side. Be creative.
  • Don’t need a resource file since there is no UI Don’t need a fragment tag in the main activity either. However without that definition there is no longer an id associated with the fragment so you’ll need to use a “tag” to get to that fragment. Easier than using the raw Activity.onRetainNonConfigurationInstance() API
  • Programmatically, you still define your fragment by extending a Fragment. Then (working from the bottom up) the first time you need to use that fragment you would have to instantiate it with a call to new(). You would then attach to that fragment with a call to “add” and supply a name, or tag, for that fragment. Since it’s considered a transaction you need to surround it with beginTransaction() and commit(). Thereafter you can locate that fragment with a call to findFragmentByTag() supplying the name you gave it when you first added it.
  • So let’s say you want your app to look like this in landscape mode on ANY device (this happens to be on a XOOM)
  • And you want it to look like this in portrait mode (this happens to be an ATRIX)
  • To get your dual pane it’s pretty much the same logic as it is on Android 3.0. You need a main activity but in the Compatibility library it’s now called a “FragmentActivity”. You still need to create each fragment by subclassing the appropriate fragment type. You still need to define a UI for each fragment. And you still need to add a fragment tag to the main activities layout file. A call to findFragmentId() is used to locate and perform any operations on that fragment.
  • Single pane logic (for instance for portrait) gets interesting. First of all this way of displaying fragments is based on the orientation. So you’ll need to check whether you’re in portrait mode or not. If so instead of calling findFragmentById() from the listFragment you’ll start a new activity for the detail by way of intents. Since fragments can’t live outside of an Activity you need to define a FragmentActivity for each fragment.
  • In the end this is what your project will contain. You’ll have two FragmentActivites and two fragments. The main activity locates fragment1 with findFragmentById(). Fragment1 loads fragment2 by launching an intent to start the second activity. You landscape layout stays the same but your portrait layout for your activity only contains the fragment tag for the first fragment. When you call setContentView(), only one fragment is loaded.
  • Introducing Fragments

    1. 1. Motorola Mobility Anna Schaller Android 기술 전도사 개발자 플랫폼 및 서비스 Fragment 소개
    2. 2. Fragment <ul><li>애플리케이션을 하위 구성 요소로 나누어 개별적으로 관리하고 다양한 방법으로 결합할 수 있도록 해줍니다 ( 예 : 다중 창 UI 만들기 ). </li></ul>
    3. 3. 왜 Fragment 인가 ? <ul><li>개발자의 관점에서 볼 때 스마트폰과 태블릿 간 가장 큰 차이점은 화면 크기입니다 . </li></ul><ul><li>Fragment 는 스마트폰과 태블릿 모두에 맞게 최적화하고 싶은 앱을 위한 가교를 만들어 줍니다 </li></ul>Fragment 가 두 개인 Activity A 또는
    4. 4. 준비 (Getting there) <ul><li>준비하기 위한 두 가지 방법 </li></ul><ul><ul><li>Android 3.0 SDK </li></ul></ul><ul><ul><li>Android Compatibility( 호환 ) 패키지 </li></ul></ul><ul><li>다수의 레이아웃 </li></ul><ul><ul><li>어디에서나 이중 + 창 지원 </li></ul></ul><ul><ul><li>어디에서나 단일 창 지원 </li></ul></ul><ul><li>Activity 가 여전히 필요함 </li></ul><ul><li>두 개 정도의 Fragment 만들기 </li></ul><ul><li>표시되는 각 Fragment 의 경우 UI 를 추가 </li></ul><ul><li>Fragment 를 Activity 에 추가 </li></ul>
    5. 5. <ul><li>화면 크기 </li></ul><ul><ul><li>소 , 중 , 대 , 초대 형 </li></ul></ul><ul><li>각 화면 크기에는 2 가지 방향이 있습니다 </li></ul><ul><ul><li>가로 </li></ul></ul><ul><ul><li>세로 </li></ul></ul><ul><li>여러 구성에 대한 계획 수립 </li></ul><ul><ul><li>/res/layout-small-land 및 /res/layout-small-port </li></ul></ul><ul><ul><li>/res/layout-normal-land 및 /res/layout-normal-port </li></ul></ul><ul><ul><li>/res/layout-large-land 및 /res/layout-large-port </li></ul></ul><ul><ul><li>/res/layout-xlarge-land 및 /res/layout-xlarge-land </li></ul></ul>레이아웃에 대한 계획 수립
    6. 6. 이중 창 ( 가로 및 세로 )
    7. 7. Fragment – 이중 창 Fragment 목록 Fragment Activity findFragmentById( DetailFragment ) setContentView(R.layout. main )
    8. 8. Android 3.0 에서 Fragment 작업하기 <ul><li>각 Fragment 를 위한 새 클래스를 만듭니다 </li></ul><ul><ul><li> ; 를 가져옵니다 </li></ul></ul><ul><ul><li>Fragment 또는 ListFragment 를 확장합니다 (Activity 대신 ) </li></ul></ul><ul><ul><li>수명 (Lifecycle) 호출을 추가합니다 </li></ul></ul><ul><li>각 Fragment 에 대한 새 resource.xml 파일을 생성합니다 </li></ul><ul><ul><ul><li><ViewGroup> <UI elements> </ViewGroup> </li></ul></ul></ul><ul><li>각 Fragment 를 위한 새 Fragment 태그로 main.xml 을 업데이트합니다 </li></ul><ul><ul><li><fragment class=“” </li></ul></ul><ul><ul><li>android:id=“@+id/fragmentIdX> </li></ul></ul><ul><li> 에서 (Activity 확장 ) </li></ul><ul><ul><li>setContentView(R.layout.main) 로 애플리케이션 레이아웃을 로드합니다 </li></ul></ul><ul><li>Fragment1 목록 항목이 findFragmentById( 로 Fragment2 에 연결됩니다 . </li></ul>
    9. 9. 프로젝트 해부 – 이중 창만 해당 (Android 3.0) <ul><li>myFragmentProject </li></ul><ul><li>|-- AndroidManifest.xml </li></ul><ul><li>|-- /src </li></ul><ul><li>|------- / // Activity 확장 </li></ul><ul><li>|------- / // Fragment, ListFragment, DialogFragment 등의 확장 </li></ul><ul><li>|------- / // Fragment, ListFragment, DialogFragment 등의 확장 </li></ul><ul><li>|--- /res </li></ul><ul><li>|------- /layout-land // 가로 방향 레이아웃 </li></ul><ul><li>|----------- /main.xml // 가로 방향 애플리케이션 리소스 파일 (Fragment 태그 포함 ) </li></ul><ul><li>|----------- /fragment1.xml // Fragment 1 UI 레이아웃 </li></ul><ul><li>|----------- /fragment2.xml // Fragment 2 UI 레이아웃 가로 방향 </li></ul><ul><li>|------- /layout-port // 세로 방향 레이아웃 </li></ul><ul><li>|----------- /main.xml // 세로 방향 애플리케이션 리소스 파일 (Fragment 태그 포함 ) </li></ul><ul><li>|----------- /fragment2.xml // Fragment 2 UI 레이아웃 세로 방향 </li></ul><ul><li>|------- /values-xlarge </li></ul><ul><li>| . . . </li></ul>
    10. 10. 3.0 코드 : <ul><li>메인 Activity 는 onCreate() 동안 일반적인 방법으로 레이아웃을 적용합니다 </li></ul><ul><li>setContentView( R.layout.main ) 는 <fragment > 태그가 있는 레이아웃이 포함된 리소스 파일을 로드합니다 . Fragment 는 Activity 가 레이아웃을 로드하는 즉시 인스턴스화됩니다 . </li></ul>
    11. 11. 3.0 코드 : 메인 레이아웃 fragment1 ( 목록 ) fragment2 ( 디테일 ) 가로 옆으로 나란히
    12. 12. 3.0 코드 : 메인 레이아웃 세로 위에서 아래로 목록 폭 및 높이가 반전되어야 함
    13. 13. 3.0 코드 : Fragment 목록 목록 어댑터 설정 목록 항목 콜백 생성 이미지 업데이트 Activity 생성 후 실행할 새 수명 호출 디테일 Fragment 찾기
    14. 14. 3.0 코드 : Fragment 디테일 디테일 보기 를 올리고 첫 번째 이미지 로드 목록 위치를 기반으로 이미지 교체
    15. 15. 3.0 코드 : Fragment UI (fragment1) 목록 항목 (fragment2) 프레임 항목 (ImageView 포함 )
    16. 16. <ul><li>UI 리소스 정의 </li></ul><ul><ul><li>Activity 와 동일한 뷰 (View) 와 뷰 그룹을 사용합니다 </li></ul></ul>UI 가 포함된 Fragment listfragment.xml <TextView> fragment.xml <FrameLayout> <ImageView> <LinearLayout> <GridView> [. . .] dialogfragment
    17. 17. UI 가 포함되지 않은 Fragment
    18. 18. findFragmentByTag() <ul><li>public static class WorkerFragment extends Fragment { </li></ul><ul><li>[. . .] // 백그라운드 쓰레드에서 해당 작업 수행 </li></ul><ul><li>} </li></ul><ul><li>public static class myOtherFragment extends Fragment { </li></ul><ul><li>@Override </li></ul><ul><li>public void onActivityCreated(Bundle savedInstanceState) {             super.onActivityCreated(savedInstanceState); </li></ul><ul><li>FragmentManager fm = getFragmentManager () ; // 워커 Fragment 가 유지되었는지 확인합니다 . mWorkFragment = ( WorkerFragment ) fm. findFragmentByTag (&quot;work&quot;) ; // 유지되지 않았다면 ( 또는 최초로 실행 중인 경우 ) 생성해야 합니다 . if (mWorkFragment == null) {    mWorkFragment = new WorkerFragment (); </li></ul><ul><li>    // 무엇과 작동 중인지 알려줍니다 .     mWorkFragment.setTargetFragment(this, 0);     fm.beginTransaction().add(mWorkFragment, &quot;work&quot;).commit(); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
    19. 19. Android Compatibility( 호환 ) 패키지 <ul><ul><li>“ 모두를 위한 Fragment” 로 알려져 있음 </li></ul></ul><ul><ul><li>Honeycomb 과 Android Compatibility( 호환 ) 패키지 비교 </li></ul></ul><ul><ul><li>차이점이 무엇입니까 ? </li></ul></ul><ul><ul><ul><li>Compatibility Library( 호환 라이브러리 ) 가 API 레벨 4 이상과 작동 가능 </li></ul></ul></ul><ul><ul><ul><li>프로젝트에 새로운 라이브러리를 추가해야 함 </li></ul></ul></ul><ul><ul><ul><li>새로운 Activity 종류 </li></ul></ul></ul><ul><ul><ul><li>새로운 API </li></ul></ul></ul>
    20. 20. 이중 창 (Android 2.2( 가로 방향 ))
    21. 21. 단일 창 (Android 2.2( 세로 방향 ))
    22. 22. Fragment – 이중 창 Fragment 목록 Fragment FragmentActivity1 findFragmentById( DetailFragment ) setContentView(R.layout. main )
    23. 23. Fragment – 단일 창 Fragment Fragment Activity1 Fragment Activity2 Fragment 목록 setContentView(R.layout. main ) findViewById( DetailFragment ) is NULL intent.setClass(getActivity(),Fragment2. class); startActivity(intent );
    24. 24. Compatibility Library( 호환 라이브러리 ) 수정 <ul><li>리소스를 업데이트합니다 </li></ul><ul><ul><li>세로 방향 레이아웃에는 fragment1 태그만 있습니다 (fragment2 태그 없음 ) </li></ul></ul><ul><li>코드를 업데이트합니다 </li></ul><ul><ul><li> 를 가져옵니다 .* </li></ul></ul><ul><ul><li>방향에 따라 boolean 을 설정합니다 </li></ul></ul><ul><ul><li>가로 방향일 경우 (orientation == landscape) 이중 창입니다 </li></ul></ul><ul><ul><ul><li>fragment1 및 fragment2 를 표시합니다 </li></ul></ul></ul><ul><ul><li>세로 방향일 경우 (orientation == portrait) 단일 창입니다 </li></ul></ul><ul><ul><ul><li>intent 를 통해 새로운 FragmentActivity 에서 fragment2 를 엽니다 </li></ul></ul></ul><ul><ul><li>getFragmentManager() 대신에 getSupportFragmentManager() 를 호출합니다 </li></ul></ul>
    25. 25. 프로젝트 해부 – 이중 창 + 단일 창 (Android Compatibility 패키지 ) <ul><li>myFragmentProject </li></ul><ul><li>|-- AndroidManifest.xml </li></ul><ul><li>|-- /src </li></ul><ul><li>|------- / // FragmentActivity 확장 </li></ul><ul><li>|------- / // Fragment, ListFragment, DialogFragment 등의 확장 </li></ul><ul><li>|------- / // Fragment, ListFragment, DialogFragment 등의 확장 </li></ul><ul><li>|------- / // FragmentActivity 확장 </li></ul><ul><li>|--- /res </li></ul><ul><li>|------- /layout-land // 가로 방향 레이아웃 ( 태블릿의 정상적인 방향 ) </li></ul><ul><li>|----------- /main.xml // 태블릿 또는 가로 방향 애플리케이션 리소스 파일 ( 이중 ) </li></ul><ul><li>|----------- /fragment1.xml // Fragment1 UI 레이아웃 </li></ul><ul><li>|----------- /fragment2.xml // Fragment2 UI 레이아웃 </li></ul><ul><li>|------- /layout-port // 세로 방향 레이아웃 ( 스마트폰의 정상적인 방향 ) </li></ul><ul><li>|----------- /main.xml // 스마트폰 또는 세로 방향 애플리케이션 리소스 파일 ( 단일 ) </li></ul><ul><li>|----------- /fragment1.xml </li></ul><ul><li>|------- /values-xlarge </li></ul><ul><li>| . . . </li></ul>
    26. 26. Android Compatibility( 호환 ) 패키지 이용 <ul><li>환경 설정 </li></ul><ul><ul><li>Android SDK 및 AVD Manager 를 이용하여 “ Android Compatibility Package”( 호환 패키지 ) 를 다운로드합니다 . SDK 설치 디렉토리에 extras/android/compatibility/v4/android-support-v4.jar 가 있습니다 . </li></ul></ul><ul><ul><li>선택한 API 레벨 (4-10) 에서 새 Android Project( 프로젝트 ) 를 생성합니다 . </li></ul></ul><ul><ul><li>android-support-v4.jar 를 프로젝트의 /libs 디렉토리에 추가합니다 . </li></ul></ul><ul><ul><li>Studio 또는 Eclipse 사용자인 경우에는 프로젝트 구축 경로에도 추가합니다 (Project -> Properties -> Java Build Path -> Libraries -> Add JAR). </li></ul></ul>
    27. 27. Fragment 사용 : 정보 <ul><li>3.0 Developer Guide 에 있는 Fragment 에 대한 대한 기본 정보 </li></ul><ul><li>3.0 Reference for APIs 참조 </li></ul><ul><ul><li> </li></ul></ul><ul><ul><li> </li></ul></ul><ul><ul><ul><li>ListActivity 와 유사한 목록을 표시합니다 </li></ul></ul></ul><ul><ul><li> </li></ul></ul><ul><ul><ul><li>부동 대화 상자를 표시합니다 </li></ul></ul></ul><ul><ul><li> </li></ul></ul><ul><ul><ul><li>Fragment 와 상호 작용을 위한 인터페이스 ( findFragmentById) </li></ul></ul></ul><ul><ul><li> </li></ul></ul><ul><ul><ul><li>Fragment 작동을 위한 API( add, remove, replace, hide, show) </li></ul></ul></ul>
    28. 28. Fragment 사용 : 견본 <ul><li>Android 3.0 Fragment 를 위한 Honeycomb Gallery 앱 </li></ul><ul><li>Android Compatibility 패키지의 extra 폴더에서 </li></ul><ul><ul><li>/android-sdk/extras/android/compatibility/v4/samples/ApiDemos/src/com/example/android/apis/app/ </li></ul></ul><ul><ul><li>HC 버전용 Fragment<>.java 를 찾습니다 </li></ul></ul><ul><ul><li>Android Compatibility 패키지 코드용 Fragment<>Support*.java </li></ul></ul><ul><li>Reto Meier 의 블로그 게시물 </li></ul><ul><ul><li> </li></ul></ul><ul><ul><li> </li></ul></ul><ul><li>Diane Hackborne 의 블로그 게시물 </li></ul><ul><ul><li> (Android 3.0 Fragment API) </li></ul></ul>
    29. 29. 자발적인 참여 : <ul><ul><li>디스커션 보드에 참여 하시 여러분의 질문에 대한 답변 및 조언을 받으십시오 </li></ul></ul><ul><ul><li> </li></ul></ul><ul><li>도구를 사용해 보십시오 </li></ul><ul><ul><li>MOTODEV Studio: 추가적 기능 ( 문자열 로컬화 , 데이터베이스 관리자 , 코드 정보 ) 이 있는 이클립스 기반의 IDE </li></ul></ul><ul><ul><li>App Validator: Android 앱의 호환성과 일관성을 검사하기 위한 온라인 도구 </li></ul></ul><ul><li>트위터 (Twitter) 에서 트윗하십시오 </li></ul><ul><ul><li>appsum11kr </li></ul></ul><ul><ul><li>제품 사양 참조 </li></ul></ul><ul><ul><li> </li></ul></ul>
    30. 30. 감사합니다 © 2010 Motorola Mobility, Inc. 46
    31. 31. 법적 고지 <ul><li>라이센스 주의 사항 </li></ul><ul><li>따로 기재된 사항이 없다면 Motorola Mobility Inc. 가 기술하고 제공하는 견본 소스 코드는 아래 설명과 같이 사용이 허가됩니다 . </li></ul><ul><li>Copyright © 2010-2011, Motorola, Inc. All rights reserved( 달리 명시적으로 표시한 것은 예외 ). </li></ul><ul><li>수정 유무를 막론하고 소스 및 2 진수 형태로의 재배포 및 사용은 다음 조건이 충족될 경우에만 허용됩니다 . </li></ul><ul><li>소스 코드의 재배포는 위의 저작권 주의 사항 , 이 조건 목록 및 다음의 부인 고지 사항을 유지해야 합니다 . </li></ul><ul><li>2 진수 형태로의 재배포는 위의 저작권 주의 사항 , 이 조건 목록 및 다음의 부인 고지 사항을 배포물과 함께 제공되는 문서 및 / 또는 기타 자료에 복제해야 합니다 . </li></ul><ul><li>구체적인 사전 서면 허가가 없이는 이 소프트웨어에서 파생된 제품을 보증하고 홍보하는 데 Motorola, Inc. 이름 및 해당 기여자의 이름을 사용할 수 없습니다 . </li></ul><ul><li>이 소프트웨어는 저작권 소유자와 기여자에 의해 &quot; 있는 그대로 &quot; 제공되며 모든 명시적 또는 묵시적 보증 ( 상품성 및 특정 목적에 대한 적합성에 대한 묵시적 보증을 포함하며 여기에 제한되지 않음 ) 을 배제합니다 . 저작권 소유자 또는 기여자는 이 소프트웨어의 사용으로 인해 발생하는 모든 직접적 , 간접적 , 부수적 , 예외적 , 전형적 또는 결과적 손해 ( 대체품이나 대체 서비스의 조달 , 사용 , 데이터 또는 이익 손실 , 또는 영업 중단을 포함하되 이에 제한되지 않음 ) 에 대하여 계약에 의한 것이든 , 엄밀한 책임 또는 불법 행위 ( 또는 과실과 기타 행위를 포함하여 ) 에 의한 것이든 이와 여타 책임 소재에 상관없이 어떠한 경우에도 책임을 지지 않으며 , 이는 그와 같은 손해의 가능성을 사전에 알고 있던 경우에도 마찬가지입니다 </li></ul><ul><li>  이 프레젠테이션에서 표시되는 기타 소스 코드는 다른 라이센스 하에 제공될 수도 있습니다 . 
 </li></ul><ul><li>Apache 2.0 </li></ul><ul><li>Copyright © 2010, Android Open Source Project. All rights reserved( 달리 명시적으로 표시한 것은 예외 ). </li></ul><ul><li>Apache 라이센스 하에서 사용이 허가됨 , 버전 2.0(&quot; 라이센스 &quot;); 이 라이센스를 준수하지 않고는 이 파일을 사용할 수 없습니다 . 에서 라이센스 사본을 얻을 수 있습니다 . </li></ul><ul><li>해당 법률에 의해 필요하거나 서면 동의가 있지 않는 한 이 라이센스 하에서 배포되는 소프트웨어는 명시적이든 묵시적이든 막론하고 어떠한 보증이나 조건 없이 &quot; 있는 그대로 &quot; 배포됩니다 . 이 라이센스 하의 특정 언어 관리 허가 및 제한 사항은 라이센스를 참조하십시오 . </li></ul><ul><li>Creative Commons 3.0 귀속 라이센스 </li></ul><ul><li>이 프레젠테이션의 일부는 Google 이 생성하고 공유하는 작업에서 복제된 것이며 ( Creative Commons 3.0 귀속 라이센스 ( 에 설명된 약관에 따라 사용되었습니다 . </li></ul>
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.