http://jamesy.tistory.com/archive/201311
사진 1
Navigation Drawer(네비게이션 드로워)
안드로이드가 발전하고 있는 만큼 화면의 효율적인 활용이 중요시 되고 있다. ActionBar, Fragment 등을 이용하여 화면을 분할하고 각각에 역할을 줄 수 있게 되었다. Navigation Drawer도 화면을 효율적으로 사용할 수 있게 해주는 방법 중 하나이다. 대부분의 구글 앱에는 Navigation Drawer가 적용되어 있고, 인기 앱에도 자주 사용되고 있다.
소스 다운로드 및 소개 페이지
http://developer.android.com/intl/ko/training/implementing-navigation/nav-drawer.html 에서
오른쪽 중간 부분에 'Download the sample app'을 다운하면 된다.
또는
소스를 보면 메인 클래스 하나가 전부이다.
변수 정의
private DrawerLayout mDrawerLayout; // 주 기능
private ListView mDrawerList; // 내용
private ActionBarDrawerToggle mDrawerToggle; // 주 기능
private CharSequence mDrawerTitle; // ActionBar의 제목을 변경하기 위한 변수
private CharSequence mTitle; // ActionBar의 제목을 변경하기 위한 변수
private String[] mPlanetTitles; // 태양계 행성 이름들
onCreate()
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 액션바 제목 mTitle = mDrawerTitle = getTitle(); // strings.xml의 데이터 삽입 mPlanetTitles = getResources().getStringArray(R.array.planets_array); // DrawerLayout 정의 mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); // DrawerLayout Shadow 정의(사진 2 참조) mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); // ListView 정의 mDrawerList = (ListView) findViewById(R.id.left_drawer); // ListView 데이터 정의 mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, mPlanetTitles)); // ListView 아이템 클릭 리스너 mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); // ActionBar의 홈버튼을 Navigation Drawer 토글기능으로 사용 getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true); // 토글 정의 mDrawerToggle = new ActionBarDrawerToggle( this, mDrawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close ) { public void onDrawerClosed(View view) { getActionBar().setTitle(mTitle); invalidateOptionsMenu(); } public void onDrawerOpened(View drawerView) { getActionBar().setTitle(mDrawerTitle); invalidateOptionsMenu(); } }; // Drawer Layout의 리스너를 mDrawerToggle로 정의 mDrawerLayout.setDrawerListener(mDrawerToggle); // 인스턴스 상태가 존재 안하면 가장 첫번째 아이템으로 시작 if (savedInstanceState == null) { selectItem(0); } }
사진 2
DrawerItemClickListener() & selectItem()
private class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
⁄// 리스트 아이템 클릭 시 변경됨
Fragment fragment = new PlanetFragment();
// Fragment에 추가적인 정보 저장
Bundle args = new Bundle();
args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
fragment.setArguments(args);
// FragmentManger가 Fragment가 바뀔때마다 교체해줌
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
// 아이템이 계속 클릭된 상태로 유지
mDrawerList.setItemChecked(position, true);
// ActionBar 제목 변경(해당 글에는 넣지 않음.)
setTitle(mPlanetTitles[position]);
// Drawer Layout 닫기
mDrawerLayout.closeDrawer(mDrawerList);
}
PlanetFragment Class
public static class PlanetFragment extends Fragment { public static final String ARG_PLANET_NUMBER = "planet_number"; public PlanetFragment() { // Fragment 하위 클래스 때문에 필요함 } // 기본 Fragment의 화면 정의 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_planet, container, false); int i = getArguments().getInt(ARG_PLANET_NUMBER); String planet = getResources().getStringArray(R.array.planets_array)[i]; int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()), "drawable", getActivity().getPackageName()); ((ImageView) rootView.findViewById(R.id.image)).setImageResource(imageId); getActivity().setTitle(planet); return rootView; } }
이 외에도 여러 메소드들이 존재하지만 이 글에는 최소한의 Drawer Layout 생성 및 작동에 필요한 메소드들과 클래스만 적어두었다.
activity_main.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http:⁄⁄schemas.android.com⁄apk⁄res⁄android"
android:id="@+id⁄drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id⁄content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" ⁄>
<ListView
android:id="@+id⁄left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color⁄transparent"
android:dividerHeight="0dp"
android:background="@android:color⁄white"⁄>
<⁄android.support.v4.widget.DrawerLayout>
DrawerLayout에 FrameLayout과 ListView를 넣어 구현하였다.
FrameLayout말고 다른 Layout이 삽입되어도 된다.
drawer_list_item.xml
<TextView xmlns:android="http:⁄⁄schemas.android.com⁄apk⁄res⁄android"
android:id="@android:id⁄text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr⁄textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textColor="@android:color⁄black"
android:background="?android:attr⁄activatedBackgroundIndicator"
android:minHeight="?android:attr⁄listPreferredItemHeightSmall"⁄>
각각의 리스트 아이템에 적용되는 속성이다.
fragment_planet.xml
<ImageView xmlns:android="http:⁄⁄schemas.android.com⁄apk⁄res⁄android"
android:id="@+id⁄image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:gravity="center"
android:padding="32dp" ⁄>
각각의 Fragment의 이미지들의 대한 속성이다.
구글이 제공하는 소스에는 ListView를 이용한 Drawer Layout을 구현되어 있다. 하지만 이 ListView를 좀 더 커스텀하여 꾸밀 수도 있고, ListView가 아닌 Layout을 넣음으로써 텍스트뷰, 버튼, Radio 버튼, 체크박스, 레이아웃 종류 등 다양한 시도를 할 수 있다.
'차근차근 > Android' 카테고리의 다른 글
webview , asset , font (0) | 2015.02.06 |
---|---|
actionbar + navigation drawer 소스 (0) | 2015.02.04 |
actionbar , Navigation Drawer, overlay (0) | 2015.02.04 |
네비게이션 드로어 Navigation Drawer (0) | 2015.02.04 |
actionbar 란 (0) | 2015.02.03 |