Development record of developer who study hard everyday.

레이블이 머티리얼디자인인 게시물을 표시합니다. 모든 게시물 표시
레이블이 머티리얼디자인인 게시물을 표시합니다. 모든 게시물 표시
, , , , , ,

안드로이드 머트리얼 디자인 바텀내비게이션 사용하기

 안드로이드 머트리얼 디자인 Bottom Navigation 사용하기


안드로이드 개발 블로그

회사에서 프로젝트를 하는데 이번에는 바텀 내비게이션을 사용해야했다.

안드로이드 개발에서 무진장 많이 사용되는 컴포넌트이기때문에 이번 기회에 제대로 알아보려고한다.


1. 앱수준의 build.gradle에 dependency 추가

dependencies {

implementation 'com.google.android.material:material:1.5.0'

}

정확히는 모르겠는데 안드로이드 스튜디오 상위버전에서는 자동으로 추가가 되어있다.


2. menu.xml 파일 만들기

menu.xml

res 폴더에 menu 폴더를 만들어서 바텀내비게이션에 쓰일 menu.xml 파일을 만들어준다.

난 파일 이름을 bottom_navigation_menu.xml로 정했다.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/measure_tab"
android:enabled="true"
android:icon="@drawable/i_lightning"
android:title="@string/measuring"
/>
<item
android:id="@+id/space1"
android:enabled="false"
android:title=""
/>
<item
android:id="@+id/search_tab"
android:enabled="true"
android:icon="@drawable/i_search"
android:title="@string/searching"
/>
<item
android:id="@+id/space2"
android:enabled="false"
android:title="" />
<item
android:id="@+id/setting_tab"
android:enabled="true"
android:icon="@drawable/i_setting"
android:title="@string/setting"
/>

</menu>

bottom_navigation_menu.xml 파일의 코드 내용은 위와 같다.

이 프로젝트의 경우 메뉴가 3개만 필요해서 중간에 빈 item을 넣어주었다.


3. xml 파일에 BottomNavigationView 추가

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

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragmentContainerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:name="com.appg.joowon.fragment.SettingFragment"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_navigation_view"/>

<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:menu="@menu/bottom_navigation_menu"
app:itemBackground="@android:color/white"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

주의할 점은

1. FragmentContainerView도 선언해줄 것

2.  BottomNavigation의 속성 중에 app:menu에 직전에 만들어준 bottom_navigation_menu.xml을 넣어준다.

4. 프래그먼트 만들기

프래그먼트 만들기

위의 캡쳐화면의 경로를 따라 프래그먼트를 만들어준다.

(기본적인거라 자세한 내용은 생략...)


5.  바텀 내비게이션 글릭 리스너 설정

private fun initBottomNavigationBar(){

binding.bottomNavigationView.setOnItemSelectedListener { menuItem ->
when(menuItem.itemId){
R.id.measure_tab -> {
if(mainViewModel.isDBConnected.value != true) { //db서버와 먼저 접속후 들어갈 수 있게
showToast(this, getString(R.string.please_connect_to_db))
return@setOnItemSelectedListener false
}
Log.d(TAG, "measure tab click")
supportFragmentManager.beginTransaction().replace(R.id.fragmentContainerView, MeasureFragment()).commitAllowingStateLoss()
true
}
R.id.search_tab -> {
if(mainViewModel.isDBConnected.value != true) { //db서버와 먼저 접속후 들어갈 수 있게
showToast(this, getString(R.string.please_connect_to_db))
return@setOnItemSelectedListener false
}
Log.d(TAG, "search tab click")
supportFragmentManager.beginTransaction().replace(R.id.fragmentContainerView, SearchFragment()).commitAllowingStateLoss()
true
}
R.id.setting_tab -> {
Log.d(TAG, "setting tab click")
supportFragmentManager.beginTransaction().replace(R.id.fragmentContainerView, SettingFragment()).commitAllowingStateLoss()
true
}
else -> {
false
}
}
}
}

바텀 내비게이션에 클릭리스너를 설정해준다.

나 같은 경우에는 데이터 바인딩을 써서 바텀내비게이션에 접근할 때, binding.bottomNavigationView ~ 형식으로 접근한다.

만약, 데이터바인딩이나 뷰바인딩을 사용하지 않는다면, findViewById를 사용해서 BottomNavigationView 객체를 참조해준다.

내가 클릭한 메뉴아이템의 id 값을 통해 열어줄 프래그먼트를 다르게 설정한다.

프래그먼트를 설정하여 열어줄 때는 supportFragmentManager.beginTransaction().replace() 메소드를 사용한다.

바텀내비게이션의 첫 번째 메뉴를 설정할 때는 아래 코드를 사용한다.

binding.bottomNavigationView.selectedItemId = R.id.measure_tab      //첫 화면은 측정탭으로!


6. 바텀내비게이션 디자인하기

바텀내비게이션을 사용할 때 머트리얼 디자인의 바텀내비게이션을 사용했다.

머트리얼 디자인의 최대 장점은 간단하게 다양한 디자인을 설정할 수 있다는 것이다.

https://material.io/components/bottom-navigation/android#bottom-navigation-bar

자세한 내용은 위 링크를 참고하길 바란다.

머트리얼 디자인은 theme.xml 파일에서 대부분의 속성을 정의하는게 편리하다.

<!--bottom navigation-->
<style name="BaseBottomNavigationTheme" parent="Widget.MaterialComponents.BottomNavigationView">
<item name="materialThemeOverlay">@style/ThemeOverlay.JooWon.BottomNavigationView</item>
<item name="labelVisibilityMode">labeled</item>

</style>

<style name="ThemeOverlay.JooWon.BottomNavigationView" parent="">
<item name="colorOnSurface">@color/color_hint</item>
<item name="colorPrimary">@color/default_black</item>
<item name="colorSurface">@android:color/white</item>
</style>


Widget.MaterialComponents.BottomNavigationView 의 속성을 상속받아 BaseBottomNavigationTheme을 만들었다.

labelVisibilityMode 값을 labeled로 설정해서 메뉴의 텍스트제목을 계속 보여주었다.

머트리얼 디자인에서는 "materialThemeOverlay" 속성을 통해 색상값을 변경해준다.

ThemeOverlay.Joowon.BottomNavigationView 스타일을 만들어서 materialThemeOverlay에 넣어준다.

ThemeOverlay.Joowon.BottomNavigationView 내용을 살펴보면,

colorSurface가 바텀 내비게이션의 배경색이다. 여기서는 하얀색으로 설정해주었다.

colorPrimary는 바텀 내비게이션의 메뉴 아이콘이 활성화 되었을 때 색이다.

colorOnSurface는 바텀 내비게이션의 메뉴 아이콘이 비활성화 되었을 때 색이다.

이렇게 내가 사용할 bottomNavigation의 스타일 속성인 BaseBottomNavigationTheme을 만들고 app의 스타일 속성에 넣어준다.

<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.JooWon" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/joowon_color</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/joowon_light_color</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/joowon_light_color</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">@android:color/white</item>
<item name="android:windowLightStatusBar" tools:targetApi="M">true</item>
<!-- Customize your theme here. -->

<item name="bottomNavigationStyle">@style/BaseBottomNavigationTheme</item>

</style>

bottomNaviagationStyle 속성에 넣어주었다.


이렇게되면 코드에서 바텀 내비게이션이 어떻게 동작하는지 그리고 디자인까지 설정 완료하였다.



Share:
Read More
, , , , ,

안드로이드 머트리얼 디자인에 대해 알아보자

 안드로이드 머트리얼 디자인(Material Design)


회사에서 입사한지 6개월 만에 첫 신규프로젝트에 투입이 되었다.

신입개발자이다보니까 제플린을 보면서 화면을 그리는 것조차 쉽지 않았다.

구글에서 머트리얼 디자인을 권장하는 것을 알기때문에 이번에 처음으로 공부하면서 사용해보았다.

처음에는 사용법이 좀 낯설어서 시행착오가 있었지만 좀 익숙해져가니 정말 좋은 디자인 툴이라는 것을 알게되었다.

코드량이 줄고 사용법도 너무 간단하기 때문이다.

머트리얼 디자인 공식페이지에 나온 가이드문서를 참고하여 머트리얼 디자인에 대한 가이드를 적어보겠다. 


1. 머트리얼 테마

머트리얼 테마는 뷰 컴포넌트들을 쉽게 커스텀하면서도 브랜드의 컨셉을 잘 나타주는 표현방식이다.

머트리얼 테마는 3가지로 구성되어있다.

먼저, 테마를 정의한다.

다음, 컴포넌트에 테마를 적용한다.

마지막으로, 코드에서 그 컴포넌트를 사용한다.

머트리얼 디자인에는 기본적으로 적용된 테마가있는데 개발자가 얼마든지 커스텀하여 사용가능하다.


2. 머트리얼 테마 구현하기

<색>

머트리얼 테마 색상

머트리얼 디자인에서는 12가지의 색상 카테고리를 제공한다.

이 12가지의 색상 카테고리를 가지고 뷰 컴포넌트들을 손쉽게 꾸밀 수가 있다.

-Primary and secondary colors

Primary color는 주로 앱바나 버튼 같은 컴포넌트에 사용된다.

Secondary color는 floating action button이나 선택도구 같은 악센트를 주는 컴포넌트에 사용된다.

 - Surface, background and error colors

Surface, background 그리고 error colors는 브랜드를 나타내는 색상은 아니다.

Surface color는 카드나 시트 같은 컴포넌트에 사용된다.

Background color는 스크롤 가능한 컨텐트에 사용된다.

Error color는 텍스트 필드에서 에러를 나타내는데 사용된다.

-"On" colors

쉽게 말하면, 원래의 카테코리 색이름과 대비되는 색들을 말한다.

예를들어, OnPrimary color는 컴포넌트에서 사용된 Primary color와 대비되는 색이라고 생각하면 된다.

<글꼴>

정확히 말하면 Typography인데 뭐라 번역을 하는게 제일 자연스러울까? ㅎ

대충 알아듣자....

글꼴과 관련해서는 13가지의 카테고리가 존재한다.

이것들을 활용하여 family, font, case, size 그리고 tracking까지 커스텀이 가능하다.

머트리얼 디자인 글꼴

-Headings

Headlines 1-6은 가장 큰 글꼴 사이즈이다.

Subtitles는 헤드라인 보다 작고 부제에 사용한다.

Body text는 긴 설명문에 사용한다.

Catpion과 overline은 가장 작은 글꼴 사이즈다. 이미지의 태그나 헤드라인의 요약에 사용된다.

Button text는 버튼에 사용된다.


<모양>

Shape system은 모서리 모양을 결정한다.

Rounded와 Cut이 존재한다.

-Rounded shapes

카드, 메뉴, 스낵바 등은 기본적으로 4dp의 rounded shape이 적용되어있다.

-Square shapes


0dp의 rounded shape이라고 생각하면 된다.

-Cut shapes


설명 생략...

<Icon>


머트리얼 디자인 아이콘

₁. Filled ₂. Sharp ₃. Rounded ₄. Outlined ₅. Two-Tone 

머트리얼 디자인에는 5가지의 아이콘 카테고리가 존재한다. 


Share:
Read More
, , ,

머터리얼 디자인 - 텍스트필드 공부하기(1)




Material Design에 대해서 공부를 좀 해보려고한다.

일단 오늘은 텍스트필드에 대해서 공부를 해보겠다.

텍스트필드는 우리가 흔히 쓰는 EditText와 같다.

그런데 비주얼적인 효과를 더 낼수가 있어서 프로젝트를 수행할 때 매우 큰 도움이 될 것 같다.


오늘 기술할 내용은 위 링크에 있는 내용들을 번역한 내용이니 참고하기 바란다.

머터리얼 디자인 텍스트필드

우선 머터리얼 디자인에서 EditText를 구현할 때는 TextInputLayout과 TextInputEditText를 같이 사용해야한다.



app:startIconDrawable을 통해서 텍스트필드 왼쪽에 아이콘을 넣을 수 있다.



오른쪽에 아이콘을 넣으려면 app:endIconMode="password_toggle"를 사용한다.
그리고 요즘에 비밀번호창에 입력한 내용을 가리게하는 앱들이 많은데 머터리얼 디자인을 활용하면 쉽게 구현이 가능하다.


한 번에 지울 수 있는 기능도 지원한다.


아이콘을 커스텀하고 싶을 때는 위 화면처럼 설정을 바꿔줘야한다.


코드로 커스텀을 할 시에는 위 리스너를 활용하면된다.
추후에 이 리스너들을 활용해서 아이디, 비밀번호 유효성 검사를 해보도록 하겠다.


드랍다운 메뉴도 텍스트필드로 구현이 가능하다.

이건 공식페이지에 오류가 좀 있어서 내 코드로 예시를 보여주겠다.

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/textField"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense.ExposedDropdownMenu"
app:layout_constraintTop_toBottomOf="@+id/no1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<AutoCompleteTextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
/>
</com.google.android.material.textfield.TextInputLayout>
위 코드는 드롭다운 메뉴를 표현한 xml 코드다.

<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">

<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceSubtitle1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>

</androidx.constraintlayout.widget.ConstraintLayout>
그리고 간단하게 위 코드처럼 list_item.xml 파일을 만들어준다.
드롭다운 메뉴의 각각의 메뉴에 해당하는 xml이다.

class MainActivity : AppCompatActivity() {


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

val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this,
R.layout.activity_main)

val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

binding.lifecycleOwner = this
binding.viewModel = viewModel

val items = listOf("Material", "Design", "Components", "Android")
val adapter = ArrayAdapter(this, R.layout.list_item, R.id.textView ,items)
(binding.textField?.editText as? AutoCompleteTextView)?.setAdapter(adapter)

}

}
그리고 메인액티비티의 코드다.
items라는 리스트를 만들어준다. (드롭다운 메뉴의 각각에 해당하는 글자들이다.)
ArrayAdpater를 생성해준다.
공식홈페이지에서는 ArrayAdapter(this, R.layout.list_item, items) 로 만들어주면 된다고하는데 그렇게하면 에러가 난다.

꼭! list_item.xml에 텍스트뷰의 id를 ArrayAdapter 만들어줄 때 넣어주어야한다.
그다음에 setAdapter(adapter)를 해주면 된다.


결과는 위 화면과 같다.








Share:
Read More