태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

네비게이션 드로어 활용 - (1) 프래그먼트와 연동하기

2014.06.02 12:02

네비게이션 드로어(Navigation drawer)는 최근 출시되는 대다수의 안드로이드 애플리케이션에서 사용하고 있는 UI 구성 요소입니다. 

이전 포스트(2013/11/05 - 네비게이션 드로어(Navigation Drawer) 사용하기)에선 네비에게이션 드로어 자체에 대한 내용을 주로 다루었는데, 이번 포스트에서는 프래그먼트와 네비게이션 드로어를 함께 사용하여 실제 애플리케이션에 적용하는 방법에 대해 알아보겠습니다.


화면에 표시할 프래그먼트 생성


예제 프로젝트에선 다음 두 프래그먼트를 네비게이션 드로어와 연결하여 사용할 것입니다.


  • TextFragment (문자열을 표시하는 프래그먼트)
  • ImageFragment (이미지를 표시하는 프래그먼트)


텍스트를 표시하는 프래그먼트인 TextFragment를 먼저 생성해 봅시다. TextFragment에서 표시할 레이아웃을 다음과 같이 작성합니다. 텍스트를 표시하는 TextView 하나를 표시하며, 표시될 텍스트는 문자열 리소스를 사용하여 별도로 저장했습니다. (@string/lorem_ipsum)


[fragment_text.xml]

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.androidhuman.example.navigationdrawer.basicfragments.app.TextFragment">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/lorem_ipsum" />

</FrameLayout>


다음, TextFragment 클래스를 작성합니다. 위에서 작성한 TextFragment의 레이아웃(layout_fragment_text)을 표시하는 것 외에는 특별한 기능은 없습니다.



[TextFragment.java]

public class TextFragment extends Fragment {

    public static TextFragment newInstance() {
        TextFragment fragment = new TextFragment();
        return fragment;
    }

    public TextFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_text, container, false);
    }

}


이어서 이미지를 표시하는 프래그먼트인 ImageFragment와 그 레이아웃을 작성합니다. TextFragment와 마찬가지로 이미지(앱 아이콘)를 표시하는 기능 외에 특별한 기능은 없습니다.


[fragment_image.xml]

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.androidhuman.example.navigationdrawer.basicfragments.app.ImageFragment">

    <ImageView
        android:id="@+id/iv_fragment_image"
        android:scaleType="center"
        android:src="@drawable/ic_launcher"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>



[ImageFragment.java]

public class ImageFragment extends Fragment {

    public ImageFragment newInstance(){
        ImageFragment fragment = new ImageFragment();
        return fragment;
    }


    public ImageFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_image, container, false);
    }

}
메인 액티비티 구현


먼저, 다음과 같이 메인 액티비티의 레이아웃을 작성합니다. 네비게이션 드로어(DrawerLayout)가 전체를 감싸고 있고, 그 안에 메뉴를 표시하는 ListView와 프래그먼트를 표시할 공간인 FrameLayout을 지정했습니다.


[activity_main.xml]

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/dl_activity_main"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/fl_activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <ListView android:id="@+id/lv_activity_main"
        android:background="#EDEDED"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start" />

</android.support.v4.widget.DrawerLayout>


이제 액티비티 본체를 작성할 차례입니다. 먼저, 네비게이션 드로어 구현에 필요한 요소들과 위에서 만든 두 프래그먼트(TextFragment, ImageFragment)의 인스턴스를 선언합니다.


[MainActivity.java]

public class MainActivity extends ActionBarActivity {

    DrawerLayout dlDrawer;
    ActionBarDrawerToggle dtToggle;

    ListView lvDrawerList;
    ArrayAdapter<String> adtDrawerList;
    String[] menuItems = new String[]{"TextFragment", "ImageFragment"};

    TextFragment fragText;
    ImageFragment fragImage;



다음, onCreate() 메서드에서 각 요소들을 초기화합니다. 먼저, 두 프래그먼트를 생성한 후, 액티비티 최초 실행시 TextFragment가 표시되도록 구현하였습니다.


// Fragments
fragText = TextFragment.newInstance();
fragImage = new ImageFragment().newInstance();

getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.fl_activity_main, fragText).commit();


네비게이션 드로어에서 표시할 메뉴 항목과, 각 항목을 선택했을 때 선택한 프래그먼트를 화면에 표시합니다.


[MainAvtivity.java]

// Navigation drawer : menu lists
lvDrawerList = (ListView) findViewById(R.id.lv_activity_main);
adtDrawerList = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, menuItems);
lvDrawerList.setAdapter(adtDrawerList);
lvDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        switch(position){
            case 0:
                getSupportFragmentManager()
                        .beginTransaction()
                        .replace(R.id.fl_activity_main, fragText).commit();
                break;
            case 1:
                getSupportFragmentManager()
                        .beginTransaction()
                        .replace(R.id.fl_activity_main, fragImage).commit();
                break;
        }
        dlDrawer.closeDrawer(lvDrawerList);
    }
});


앱 아이콘 측면의 작은 아이콘을 통해 네비게이션 드로어의 동작 상태 (열림/닫힘)을 표시하기 위해, 다음과 같이 액션바 토글을 구성합니다.


[MainActivity.java]

// Navigation drawer : ActionBar Toggle
dlDrawer = (DrawerLayout) findViewById(R.id.dl_activity_main);
dtToggle = new ActionBarDrawerToggle(this, dlDrawer, R.drawable.ic_drawer, R.string.app_name, R.string.app_name);
dlDrawer.setDrawerListener(dtToggle);

getSupportActionBar().setDisplayHomeAsUpEnabled(true);


onCreate() 메서드의 구현은 모두 끝났습니다. 이제 액션바 토글의 정상 동작을 위해 아래 메서드를 다음과 같이 구현합니다.


[MainActivity.java]

@Override
protected void onPostCreate(Bundle savedInstanceState){
    super.onPostCreate(savedInstanceState);
    dtToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig){
    super.onConfigurationChanged(newConfig);
    dtToggle.onConfigurationChanged(newConfig);
}

@Override
public boolean onOptionsItemSelected(MenuItem item){
    if(dtToggle.onOptionsItemSelected(item)){
        return true;
    }
    return super.onOptionsItemSelected(item);
}


이것으로 모든 구현이 끝났습니다. 완성된 애플리케이션을 빌드 후 실행하면 다음과 같이 네비게이션 드로어와 프래그먼트가 잘 표시되는 것을 확인할 수 있습니다.




 













저작자 표시 비영리 변경 금지
신고

커니 유저 인터페이스 , , , , , , , , , , , , , ,

  1. Blog Icon

    FrameLayout을 사용한 가운데 컨텐츠 영역은 반드시 FrameLayout으로만 구현되어야 하나요?
    FrameLayout 안에 Fragment를 사용하지 않고 LinearLayout등을 사용하여, View를 배치해서 사용할 수는 없나요..?

  2. 상관 없습니다~ 예제에서는 편의상 FrameLayout을 사용하였을 뿐 다른 View와 혼합하여 배치할 수 있습니다.

  3. Blog Icon
    anonymous

    안드로이드 공부중인데 커니님 예제가 많은 도움이 됩니다. 감사합니다.

  4. Blog Icon
    가을월식

    안녕하세요 매번 좋은 글 많이 보고 가는 학생입니다.

    현재 네비게이션 드로어어를 구현했고, 그 중의 한 프레그먼트에 swipe + tab기능을 넣고 싶은데요
    이 글에는 프레그먼트 다루는 부분이 없어서 힘이 듭니다.

    간단한 조언이라도 해주시면 감사드립니다.

  5. Blog Icon
    호로롱

    안녕하세요!!! 네비게이션드로어랑 탭뷰를 연결하는 중인데요!
    네비게이션에 있는 리스트에서 클릭시 탭뷰의 해당 화면으로 넘어가는게 안되서요..
    탭뷰가 프레그먼트 교체방식으로 되어있어서 DrawItemClickListener에서 switch문 안에 프레그먼트를 이용하여 화면을 바꿔봤는데 계속 안되서 toast메세지를 넣어보기도 했는데 아예 뜨지 않더라구요ㅠㅠ
    혹시 괜찮으시다면 해당부분 소스코드를 올려봐도 괜찮을까용?

  6. 학교 프로젝트를 만드는데 초기작업할때 도움이 많이 됐습니다
    코드 좀 인용하겠습니다 감사합니다^^