[컴][안드로이드] 간단한 Material design 경험하기



간단한 material design 을 만들어 보고 싶었다. 그런데 아쉽게도 내 폰은 갤럭시 넥서스 이다. ㅜ.ㅜ
그래서 일단 emulator 에서 돌려볼 생각으로 시작했다.

그래서 구글링을 조금 찾아보니, ref. 1 의 내용을 참고했다.
소스는 ref. 2 에 있다.
  • Tools : Android Studio 1.0.2 / Gradle


Emulator 설치

Nexus 5 를 설치했다.
CPU/ABI(application binary interface) 를 x86 으로 설정하면 되는데, 이때에는
  • Intel x86 Emulator Accelerator(HAXM installer) 
를 설치해야 한다.


HAXM install

  1. SDK manager 를 통해서 download 를 하고, 
  2. <Android_sdk>\extras\intel\Hardware_Accelerated_Execution_Manager

에 가서 .exe 를 실행하면 install 이 된다.

아래 글을 참고하자.
좀 더 자세한 사항은 아래글을 참고하자.



Material design style toolbar

자 이제 여기서 부터는 ref. 4의 내용을 참고해서 설명하겠다. ref. 4 는 Lollipop 이전 버전에서 material design 스타일의 toolbar 를 구현하는 방법을 이야기 해준다.


절차

  1. "Blank Activity with Fragment" project : project 생성
  2. colors.xml 변경 : 원하는 material design 의 색을 설정한다.
  3. themes.xml : themes.xml 에 AppTheme 색 변경
  4. activity_main.xml : activity_main.xml 에 DrawerLayout 추가 / Toolbar 추가
  5. onStart() : MainActivity 의 onCreate() 에 setSupportActionBar


Project 생성

이제부터 material design 의 toolbar 를 사용하는 단순한 activity 하나를 갖는 application 을 만들어 보자. 일단 project 생성을 하자. 순서는 아래와 같다.
  1. New Project 
  2. Application name, Company Domain, Project location 설정
  3.  Minimum SDK 설정
  4. "Blank Activity with Fragment" 를 선택

이러면 ActionBarActivity 를 상속받은 MainActivity 를 하나 얻게 된다. 이부분은 차차 이야기하기로 하고, 이제 toolbar 를 위한 setting 을 하자.

참고로 이렇게 만들어진 fragment_main.xml 에 아래처럼 기본적으로 padding 이 들어가 있다. 개인적으로 padding 을 없애는 것이 훨씬 자연스럽다.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity$PlaceholderFragment">


    <android.support.v7.widget.Toolbar


Set up

Lollipop 이전 버전에서 Material design style 의 toolbar 를 사용하려면 appcompat 이 필요하다.

gradle 설정


// build.gradle
...
dependencies {
    compile "com.android.support:appcompat-v7:21.0.+"
}


ActionBarActivity 를 사용한다.
theme 은 Theme.AppCompat 을 상속받는다.

app/res/values/styles.xml
 <style name="AppTheme" parent="Theme.AppCompat.Light">
        <!-- Set AppCompat’s actionBarStyle -->
        <item name="actionBarStyle">@style/MyActionBarStyle</item>

        <!-- Set AppCompat’s color theming attrs -->
        <item name="colorPrimary">@color/my_awesome_red</item>
        <item name="colorPrimaryDark">@color/my_awesome_darker_red</item>
    </style>

위의 actionBarStyle 은 밑에 있는 ToolBar 사용을 하게 되면, 굳이 필요없다.

Theme 에서 아래의 색상을 자신이 원하는 색으로 정해줄 수 있다.
  • colorPrimary
  • colorPrimaryDark : status bar 에 사용
  • colorAccent : widget 를 색칠할 때 사용하는 colorControlActivated 에서 기본 color 로 사용된다.
  • colorControlNormal
  • colorControlActivated
  • colorControlHighlight
  • colorSwitchThumbNormal
이 color 들이 Lollipop 이전에서는 원하는대로 동작하지 않을 수 있지만, 최대한 가능한 부분까지 적용된다고 한다.

출처 : Using the Material Theme | Android Developers


색을 정할 때 아래 사이트가 도움이 된다.

참고하자.



ActionBar 없애고, ToolBar 사용하기

Toolbar 를 기존의 ActionBar 로 이용할 수 있다. 그리고 기존에 제공하지 않은 형식의 ActionBar 를 원하면 standalone 형태의 Toolbar 를 사용해서 원하는 대로 만들어 사용할 수 있다고 한다.[ref. 4]

직접 toolbar 를 xml 로 inflate 한다.
그리고 theme 에서 사용되는 Actionbar 를 사용하지 않기 위해 .NoActionBar 를 이용한다.


layout/fragment_main.xml
<android.support.v7.widget.Toolbar
                android:id="@+id/my_awesome_toolbar"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:height="?actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />


res/styles.xml
<resources><
!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <!--<item name="colorPrimary">@color/primary_color</item>-->
        <!--<item name="colorPrimaryDark">@color/primary_color_dark</item>-->
    </style>


아래 부분을 추가해 주지 않으면 ActionBar 로서의 기능을 갖지 않는다. 그저 단순히 Bar 하나가 덩그러니 존재할 뿐이다. 아래 setting 을 넣어주는 순간 여기에 Action bar 와 관련된 title 과 ActionProvider 가 추가된다.

아래는 fragment 에 toolbar 가 있는 경우에 대한 코드이다. 여기서는 MainActivity 에서 만들어서 아래처럼 하지 않고, MainActivity 의 onCreate 에서 한다.

fragment 가 onCreate 되고 난 이후에 main_toolbar 의 reference 를 얻을 수 있다.

MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment())
                .commit();
    }

}
@Override
protected void onStart() {
    super.onStart();
    Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar);
    setSupportActionBar(toolbar);
}





ref. 7 에서 이야기하는 바로는 Toolbar 는 단순히 ViewGroup 의 하나이기 때문에 원하는 대로 View 를 끼워넣어서 만들 수 있다고 한다.

관련 자료

  • ref.4 의 Action bar 부분을 보자.
  • ref. 5 에서는 자세한 toolbar theme 설정의 예제를 볼 수 있다.
  • ref. 6 에서 자세한 설명과 함께 toolbar 를 사용하는 예제를 보여준다.
  • ref. 7 에서는 toolbar 에 자신의 원하는 font 와 title 의 위치를 설정하는 방법을 알려준다.



왼쪽 메뉴 넣기

흔히 많이 쓰는 왼쪽 sliding menu, 왼쪽 Drawer 를 추가해 보자. 대략적인 layout 의 모습은 아래와 같다. 자세한 layout xml 은 여기 를 참고하자.

//activity_main.xml

<RelativeLayout>
    <android.support.v4.widget.DrawerLayout>
        <LinearLayout>
            <android.support.v7.widget.Toolbar/>
            <RelativeLayout/>

        </LinearLayout>

        <RelativeLayout android:id="@+id/rl_left_drawer" 
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" 
            android:layout_gravity="start"
            android:background="#ffffffff" />

    </android.support.v4.widget.DrawerLayout>

</RelativeLayout>

이러면 왼쪽 메뉴의 모습까지 갖춰졌다.

여기서 아래처럼 navigation drawer 를 호출하는 icon 을 달아보자.


아래처럼 MainActivity.java 에 code 를 추가하자. 그러면 toggle 아이콘이 생기고 작동한다. [ref.8, ref. 9]

// MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.rl_container_main, new PlaceholderFragment())
                .commit();
    }
    Toolbar toolbar = (Toolbar) findViewById(R.id.tlbr_main);
    setSupportActionBar(toolbar);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.dl_main);
    mDrawerToggle = new ActionBarDrawerToggle(this,
            mDrawerLayout,
            toolbar,
            R.string.app_name,
            R.string.app_name);
    mDrawerLayout.setDrawerListener(mDrawerToggle);
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
}

@Override
public void onBackPressed() {
    if (mDrawerLayout.isDrawerOpen(Gravity.START | Gravity.LEFT)) {
        mDrawerLayout.closeDrawers();
        return;
    }
    super.onBackPressed();
}



back 버튼 추가 하기

UPDATED:
좀 더 간단하게 back button 을 추가할 수 있다. 아래 글을 보고 따라하자.
아래 2개 code 정도만 있으면 된다.
<?xml version="1.0" encoding="utf-8"?>
<manifest...>
    <application>
        ...
        
        <activity
            android:name=".cheese.CheeseDetailActivity"
            android:parentActivityName=".MainActivity">
            <!-- Parent activity meta-data to support 4.0 and lower -->
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity" />
        </activity>
        
    </application>

</manifest>


@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    getActionBar().setDisplayHomeAsUpEnabled(true);
}


----

아래는 Kotlin code 라 조금 헷갈릴 수 있겠지만, 대체로 비슷하니, 이해하는 데는 어렵지 않을 듯 하다. 아래 처럼 setNavigationIcon 을 통해 image 를 설정해 주면 back button 이 생기게 된다.

val toolbar = find<Toolbar>(R.id.tlbr_note)
setSupportActionBar(toolbar)
toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)  // back arrow



action

toolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        MainActivity.this.finish();

    }
});


Source





Advanced

좀 더 자세한 사항을 배우고 싶다면 아래 링크를 참고하자.

Flat button example


Sliding Menu





References

  1. Develop Android Weather App With Material Design
  2. Surviving-with-android/MaterialWeather at master · survivingwithandroid/Surviving-with-android · GitHub
  3. Implementing Material Design in Your Android app
  4. AppCompat v21 — Material Design for Pre-Lollipop Devices!
  5. Android: Changing the Toolbar’s text color and overflow icon color,  October 28, 2014
  6. Using Toolbars in your apps, 16 November 2014
  7. Android toolbar center title and custom font - Stack Overflow
  8. Android 5.0 material design style navigation drawer for KitKat
  9. Creating a Navigation Drawer | Android Developers


댓글 2개:

  1. 안녕하세요. 작성해주신 예문 잘보고 공부하고있습니다.
    그런데 toolbar에서 이벤트를 setnavigationicon에서 등록해준 아이콘을
    눌렀을 때 액티비티를 종료하고싶은데 툴바를 눌러야지만 종료되고
    아이콘을 눌렀을 때는 액티비티가 종료가안되네요
    실례가 안된다면 답변부탁드리겠습니다.. ^^

    답글삭제
    답글
    1. 안녕하세요. 죄송합니다. 제가 코드를 잘못 적어놓은듯 하네요. 아래처럼 setNavigationOnClickListener 를 사용하시면 될 듯 하네요. 위의 글의 code 도 수정하였습니다.

      toolbar.setNavigationOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
      MainActivity.this.finish();

      }
      });

      삭제