본문 바로가기

안드로이드

상단 탭 만들기

반응형
https://choheeis.github.io/newblog//articles/2020-07/CoordinatorLayout
CoordinatorLayout에 대한 설명

 

탭은 네이게이션 위젯으로 불리기도 하며, 상단 탭은 액션바에 탭 기능을 넣어 보여주는 방법으로 제공되며, 하단 탭은 별도의 위젯으로 제공된다

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?colorPrimaryDark"
                android:elevation="1dp"
                android:theme="@style/ThemeOverlay.AppCompat.Dark">

                <TextView
                    android:id="@+id/titleText"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="타이틀"
                    android:textAppearance="@style/TextAppearance.AppCompat.Title" />

            </androidx.appcompat.widget.Toolbar>

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/background_light"
                android:elevation="1dp"
                app:tabGravity="fill"
                app:tabMode="fixed"
                app:tabSelectedTextColor="?colorAccent"
                app:tabTextColor="?colorPrimary" />

        </com.google.android.material.appbar.AppBarLayout>

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"></FrameLayout>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

</RelativeLayout>

 

CoordinatorLayout은 액션바 영역을 포함한 전체 화면의 위치를 잡아주는 역할을 하므로 가장 바깥에 위치한다

CoordinatorLayout 안에 AppBarLayout과 다른 레이아웃을 넣으면 그 둘 간의 간격이나 위치가 자동으로 결정된다

 

AppBarLayout은 액션바를 가리키는데 이 안에는 Toolbar가 들어갈 수 있으며, 탭을 사용하는 경우에는 탭의 버튼들이 들어갈 수 있는 TabLayout을 추가할 수 있다

AppBarLayout 아래쪽에는 FrameLayout을 넣어 화면의 내용을 구성할 수 있다

 

ToolBar 안에는 텍스트뷰를 하나 넣어 제목을 표시할 수 있다

 

TabLayout에는 여러가지 속성이 들어갈 수 있는데, tabMode의 값을 fixed로 하고 tabGravity의 값을 fill로 설정하여

[탭] 버튼들이 동일한 크기를 갖게 만든다

 

탭을 3개 만들어서, 각각의 탭을 누를 때마다 하단에 다른 내용이 보이도록 할 수 있다

FrameLayout으로 하단에 공간을 확보한 후 그 안에 상황에 따라 서로 다른 프래그먼트를 넣어줄 수 있다

 

app/res/layout/fragment1.xml

<?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="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="첫 번째" />
</LinearLayout>

 

app/res/layout/fragment1.xml

<?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="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="첫 번째" />
</LinearLayout>

 

app/res/layout/fragment2.xml

<?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="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="두 번째" />
</LinearLayout>

 

app/res/layout/fragment3.xml

<?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="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="세 번째" />
</LinearLayout>

 

Fragment1.java

package com.example.a33_sampletab;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class Fragment1 extends Fragment {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment1, container, false);
    }
}

 

Fragment2.java

package com.example.a33_sampletab;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;

public class Fragment2 extends Fragment {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment2, container, false);
    }
}

 

Fragment3.java

package com.example.a33_sampletab;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;

public class Fragment3 extends Fragment {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment3, container, false);
    }
}

 

MainActivity

package com.example.a33_sampletab;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;

import android.os.Bundle;
import android.util.Log;

import com.google.android.material.tabs.TabLayout;

public class MainActivity extends AppCompatActivity {

    //   androidx.appcompat.widget.Toolbar로 임포트해야 setSupportActionBar 메소드가 호출된다
    Toolbar toolbar;

    Fragment1 fragment1;
    Fragment2 fragment2;
    Fragment3 fragment3;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        toolbar = findViewById(R.id.toolbar);

//        setSupportActionBar 메소드는 액티비티에 디폴트로 만들어진 액션바가 없을 경우에만 작동한다
//        그런데 프로젝트가 만들어질 때 메인 액티비티에는 자동으로 액션바가 만들어진다
//        이것은 테마를 액션바가 들어있는 테마로 설정했기 때문이다
//        이대로 시작하면 에러가 뜬다 - Caused by: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.
//        액티비티에 설정된 테마를 변경하려면 /app/res/values/themes.xml 파일을 수정해야한다
        setSupportActionBar(toolbar);

//        액션바에서 기본적으로 표시되는 타이틀을 없애기, activity_main.xml에 만들어놓은 AppBarLayout/Toolbar/TextView로 대체됨
        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayShowTitleEnabled(false);

        fragment1 = new Fragment1();
        fragment2 = new Fragment2();
        fragment3 = new Fragment3();

        getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment1).commit();

//        TabLayout에 탭 추가
        TabLayout tabLayout = findViewById(R.id.tabLayout);
        tabLayout.addTab(tabLayout.newTab().setText("통화기록"));
        tabLayout.addTab(tabLayout.newTab().setText("스팸기록"));
        tabLayout.addTab(tabLayout.newTab().setText("연락처"));

        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                int position = tab.getPosition();
                Log.d("MainActivity", "선택된 탭 : " + position);

                Fragment selected = null;

                if (position == 0) {
                    selected = fragment1;
                } else if (position == 1) {
                    selected = fragment2;
                } else if (position == 2) {
                    selected = fragment3;
                }

                getSupportFragmentManager().beginTransaction().replace(R.id.container, selected).commit();
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });


    }
}

 

반응형