맛있는감귤

[Android] BottomBar API를 이용해 하단에 액션바 만들기 본문

Android

[Android] BottomBar API를 이용해 하단에 액션바 만들기

맛있는감귤 2017. 4. 26. 19:46

버전 정보

Android Studio 2.3.1

Android 4.4(Kitkat , minSDK : API 11 HoneyComb)

BottomBar API : https://github.com/roughike/BottomBar


아래 움짤처럼 음악 앱, 다양한 앱에서 하단에 액션 바, 혹은 탭, 버튼이 보여지는 앱을 보신적이 있을거에요.


보통 이 것을 bottombar 라고 부릅니다. 

view flipper나 view pager로 비슷한 기능을 구현할 수 있는데 퀄리티에서 많이 차이나기 때문에 API를 이용하여 만들어보도록 하겠습니다.

들어가기 전에

 - 해당 API github에 개요와 데모 파일이 있으니 그것을 보셔도 됩니다.

 - bottom bar API는 위에 기재된 API말고도 다양한 API가 있지만 저는 roughike이 만든 것을 사용하도록 하겠습니다.

 - Activity가 아닌 Fragment를 사용할 예정입니다.

1. Project 생성

먼저, New Project를 생성하여 Empty Activity를 만들어 주세요.

Minimum SDK는 API 11 : Android 3.0 (HoneyComb) 이상이기만 하면 됩니다. (태블릿도 지원하기 때문)

그럼 MainActivity와 activity_main.xml이 만들어집니다.

1
2
3
4
5
6
7
8
public class MainActivity extends FragmentActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

cs



처음 MainActivity를 보면 AppcompatActivity를 상속하고 있는데

이것을 위 처럼 FragmentActivity로 변경해줍니다.

이제 MainActivity는 Activity가 아닌 Fragment 성질을 가지고 있습니다.


2. bottom bar API 추가

이제 저희가 사용하고 싶은 API를 추가해봐요.

API추가 방법은 

 1) Project Structure - (Modules) App - Dependencies 탭에서 직접 검색하여 추가

 2) 아래 사진에서 보시는 것처럼 프로젝트 구조를 Android 단에서 보면 아래 Gradle Scripts에 build.gradle(Module: app)을 클릭하시면


해당 파일에 들어가보면 아래 같은 dependencies가 있습니다.

다른 것은 건들지 마시고 

compile 'com.roughike:bottom-bar:2.3.1' 

아래처럼 위 코드를 그대로 복사합니다. 

그러면 안드로이드 스튜디오 오른쪽 상단에 동기화할꺼냐고 묻는 알림이 뜨는데 Sync Now 를 눌러서 동기화해줍니다.

1
2
3
4
5
6
7
8
9
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.roughike:bottom-bar:2.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
}
cs

이제 저희는 bottom bar API를 사용할 준비가 됐습니다!


3. Bottom Bar 생성

 1) Bottom Bar Item 생성

저는 3개의 탭 만들어 보겠습니다.

res 폴더 아래에 xml resource 폴더를 만들고 그 안에 xml파일을 만들어 줍니다. (이름은 알아서)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
 
    <tabs>
        <tab
            id="@+id/tab_call_log"
            icon="@drawable/ic_call_black_24dp"
            title="call" />
        <tab
            id="@+id/tab_contacts"
            icon="@drawable/ic_contact_mail_black_24dp"
            title="contacts" />
        <tab
            id="@+id/tab_macro_setting"
            icon="@drawable/ic_message_black_24dp"
            title="macro" />
    </tabs>
</PreferenceScreen>
cs

아이템(탭)의 추가는 자유로이 하시면 됩니다.

github의 API 레퍼런스 보시면 아이콘만 있는 탭, 탭할 때마다 색이 바뀌는 기능을 만들 수도 있으니 참고하세요.

icon은 https://material.io/icons/ 또는 https://romannurik.github.io/AndroidAssetStudio/index.html 이곳에서 만들 수 있어요.

@drawable은 drawable 폴더를 말합니다.


 2) MainActivity에 Bar 띄우기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <FrameLayout
        android:id="@+id/contentContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/bottomBar" />
 
    <com.roughike.bottombar.BottomBar
        android:id="@+id/bottomBar"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        app:bb_tabXmlResource="@xml/bottombar_tabs" />
 
</RelativeLayout>
cs

activity_main.xml에 위 코드를 붙여 넣습니다.

FrameLayout에는 각 탭을 클릭할 때 보여지는 Fragment가 보여지는 공간입니다.

app:bb_tabXmlResource="@xml/bottombar_tabs" 여기 이름은 위에서 만든 xml파일 이름과 동일해야 댐

그리고 FrameLayout과 BottomBar의 id를 지정해줍니다.


4. select 이벤트 구현

이렇게 까지만 해도 하단에 bar가 생성된 것을 보실 수 있습니다.

이제 탭을 클릭 했을 때 이벤트 코드를 작성해줘야 돼요.

1
2
3
4
5
6
7
8
9
10
11
BottomBar bottomBar = (BottomBar) findViewById(R.id.bottomBar);
bottomBar.setOnTabSelectListener(new OnTabSelectListener() {
@Override
public void onTabSelected(@IdRes int tabId) {
          FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
 
          if(tabId == R.id.tab_call_log){
              transaction.replace(R.id.contentContainer, callLogFragment).commit();
          }
     }
});
cs

MainActivity의 onCreate 메소드에 위 코드를 붙여 넣으면 bottom bar를 tab했을 때 id를 구분해 해당 내부코드를 실행하여 Fragment전환이 이루어집니다.


5. Fragment 생성

프래그먼트는 New에서 생성하시면 xml도 같이 만들어지기 때문에 편합니다. 

Fragment는 다양한 기능이 있지만 일단은 구현을 목표로하기 때문에 생성자와 onCreateView만 있어도 상관이 없습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class CallLogFragment extends Fragment {
 
    public CallLogFragment() {
        // Required empty public constructor
    }
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_call_log, container, false);
    }
}
cs

이제 Run을 해보면 아래처럼 text를 출력해주는 것을 볼 수 있습니다.

이후에, 탭마다 Fragment를 생성해줘 이벤트에 추가해주면 됩니다.

각 탭의 UI와 코드는 각 프레그먼트에서 구현하시면 돼요 ㅎㅎ


가독성 문제나 오타 그리고 다른 질문있으면 언제든지 댓글남겨주세요!


아래는 필요하시면 사용하세요.

MainActivity.java

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 
import android.support.annotation.IdRes;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
 
import com.roughike.bottombar.BottomBar;
import com.roughike.bottombar.OnTabSelectListener;
 
public class MainActivity extends FragmentActivity {
 
    private CallLogFragment callLogFragment;
    private ContactsFragment contactsFragment;
    private SetMacroFragment setMacroFragment;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        callLogFragment = new CallLogFragment();
        contactsFragment = new ContactsFragment();
        setMacroFragment = new SetMacroFragment();
 
        initFragment();
 
        BottomBar bottomBar = (BottomBar) findViewById(R.id.bottomBar);
        bottomBar.setOnTabSelectListener(new OnTabSelectListener() {
            @Override
            public void onTabSelected(@IdRes int tabId) {
                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
 
                if(tabId == R.id.tab_call_log){
                    transaction.replace(R.id.contentContainer, callLogFragment).commit();
                }
 
                else if(tabId == R.id.tab_contacts){
                    transaction.replace(R.id.contentContainer, contactsFragment).commit();
 
                }
 
                else if(tabId == R.id.tab_macro_setting){
                    transaction.replace(R.id.contentContainer, setMacroFragment).commit();
 
                }
            }
        });
    }
 
    /*
     App 실행시 보여지는 Fragment 설정.
    */
    public void initFragment(){
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.add(R.id.contentContainer, callLogFragment);
        transaction.addToBackStack(null);
        transaction.commit();
    }
}
 
cs