[Android Studio] 사이드바 만들기

노유성·2023년 4월 16일
0
post-thumbnail

🌞레이아웃 만들기

🪐drawerlayout.xml

사이드바에 들어갈 메뉴 아이템을 만들어야 한다.
경로: res/menu/drawerlayout.xml

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

    <item
        android:id="@+id/menuitem1"
        android:title="menuItem1" />
    <item
        android:id="@+id/menuitem2"
        android:title="menuItem2" />
    <item
        android:id="@+id/menuitem3"
        android:title="menuItem3" />
</menu>

나중에 item에 사이드바에 넣을 메뉴들을 넣으면 된다.

🪐appbar.xml

메인화면에서 보여줄 appbar를 만든다.
경로: res/layout/appbar.xml

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

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary" />
    </com.google.android.material.appbar.AppBarLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

androidx.coordinatorlayout.widget.CoordinatorLayout

androidx.coordinatorlayout.widget.CoordinatorLayout은 AndroidX 라이브러리에서 제공되는 클래스 중 하나입니다. 이 클래스는 FrameLayout을 상속하면서, 컨텐츠나 뷰의 동작을 조정하거나 애니메이션 효과를 적용하는 데 유용한 레이아웃입니다.
CoordinatorLayout은 특정 뷰와 다른 뷰의 동작을 연동시키기 위한 "Coordinator"를 사용하여 작동합니다.
예를 들어, AppBarLayout을 CoordinatorLayout 내부에 배치하면 AppBarLayout은 스크롤 이벤트에 반응하여 스크롤되면서 자동으로 크기를 조절할 수 있습니다.
CoordinatorLayout은 Material Design 가이드라인에서 권장하는 레이아웃 중 하나로, 머터리얼 디자인을 구현하려는 앱에서 자주 사용됩니다.
-chatGPT

com.google.android.material.appbar.AppBarLayout

com.google.android.material.appbar.AppBarLayout은 구글에서 제공하는 머티리얼 디자인 라이브러리(Material Design Library)의 일부로, 앱바(App Bar)를 구현할 때 사용되는 클래스입니다.
AppBarLayout은 다양한 스크롤 효과를 지원하여, 앱바의 크기나 위치를 자동으로 조절할 수 있습니다.
예를 들어, CollapsingToolbarLayout과 함께 사용하면 스크롤에 따라 앱바를 축소하거나 확대하는 효과를 적용할 수 있습니다.
AppBarLayout은 머티리얼 디자인을 적용하는 앱에서 자주 사용되며, CoordinatorLayout과 함께 사용하여 다양한 애니메이션 효과를 구현할 수 있습니다.
-chatGPT

androidx.appcompat.widget.Toolbar

androidx.appcompat.widget.Toolbar는 안드로이드X(AndroidX) 라이브러리에서 제공하는 클래스로, 앱바(App Bar)를 구현하는 데 사용되는 위젯입니다.
Toolbar는 이전에 사용되던 ActionBar와 비슷한 역할을 하지만, 더욱 유연하고 개발자가 커스터마이징하기 쉬운 기능을 제공합니다. 예를 들어, Toolbar를 사용하면 앱바에 임의의 뷰나 위젯을 추가할 수 있으며, 앱바의 디자인도 개발자가 직접 지정할 수 있습니다.
Toolbar는 ActionBar와 달리 반드시 AppBarLayout와 함께 사용되어야 하며, 이를 통해 스크롤에 따라 앱바가 확장/축소되는 효과 등을 구현할 수 있습니다
-chatGPT

그렇다고 한다. Toolbar를 만들 때 참고하자.

🌈android 라이브러리

안드로이드 - 네비게이션 드로어(Navigation Drawer)를 활용하여 슬라이드 메뉴 구현하기
위 사이트를 참고하여서 만들었는데 해당 사이트에서는 android 라이브러리를 사용하고 있다. 하지만 지금 대부분의 android studio에서는 androidx 라이브러리를 지원하고 있다. 그래서 특정 view(위에서 설명한 것들 layout, textview 등등)를 현재 라이브러리에 맞게 변환하고 싶으면 chatGPT에게 물어보면 된다!

🪐header.xml

사이드바에서 메뉴바를 보여주기 이전에 위에 보여주는 헤더이다. 주로 이 부분에 사용자의 정보나 프로필을 보여주면 된다.
경로: res/menu/header.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="@color/cardview_dark_background"
    android:gravity="center"
    android:orientation="vertical"
    android:theme="@style/ThemeOverlay.AppCompat.Dark">

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Select Item"
        android:textSize="50dp" />

</LinearLayout>

위 예제에서는 TextView 객체를 만들어서 보여주고 있지만 imageView를 이용해서 보여줄 수도 있고 프로필 아이콘을 만들어서 프로필 바로가기를 만들 수도 있을 것 같다.

⭐기능 구현

🪐activity_main.xml

app bar 추가하기

구현한 appbar를 main.xml 파일에 추가한다.

<include
        layout="@layout/appbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

이렇게 추가를 하면 onCreate() method에서 setContentView() method로 activity_main 레이아웃의 view 객체들을 불러올 때 appbar 레이아웃의 객체들도 불러올 수 있게 된다.

<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"
        android:fitsSystemWindows="true"
        app:menu="@menu/drawerlayout"
        app:headerLayout="@layout/header"/>

사이드바를 구현한 view객체이며 마지막 두 줄은 menu를 담은 drawerlayout을 가져와서 설정하고 만들어놓은 헤더도 가져온 속성이다.

뒤에서 헷갈릴 수도 있으니 강조하자면 얘는 Drawer객체이다. (!= DrawerLayout)

🪐InitializeLayout()

처음 activity가 생성되면 onCreate() 메소드가 실행되는데 이 때 같이 실행해줄 메소드를 구현했다.

App bar 생성

public void InitializeLayout() {
        //toolBar를 통해 App Bar 생성
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //App Bar의 좌측 영영에 Drawer를 Open 하기 위한 Incon 추가
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 		getSupportActionBar().setHomeAsUpIndicator(R.drawable.menuicon);

toobar 객체의 참조를 toolbar 변수에 할당한 후 actionbar로 설정한다.

getSupportActionBar()는 현재 Activity에서 사용 중인 Appbar를 가져오는 메소드이며
setDisplayHomeAsUpEnabled(true)로 appbar 좌측에 "화살표 모양"의 버튼을 표시할 수 있다.
setHomeAsUpIndicator(R.drawable.menuicon)는 인자로 이미지 리소스를 전달하며 설정된 버튼을 클릭하면 네비게이션 드로어가 열린다.

하지만 아직 DrawerLayout과 ActionBarDrawerToggle 객체를 연결해주지 않았기 때문에 버튼을 클릭한다고 네비게이션 드로어가 열리지 않는다.

DrawerLayout에 드로어 리스너 설정

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

ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(
                this,
                drawer,
                toolbar,
                R.string.open,
                R.string.closed
        );
drawer.addDrawerListener(actionBarDrawerToggle);

메인 xml파일에 만들어놓은 DrawerLayout의 id를 가져와 drawer 객체를 만든다. 여기서는 main xml 파일의 최상단 레이아웃을 의미한다.
그 후에 actionBarDrawerToggle 객체를 만든다. 인자는 다음과 같다.

  • 설정할 activity 객체, 일반적으로 this
  • 드로어를 포함한 DrawerLayout 객체, 예제에서는 방금 가져온 drawer이다. 포인트는 Drawer를 가져오는 것이 아니라 DrawerLayout 객체를 가져온다는 점이다
  • 드로어가 열리는 경우 나타나는 문자열의 리소스
  • 드로어가 닫히는 경우 나타나는 문자열의 리소스

3, 4번은 잘 안 쓴다고 한다.

드로어의 메뉴에 리스너 설정

		// navigation 객체에 nav_view의 참조 반환
		NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        // navigation 객체에 이벤트 리스너 달기
        navigationView.setNavigationItemSelectedListener(menuItem -> {
            switch (menuItem.getItemId())
            {
                case R.id.menuitem1:
                    Toast.makeText(getApplicationContext(), "SelectedItem 1", Toast.LENGTH_SHORT).show();
                case R.id.menuitem2:
                    Toast.makeText(getApplicationContext(), "SelectedItem 2", Toast.LENGTH_SHORT).show();
                case R.id.menuitem3:
                    Toast.makeText(getApplicationContext(), "SelectedItem 3", Toast.LENGTH_SHORT).show();
            }
            drawer.closeDrawer(GravityCompat.START);
            return true;
        });

먼저 Drawer 객체를 id로 찾아와서 navigationView에 할당한다.
그 다음 setNavigationItemSelectedListener() method를 실행하면 되는데 인자로 들어가는 값이 콜백함수이다. (java에서는 람다식이라고 부른단다)

Drawer 객체에 이미 정의된 menu를 누르면은 리스너의 콜백함수가 실행된다.
인자로 menuItem 객체가 넘어가며 getItemId() method를 이용해서 item 객체의 id를 얻은 후에 id값을 기준으로 다음 action을 정의하면 된다. 해당 예제에서는 Toast메세지를 띄웠다.

🌌정리하며

사이드바를 구현하기 위해서 필요한 것은 다음과 같다.

  • Drawer: 주로 main xml파일에 정의된다.
  • header: Drawer 상단에 보여주는 헤더이며 Drawer view를 정의할 때 headerLayout 속성으로 정의된다.
  • menu: Drawer의 메뉴 아이템이며 Drawer view를 정의할 때 menu 속성으로 정의된다.
  • Appbar: 메뉴버튼을 넣을 Appbar도 구현해야한다.

그리고 구현 순서는 다음과 같다.

  • 앱바를 설정한다.
  • 앱바에 메뉴 아이콘을 만든다.
  • acitonBar와 DrawerLayout을 연결한다.
  • DrawerLayout에 정의된 Drawer객체에 이벤트 리스너를 등록한다.(객체의 menuItem객체를 처리하는)
profile
풀스택개발자가되고싶습니다:)

0개의 댓글