반응형

1. AppBar의 정의?

AppBar(앱바)란, 앱에서 화면 위쪽의 꾸밀 수 있는 영역을 의미합니다.  이 앱바 영역에는 이동할 수 있는 내비게이션 아이콘을 배치하거나 로그인 등 여러가지 기능(액션:Action)을 넣을 수 있도록 하여 앱을 좀 더 편리하게 사용할 수 있도록 하는 영역을 말합니다.

2. ActionBar(액션바)의 정의?

ActionBar(액션바)란,  위에서 정의한 AppBar(앱바)의 영역에 실질적으로 네비게이션 아이콘 같은 기능을 넣을 수 있도록 안드로이드 초기부터 제공되던 클래스를 말하는데요, 다만 안드로이드 버전이 업그레이드될 때마다, 즉 버전이 달라질 때마다 다양한 기능이 추가되고 변경되었기 때문에, 기기에 설치된 안드로이드 버전마다 다른 동작을 하게 되는 결과를 초래하게 됩니다. (단점)   이는 다른 말로 버전 하위 호환성 문제가 있다고 합니다. (Backward Compatibility)
예전 버전의 안드로이드 스튜디오에서는 기본적으로 ActionBar가 나타나도록 설정되어 있었지만, 최근 버전부터는 액션바가 나타나지 않도록 NoActionBar 형태로 세팅되어 있습니다.

3. ToolBar(툴바)의 정의?

ToolBar(툴바)란, 위 액션바의 큰 단점을 해결하기 위해, 안드로이드 버전이 달라지더라도 동일한 동작(액션)을 하도록, 안드로이드 5.0 (API Level 21)부터 추가된 위젯(Widget)을 말하는데요, 주로 이 툴바를 사용하여 편리하게 앱바(AppBar) 영역을 만들 수 있도록 하였습니다.   그리고 위젯을 직접 사용하지 않더라도 기본적으로  activity_main.xml에  toolbar.xml을 추가(include)하여 툴바 기능을 하도록 처리할 수 있습니다.

4. ToolBar(툴바) 만들기 예제

그럼, 가장 기본적인 ToolBar(툴바)를 만들어 볼 텐데요.  layout 폴더에 toolbar.xml 파일을 추가하여 activity_main.xml에서  이와 같은 <include layout="@layout/toolbar" />  include 태그를 이용해 툴바기능을 하도록 해볼게요. 우선, 툴바 사용을 위해서는 액션바가 없는 조건으로 해야 하는데요, 기본적으로 NoActionBar로 설정되어 있기에 특별히 건드릴 것은 없습니다.

< 예제 실행 결과 이미지 미리 보기 >

그리고  "← 화살표"와  "Home" 글자와  "☰" 메뉴기호를 각각 터치할 때 어떤 액션을 취할 수 있는데요, 여기서는 간단하게 Toast 명령어로 메시지를 띄워보도록 할게요.


① 그럼, 안드로이드 스튜디오를 실행시키고, 새 프로젝트를 여세요. 

여기서는 프로젝트 이름을 "AppBar_ToolBar"로 했습니다.

 

②  build.gradle.kts에  뷰바인딩 기능 사용을 위해, "viewBinding.isEnabled = true"를 추가하고  "Sync Now"를 클릭해 주세요.

③ layout 폴더에서 마우스 우클릭(RMB) >> New >> Layout Resource File을 선택하여 toolbar.xml 파일을 만들어 주세요.

layout 방식은 RelaytiveLayout으로 해주세요.

④ 툴바에는 하나의 텍스트와 두 개의 이미지를 넣을 건데요, 이 두 개의 이미지는 아래처럼 에셋에서 다운로드하여 처리할게요.

Vector Asset창이 열리면 Clip art를 클릭하세요.

검색창에 "arrow"로 검색하고 "arrow back"를 선택 후, OK 클릭하세요.

 

Color를 클릭하여 흰색(FFFFFF)을 선택하고 Next 클릭 후 Finish를 클릭하세요.

그럼,  안드로이드 스튜디오의 프로젝트 탐색창에  Res >> drawable >> 폴더에 아래와 같이 화살표 파일이 다운로드된 것을 볼 수 있어요.  

동일한 방법으로   "☰" 메뉴 이미지를 추가해 주세요. 


⑤ 그럼, 이제 toolbar.xml 파일의 내용은 아래처럼 해주세요. 

< toolbar.xml 코드 내용 >

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/toolbar"
    android:background="@android:color/holo_red_light">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:padding="18dp">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/iv_backArrow"
            android:layout_centerVertical="true"
            android:src="@drawable/baseline_arrow_back_24"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Home"
            android:textColor="@color/white"
            android:id="@+id/tv_home"
            android:textStyle="bold"
            android:textSize="20dp"
            android:layout_centerVertical="true"
            android:layout_marginStart="30dp"/>

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/iv_menu"
            android:src="@drawable/baseline_menu_24"
            android:layout_centerVertical="true"
            android:layout_alignParentEnd="true"/>
    </RelativeLayout>

</RelativeLayout>

< toolbar.xml  미리 보기 모습 >

 

⑥ activity_main.xml 파일은 아래와 같이 구성해 주세요.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
        <include layout="@layout/toolbar"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        android:textStyle="bold"
        android:text="Hello Rasino!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

⑦ MainActivity.kt 에는 아래와 같이 구성해 주세요.

package com.example.appbar_toolbar

import android.os.Bundle
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import com.example.appbar_toolbar.databinding.ActivityMainBinding
import com.example.appbar_toolbar.databinding.ToolbarBinding
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var toolbarBinding: ToolbarBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        binding = ActivityMainBinding.inflate(layoutInflater)
        toolbarBinding = ToolbarBinding.bind(binding.root.findViewById(R.id.toolbar))
        setContentView(binding.root)

        val backArrow = findViewById<ImageView>(R.id.iv_backArrow)
        val home = findViewById<TextView>(R.id.tv_home)
        val menu = findViewById<ImageView>(R.id.iv_menu)
        backArrow.setOnClickListener{
            Toast.makeText(this, "← 처음 화면으로 이동합니다!", Toast.LENGTH_SHORT).show()
        }
        home.setOnClickListener{
            Toast.makeText(this, "Home을 터치했습니다!", Toast.LENGTH_SHORT).show()
        }
        menu.setOnClickListener{
            Toast.makeText(this, "Menu를 선택했습니다!", Toast.LENGTH_SHORT).show()
        }
    }
}


여기까지 작성하면 toolbar.xml 파일의 내용이 activity_main.xml 파일 속 상단에 나타나게 되어 툴바의 기능을 할 수 있게 됩니다. 

5. 예제 실행 결과 보기

그럼, 결과를 실행해 보면 아래와 같고, 영상으로도 보여드릴게요.

그리고 각각의 이미지나 Home 글자를 터치하게 되면 여러 가지 액션을 줄 수 있는데 여기서는 간단히 Toast 명령어로 메시지만 팝업 시켰어요. 


< 결과 실행 동영상 보기 >


그럼, 오늘도 좋은 하루 보내세요~  ^^

반응형
반응형

 이번 실습은 메인 창에서 흔히 사이드 메뉴라고 하는 Sub Menu를 여는 Drawer 기능에 대해 다루어 보려고 하는데요, 영어 뜻 그대로 마치 서랍(Drawer)을 열고 닫는 기능을 통해 평소에는 메인 화면을 깔끔하게 보여주고 필요시 서브 메뉴를 열어 특정 메뉴를 선택할 수 있도록 해주는 기능입니다. 

 

 먼저 안드로이드 스튜디오를 실행하고 New Project로 아래와 같이 Empty Views Activity를 선택해 주세요.

title 제목으로 Navigation Drawer를 입력했습니다.

Drawer 기능을 이용하려면 적용하고 싶은 곳, 예를 들어 activity_main.xml에 Drawer Layout을 적용해 주면 되는데요, 
그리고 Drawer Layout은 네비게이션 아이콘을 클릭하거나 사이드를 드래그했을 때 기존 레이아웃 위에 새로운 메뉴를 보여주게 되는데, 이것이 바로 Navigation View입니다. 
따라서 Drawer 기능을 이용한다는 뜻은 Drawer Layout과 Navigation View를 세트로 같이 사용하게 되며, 아래와 같은 구조로 사용해야 하니 기억해 주세요.   왜냐하면 메인뷰 화면(View)이 먼저 존재하고 네이게이션뷰가 그 위로 오버랩 되기 때문이죠.  따라서 배치 순서를 Drawer Layout을 먼저 배치하고 그 아래에 Navigation View가 위치해야 합니다. 만약 순서가 바뀔경우 에러가 발생하게 됩니다. (아래 순서 참고)

<DrawerLayout> 
 	....
 
    <ConstraintLayout>
    	...
    </ConstraintLayout>
    
    <NavigationView>
    	...
    </NavigationView>
    
</DrawerLayout>

그럼, 

1. activity_main.xml 파일에 아래와 같이 코드를 구성해 주세요.

<?xml version="1.0" encoding="utf-8"?>
<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/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Rasino IoT!"
            android:textSize="20dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

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

</androidx.drawerlayout.widget.DrawerLayout>

여기서 위와 같이 작성하면, app:headerLayout="@layout/nav_header" 부분에 에러가 날텐데요, activity_main.xml 파일이 있는 res>>layout>> 폴더에 nav_header.xml 파일을 아래처럼 만들어주면 됩니다. 

2. nav_header.xml 파일 생성과 코드 작성

<code>

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="150dp"
    android:background="@android:color/holo_orange_dark">

</androidx.constraintlayout.widget.ConstraintLayout>

<생성결과>

 

3. nav_menu.xml 파일 생성과 코드 작성

그리고  app:menu="@menu/nav_menu"  비부분도 아래처럼 res 폴더에서 마우스 우클릭(RMB) New>>Android Resource Directory를 선택하여 menu 폴더를 만들어주고, 여기에 nav_menu.xml 파일을 생성해 주면 됩니다.

<Code>

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/item1"
        android:title="Item 1"
        android:icon="@drawable/ic_home"/>
    <item
        android:id="@+id/item2"
        android:title="Item 2"
        android:icon="@drawable/ic_home"/>
    <item
        android:id="@+id/item3"
        android:title="Item 3"
        android:icon="@drawable/ic_home"/>
</menu>

<생성 결과>

위 코드에서 Item1~3 앞에 아이콘이 나오도록 하려면 넣고 싶은 아이콘 이미지를 res>>drawable 폴더에 넣어주면 되는데요,  여기서는 간편하게 제공되는 클립아트(Clip Art) 기능인, Vector Asset에서 찾아서 넣었습니다.  그럼, 아래와 res>>drawable 폴더를 RMB 해서 Vector Asset을 클릭해 주세요. 여기서는 모두 동일한 집(Home) 아이콘을 선택했어요. 

아래와 같은 창이 뜨면, Clip art 부분을 클릭하세요.

만약, 여기서 클립아트 부분이 클릭을 해서 아래와 같은 창이 안나오거나 아무 변화가 없다면, 아래 게시글을 참고해서 특정 임시 폴더를 삭제하고 Android Studio를 재실행하면 해결될 수 있으니 참고하세요. 
(클립아트 문제 시 해결방법 : [App개발/Android_Studio] - 【AndroidStudio】 gradle 관련 에러 해결하기! )

그럼, 아래에 보이는 검색창에 home 이라고 입력해서 home 모양의 아이콘을 선택 추가해 주면 됩니다.

 

저장할 때 , 혹은 저장하고서 icon의 이름은 ic_home.xml로 너무 길지 않게 수정해 주었습니다. 

4.  MainActivity.kt 파일 생성과 코드 작성

아래와 같이 메인 액티비티 코드를 작성해 주세요. 

package com.example.navigationdrawer1

import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.drawerlayout.widget.DrawerLayout
import com.example.navigationdrawer1.databinding.ActivityMainBinding
import com.google.android.material.navigation.NavigationView

class MainActivity : AppCompatActivity() {
    lateinit var toggle: ActionBarDrawerToggle
    lateinit var drawerLayout: DrawerLayout
    lateinit var navigationView: NavigationView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)
        drawerLayout = findViewById(R.id.drawerLayout)
        navigationView = findViewById(R.id.nav_view)
        toggle = ActionBarDrawerToggle(this,drawerLayout, R.string.open, R.string.close)
        drawerLayout.addDrawerListener(toggle)
        toggle.syncState()
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        navigationView.setNavigationItemSelectedListener {
            when(it.itemId) {
                R.id.item1 -> Toast.makeText(applicationContext, "Item 1 Clicked", Toast.LENGTH_SHORT).show()
                R.id.item2 -> Toast.makeText(applicationContext, "Item 2 Clicked", Toast.LENGTH_SHORT).show()
                R.id.item3 -> Toast.makeText(applicationContext, "Item 3 Clicked", Toast.LENGTH_SHORT).show()
            }
            true
        }
    }
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if(toggle.onOptionsItemSelected(item)) {
            true
        }
        return super.onOptionsItemSelected(item)
    }
}

위 코드에서 작성 중간에 toggle = ActionBarDrawerToggle(this,drawerLayout, R.string.open, R.string.close)  코드에서,

open이라는 부분과 close라는 부분에서 붉은색으로 표시가 뜰 텐데요,  그때 마우스를 Open 글자 위에 클릭 후 올려놓고 있으면 Sub메뉴가 뜨는데 "Create String Value Resource"를 클릭해서 아래처럼 각각 Open이라는 Value값을 입력해 주세요.  그리고 이어서 Close도 동일하게 진행해 주세요.

< open >

< close도 동일하게 >

그리고 내용에 보면, Drawer 메뉴가 오버랩 되며 열렸을 때 Item 1이나 Item 2, Item 3 등을 각각 선택했을 때 특정 View 페이지로 넘어가게(열게) 할 수도 있으며,  여기서는 간단히 Toast 메시지를 출력하도록 했습니다. 

navigationView.setNavigationItemSelectedListener {
    when(it.itemId) {
        R.id.item1 -> Toast.makeText(applicationContext, "Item 1 Clicked", Toast.LENGTH_SHORT).show()
        R.id.item2 -> Toast.makeText(applicationContext, "Item 2 Clicked", Toast.LENGTH_SHORT).show()
        R.id.item3 -> Toast.makeText(applicationContext, "Item 3 Clicked", Toast.LENGTH_SHORT).show()
    }
    true
}

 

이렇게 하면 기본적으로 작성해야 할 것은 모두 작성했는데요,  실행해 보면, Navigation View를 선택할 수 있는 Bar가 보이지 않는데요,  이는 안드로이드 기본 설정이 NoActionBar가 적용되어 있기 때문에 그렇습니다. 
이 때는  Action Bar가 보이도록 아래처럼   res>> values >> themes 폴더에 있는 themes.xml 파일을 수정해 주세요.  필요 시 night(다크 디스플레이 모드)화면 모드의 themes.xml 메뉴에도 적용해 주세요.

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Base.Theme.NavigationDrawer1" parent="Theme.Material3.DayNight">
        <!-- Customize your light theme here. -->
        <!-- <item name="colorPrimary">@color/my_light_primary</item> -->
    </style>

    <style name="Theme.NavigationDrawer1" parent="Base.Theme.NavigationDrawer1" />
</resources>

 

그리고 실행해 보면 아래처럼 실행 되는 것을 볼 수 있습니다.  삼선 Action Bar 부분을 터치해도 Drawer 메뉴가 열리며,  폰의 왼쪽 라인 부분을 한 손가락으로 살짝 누른 후 왼쪽에서 오른쪽으로 드래그해도 Drawer 메뉴가 열리는 것을 볼 수 있어요. (No ActionBar 사용시)


< 실행 동영상 >


감사합니다. 
오늘도 보람된 하루 되세요~

반응형