일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 알고리즘
- android architecture component
- mfc
- RxJava
- Android P
- C++
- 안드로이드
- NDK
- RxAndroid
- android push
- Flutter TextField
- Python
- 안드로이드 구글맵
- kodility
- dart
- Django REST Android
- Android
- 코틀린
- Java
- C
- C/C++
- FLUTTER
- Rxjava2
- livedata
- Kotlin
- UWP
- flutter firestore
- Django REST framework
- Django REST
- 프로그래머스
- Today
- Total
개발하는 두더지
[Android] DrawerLayout, NavigationView 사용하기 본문
Drawer Navigation 이란?
Hambuger, Sandwich 라고 불리는 보통 왼쪽 상단에 위치하는 메뉴버튼을 클릭하거나 손가락으로 화면 왼쪽을 스와이프하여 나오는 뷰를 말합니다.
모바일 디바이스는 화면이 작아서 모든 UI를 담을 수 없습니다.
Toolbar, Fragment와 같이 앱의 Depth (Activity 이동 최소화) 를 줄일 수 있는 뷰를 제공하게 되었습니다.
아래에서 Drawer Navigation을 적용하는 방법을 알아보겠습니다.
실행 결과
소스 코드
build.gradle
아래 2개를 추가해줘야 사용 가능합니다.
dependencies {
...
// DrawerLayout
compile 'com.android.support:support-v4:26.1.0'
// NavigationView
compile 'com.android.support:design:26.1.0'
}
style.xml
API 21 부터 Toolbar가 추가되었습니다. Toolbar는 View이기 때문에 기존에 ActionBar에서 하지 못했던 것들을 할 수 있게 해줍니다.
ActionBar는 View가 아니며 내부 아이템과 위치를 제어하기 어렵습니다.
Toolbar는 View이며 제어하기 쉽습니다.
ActionBar가 deprecated 되었기 때문에 Toolbar를 사용하기위해 NoActionBar를 적용해줍니다.
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
drawer.xml
네비게이션에 사용될 menu 입니다.
res 하위에 반드시 menu 폴더를 만들고 그 하위에 drawer.xml 파일을 만들어야 합니다.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/item1"
android:icon="@mipmap/ic_launcher_round"
android:title="item1"
/>
<item
android:id="@+id/item2"
android:icon="@mipmap/ic_launcher_round"
android:title="item2"
/>
<item
android:id="@+id/item3"
android:icon="@mipmap/ic_launcher_round"
android:title="item3"
/>
</menu>
toolbar.xml
Custom Toolbar를 새로 만들어 줍니다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="?attr/colorPrimary"
/>
activty_main.xml
DrawerLayout 는 반드시 메인 뷰와 네비게이션 뷰를 감싸고 있어야 합니다.
메인 뷰는 xml 순서가 z-ordering 순서로 되어있기 때문에 DrawerLayout 의 처음에 위치해야 합니다.
네비게이션 뷰는 문서에보면 보통 ListView나 RecyclerView를 사용한다고 나오지만 NavigationView를 이용하여 커스텀UI를 사용해도 됩니다.
DrawerLayout에서
fitsSystemWindows : true를 주면 네비게이션 뷰가 상태창과 소프트키 사이를 차지한다. 즉, toolbar를 덮는다.
openDrawer : start를 주면 네비게이션 뷰가 왼쪽에서 생긴다
NavigationView에서
headerLayout : 헤더 레이아웃
menu : 메뉴 레이아웃
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<android.support.v4.widget.DrawerLayout
android:id="@+id/dl_main_drawer_root"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:fitsSystemWindows="true"
tools:openDrawer="start"
>
<!-- main content -->
<include
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/activity_main_content" />
<!-- navigation drawer-->
<android.support.design.widget.NavigationView
android:id="@+id/nv_main_navigation_root"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/drawer" />
</android.support.v4.widget.DrawerLayout>
</android.support.constraint.ConstraintLayout>
activity_main_content.xml
Custom Toolbar를 include 해주고 나머지는 메인 콘텐츠 내용을 구성합니다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--Custom Toolbar-->
<include layout="@layout/toolbar" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:text="SAMPLE"
/>
</android.support.constraint.ConstraintLayout>
nav_header_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@android:color/holo_green_dark"
android:gravity="bottom"
android:orientation="vertical"
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="8dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="8dp"
app:srcCompat="@mipmap/ic_launcher_round" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:text="duzi"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="duzi@naver.com" />
</LinearLayout>
string.xml
<resources>
<string name="app_name">NavigationSample</string>
<string name="drawer_open">drawer_open</string>
<string name="drawer_close">drawer_close</string>
</resources>
MainActivity.java
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
DrawerLayout drawerLayout;
NavigationView navigationView;
ActionBarDrawerToggle drawerToggle;
Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initLayout();
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch(item.getItemId()) {
case R.id.item1:
Toast.makeText(this, "item1 clicked..", Toast.LENGTH_SHORT).show();
break;
case R.id.item2:
Toast.makeText(this, "item2 clicked..", Toast.LENGTH_SHORT).show();
break;
case R.id.item3:
Toast.makeText(this, "item3 clicked..", Toast.LENGTH_SHORT).show();
break;
}
drawerLayout.closeDrawer(GravityCompat.START);
return false;
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
drawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (drawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
private void initLayout() {
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.mipmap.ic_menu_white_24dp);
drawerLayout = (DrawerLayout) findViewById(R.id.dl_main_drawer_root);
navigationView = (NavigationView) findViewById(R.id.nv_main_navigation_root);
drawerToggle = new ActionBarDrawerToggle(
this,
drawerLayout,
toolbar,
R.string.drawer_open,
R.string.drawer_close
);
drawerLayout.addDrawerListener(drawerToggle);
navigationView.setNavigationItemSelectedListener(this);
}
@Override
public void onBackPressed() {
if(drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
}
네비게이션 뷰에서 아이템을 클릭 시 다음 동작을 하려면?
Activity class 에 NavigationView의 아이템선택리스너를 구현해줘야 합니다.
implements NavigationView.OnNavigationItemSelectedListener
drawer.xml 에서 구현된 메뉴를 파라미터로 받습니다.
해당 메뉴 아이템이 선택되면 네비게이션 뷰를 닫아주고 종료해야합니다.
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch(item.getItemId()) {
case R.id.item1:
Toast.makeText(this, "item1 clicked..", Toast.LENGTH_SHORT).show();
break;
case R.id.item2:
Toast.makeText(this, "item2 clicked..", Toast.LENGTH_SHORT).show();
break;
case R.id.item3:
Toast.makeText(this, "item3 clicked..", Toast.LENGTH_SHORT).show();
break;
}
drawerLayout.closeDrawer(GravityCompat.START);
return false;
}
그리고 네비게이션 뷰 객체에서 이벤트를 받으려면 리스너를 세팅해줘야 합니다.
navigationView = (NavigationView) findViewById(R.id.nv_main_navigation_root);
navigationView.setNavigationItemSelectedListener(this);
참고
Drawer Navigation Google 개발 가이드
'Java,Android' 카테고리의 다른 글
[Android] android.app.Application cannot be cast to xxxx (0) | 2018.04.25 |
---|---|
[Android] DI, Dagger2 란? (0) | 2018.04.22 |
안드로이드 toolbar 중복 코드 지우기 (1) | 2018.04.21 |
[Android] Dalvik , ART 란 ? (0) | 2017.12.18 |
[Android] ADB ( Android Debug Bridge ) 란? (0) | 2017.12.18 |