728x90
반응형

목차

     

    원래 그냥 안드로이드 스튜디오에서 제공하는 Navigation Drawer Activity로 묻어가려 했는데

    하다보니 이해가 너무 안되길래 처음부터 다시 만들기로 했다

     

    먼저 지금까지 작업했던 프로젝트 대신 새로운 프로젝트를 하나 만들자

    평소대로 Empty Activity로...

     

     

    기존 프로젝트의 이름을 바꾸고 새로 GYMPartner 프로젝트를 만들어 주자

     

    그리고 유튜브 검색...

    Part3로 나누어진 강좌를 발견

    https://www.youtube.com/watch?v=fGcMLu1GJEc

    https://www.youtube.com/watch?v=zYVEMCiDcmY 

    https://www.youtube.com/watch?v=bjYstsO1PgI&t=214s 

     

    아이콘 추가

    먼저 Navigation Drawer에 나올 아이콘들을 추가해주자

    res - drawable 우클릭 - New - Image Asset 클릭

     

    Name를 변경하고 Image 선택, Path 선택

     

    같은 방법으로 4번 더 반복해서 각각 아이콘을 만들어주었다

     

    menu 추가

    menu는 NavigationDrawer에서 아이콘 등을 보여줄 때 사용한다

     

    res 우클릭 - New - Android Resource Directory 클릭

     

    Resource type를 menu로 바꿔준 뒤 OK

     

    만들어진 menu 폴더를 우클릭 - New - Menu Resource File 클릭

     

    파일 이름은 drawer_menu로 정했다

     

    그다음 xml 파일을 작성

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        tools:showIn="navigation_view">
        <item android:title="사용자 정보">
            <menu>
                <item android:id="@+id/height"
                    android:title="키: 180cm"/>
                <item android:id="@+id/weight"
                    android:title="몸무게:80.0kg"/>
            </menu>
        </item>
    
        <group android:checkableBehavior="single">
            <item
                android:id="@+id/nav_userinfo"
                android:icon="@drawable/ic_account"
                android:title="마이페이지" />
            <item
                android:id="@+id/nav_list"
                android:icon="@drawable/ic_list"
                android:title="운동목록" />
            <item
                android:id="@+id/nav_addexercise"
                android:icon="@drawable/ic_add"
                android:title="운동추가" />
            <item
                android:id="@+id/nav_addroutine"
                android:icon="@drawable/ic_dumbbell"
                android:title="루틴추가" />
            <item
                android:id="@+id/nav_statistics"
                android:icon="@drawable/ic_statistics"
                android:title="통계" />
        </group>
    </menu>

    Design에서는 아래와 같이 나온다

     

    <item>안에 <menu>를 넣어서 divider를 만들 수 있는듯 하다

    <group android:checkableBehavior="single">은 이 <group>안의 item들이 배타적으로 선택되도록 한다

    <item>에서 icon은 필수가 아니지만 title은 필수속성이다.

     

    Action Bar 삭제

    Action Bar는 앱의 최상단에 있는 것으로 보통 제목 같은 걸 넣는다

    근데 왜 지우는 거지...

    일단 그대로 따라해봤다

     

    예전 영상이라 그런지 영상에서는 styles.xml밖에 없지만 나는 theme 폴더에 두 xml 파일이 있었기에 둘다 수정했다

     

    <style name="AppTheme.NoActionBar">
            <item name="windowActionBar">false</item>
            <item name="windowNoTitle">true</item>
    </style>

     

    그런데 영상과는 다르게 오류가 뜬다

    흠... 일단 원래 파일에 있던 것처럼 parent를 추가해봤다

    정확한 이유는 잘 모르겠으나 Theme.~~를 추가하면 되는 듯 하다

     

    일단 가장 먼저 자동완성에 나왔던 Theme.AppCompat으로 해놨다

        <style name="AppTheme.NoActionBar" parent="Theme.AppCompat">
            <item name="windowActionBar">false</item>
            <item name="windowNoTitle">true</item>
        </style>

     

    그리고 AndroidManifest.xml에서 만든 theme를 추가해준다

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.lektion.gympartner">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/Theme.GYMPartner">
            <activity
                android:name=".MainActivity"
                android:exported="true"
                android:theme="@style/AppTheme.NoActionBar">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

     

     

    Navigation Header 만들기

    요부분이다

     

    layout 우클릭 - New - Layout Resource File 클릭

     

    File name은 nav_header, Root element는 LinearLayout으로 설정한다

     

    계획상 header에는 앱 이름만 들어가기 때문에 간단히 TextView만 추가해주었다

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:background="#606D72"
        android:gravity="center"
        android:orientation="vertical"
        android:theme="@style/ThemeOverlay.AppCompat.Dark">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="GYM Partner"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"
            android:textSize="25dp" />
    
    </LinearLayout>

     

    activity_main.xml 수정

    속성 추가

    activity_main.xml를 열고 Root element를 DrawerLayout으로 변경한다

    <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context=".MainActivity">

    id를 drawer_layout으로 설정해주고

    fitsSystemWindows를 true로 설정

     

    fitsSystemWindows를 true로 설정하면 상태표시줄과 Drawer가 겹치지 않는다

     

    LinearLayout 추가

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="#606D72"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    
            <FrameLayout
                android:id="@+id/fragment_container"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>

    Toolbar는 아까 삭제했던 Action Bar를 대체한다

    Action Bar는 버전별로 호환이 안되기도 한다고...

    FrameLayout는 이후 만들 fragment들이 보여질 부분이다

     

    NavigationView 추가

        <com.google.android.material.navigation.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/nav_header"
            app:menu="@menu/drawer_menu" />

    layout_gravity="start"는 시작점에 위치시켜준다고 한다

    시험삼아 end로 바꿔보자 충돌났다

     

    그리고 DrawLayout 속성에 openDrawer를 추가해준다

    <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context=".MainActivity"
        tools:openDrawer="start">

     

     

    MainActivity.java

    Toolbar 설정

    먼저 Toolbar를 찾아서 ActionBar로 설정한다

            Toolbar toolbar = findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);

     

    drawer

    다음으로 DrawerLayout를 찾아 설정

    private DrawerLayout drawer;
    
    ...
    
    drawer = findViewById(R.id.drawer_layout);
    
    ...

     

    ActionBarDrawerToggle

    strings.xml에 다음을 추가

    <string name="navigation_drawer_open">Open navigation drawer</string>
    <string name="navigation_drawer_close">Close navigation drawer</string>

    다시 MainActivity로 돌아와서 toggle 추가

    private ActionBarDrawerToggle toggle;
    ...
    
    toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    ...

     

    drawer에 toggle를 추가해주고 현재 Drawerlayout 상태와 ActionBarDrawerToggle 의 상태를 동기화한다

    drawer.addDrawerListener(toggle);
    toggle.syncState();

     

    onBackPressed

    onBackPressed는 Overide method로 백버튼(뒤로가기)가 눌렸을 때 호출된다

    만약 Drawer가 열려있다면 백버튼을 눌렀을때 Drawer를 닫는다

        @Override
        public void onBackPressed() {
            if(drawer.isDrawerOpen(GravityCompat.START))
            {
                drawer.closeDrawer(GravityCompat.START);
            }
            else
            {
                super.onBackPressed();
            }
        }

     

    버전에 따른 styles.xml 설정

    영상에서 말하길 API버전에 따라 style이 적용이 안될 수도 있다고 한다

     

    values폴더에 새로운 values Resource File를 만들자

    이름은 styels.xml로 한 뒤 Available qualifiers에서 Version를 선택, 21을 입력한다

     

    그리고 다음과 같이 수정한다

        <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight">
            <item name="windowActionBar">false</item>
            <item name="windowNoTitle">true</item>
            <item name="android:statusBarColor">@android:color/transparent</item>
        </style>

    statusBarColor를 transparent로 설정하면 상태표시줄이 반투명화가 된다

     

    하지만 딱히 맘에 들지 않아서 그냥 상태표시줄을 없애버렸다

    아래 코드는 앱을 전체화면으로 해서 상태표시줄이 보이지 않게 한다

    <item name="android:windowFullscreen">true</item>

     

     

     

    이로써 Navigation Bar는 다시 구현되었다

    이제 Fragment를 전환해보자