Bottom Navigation
<?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.appcompat.widget.Toolbar
android:id="@+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="35dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/logo_title">
</ImageView>
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
<LinearLayout
android:id="@+id/toolbar_division"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorDivision"
android:orientation="horizontal"
android:layout_below="@id/my_toolbar"/>
<FrameLayout
android:id="@+id/main_content"
android:layout_below="@id/toolbar_division"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/nav_division"/>
<LinearLayout
android:id="@+id/nav_division"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorDivision"
android:orientation="horizontal"
android:layout_above="@id/bottom_navigation"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:background="@color/colorWhite"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_navigation_main">
</com.google.android.material.bottomnavigation.BottomNavigationView>
</RelativeLayout>
bottomNavigation을 추가하여보자. 여기에 menu를 적용하기 위해 menu res를 만들어야 한다.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_home"
android:icon="@drawable/ic_home"
android:enabled="true"
android:title="@string/home"/>
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
android:enabled="true"
android:title="@string/search"/>
<item
android:id="@+id/action_add_photo"
android:icon="@drawable/ic_add_a_photo"
android:enabled="true"
android:title="@string/gallery"/>
<item
android:id="@+id/action_favorite_alarm"
android:icon="@drawable/ic_favorite_border"
android:enabled="true"
android:title="@string/favorite"/>
<item
android:id="@+id/action_account"
android:icon="@drawable/ic_account"
android:enabled="true"
android:title="@string/account"/>
</menu>
간단하게 id와 icon정도만 정의해주면 된다.
이제 navigation에서 icon이 클릭되었을 때 처리 로직만 만들어주면 간단하게 처리할 수 있다.
icon이 클릭되었을 때 main_content에 Fragment를 바꿔줄 것이다. 일단은 구분만 되도록 색상만 바꾼 간단한 Fragment를 구성해보자.
<?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.appcompat.widget.Toolbar
android:id="@+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="35dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/logo_title">
</ImageView>
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
<LinearLayout
android:id="@+id/toolbar_division"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorDivision"
android:orientation="horizontal"
android:layout_below="@id/my_toolbar"/>
<FrameLayout
android:id="@+id/main_content"
android:layout_below="@id/toolbar_division"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/nav_division"/>
<LinearLayout
android:id="@+id/nav_division"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorDivision"
android:orientation="horizontal"
android:layout_above="@id/bottom_navigation"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:background="@color/colorWhite"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_navigation_main">
</com.google.android.material.bottomnavigation.BottomNavigationView>
</RelativeLayout>
package com.example.firstapp.navigation
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.firstapp.R
class DetailViewFragment: Fragment(){
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
var view = LayoutInflater.from(activity).inflate(R.layout.fragment_detail,container,false)
return view
}
}
MainActivity에서 클릭 처리를 해주자.
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when(item.itemId){
R.id.action_home -> {
var detailViewFragment = DetailViewFragment()
supportFragmentManager.beginTransaction().replace(R.id.main_content, detailViewFragment).commit()
return true
}
R.id.action_search -> {
var gridFragment = GridFragment()
supportFragmentManager.beginTransaction().replace(R.id.main_content, gridFragment).commit()
return true
}
R.id.action_add_photo -> {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){
startActivity(Intent(this, AddPhotoActivity::class.java))
}
return true
}
R.id.action_favorite_alarm -> {
var alarmFragment = AlarmFragment()
supportFragmentManager.beginTransaction().replace(R.id.main_content, alarmFragment).commit()
return true
}
R.id.action_account -> {
var userFragment = UserFragment()
supportFragmentManager.beginTransaction().replace(R.id.main_content, userFragment).commit()
return true
}
}
return false
}
item이 어떤 것이 클릭되냐에 따라 FragmentManager를 통해 replace를 하자.
중간에 에러를 방지하기 위해 Transaction으로 처리하자.

그리고 다른 기능과 다르게 사진을 업로드하기 위해서는 권한과 firebase설정이 필요하다.
https://console.firebase.google.com/
로그인 - Google 계정
하나의 계정으로 모든 Google 서비스를 Google 계정으로 로그인
accounts.google.com
프로젝트에서 storage를 설정하면 된다.
그리고 Manifest에서 read_permission을 설정해주자.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
이제 마지막으로 업로드처리만 해주면 된다.
class AddPhotoActivity : AppCompatActivity() {
var PICK_IMAGE_FROM_ALBUM = 0
var storage: FirebaseStorage? = null
var photoUri: Uri? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_photo)
var addPhotoBtnUpload = findViewById<Button>(R.id.addPhoto_btn_upload)
//Initiate storage
storage = FirebaseStorage.getInstance()
//Open the album
var photoPickerIntent = Intent(Intent.ACTION_PICK)
photoPickerIntent.type = "image/*"
startActivityForResult(photoPickerIntent, PICK_IMAGE_FROM_ALBUM)
//add image upload event
addPhotoBtnUpload.setOnClickListener {
contentUpload()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
var addPhotoImage = findViewById<ImageView>(R.id.addPhoto_image)
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == PICK_IMAGE_FROM_ALBUM){
if(resultCode == Activity.RESULT_OK){
//path to the selected image
photoUri = data?.data
addPhotoImage.setImageURI(photoUri)
}else{
//cancel
finish()
}
}
}
fun contentUpload() {
//make filename
var timestamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
var imageFileName = "IMAGE_" + timestamp + "_.png"
var storageRef = storage?.reference?.child("image")?.child(imageFileName)
storageRef?.putFile(photoUri!!)?.addOnSuccessListener {
Toast.makeText(this, getString(R.string.upload_image),Toast.LENGTH_LONG).show()
}
}
}

화면에 보이는 것과 같이 사진을 선택하는 창이 띄워진다.
사진을 선택하면 다음과 같은 화면이 나온다.

코드에서 보면 선택이 완료된다면 image를 띄워주는 startActivityOnResult함수가 있다.
또한, '사진올리기' 버튼에 리스너를 달아 pufile 처리를 해주었다.
Bottom Navigation
<?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.appcompat.widget.Toolbar
android:id="@+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="35dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/logo_title">
</ImageView>
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
<LinearLayout
android:id="@+id/toolbar_division"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorDivision"
android:orientation="horizontal"
android:layout_below="@id/my_toolbar"/>
<FrameLayout
android:id="@+id/main_content"
android:layout_below="@id/toolbar_division"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/nav_division"/>
<LinearLayout
android:id="@+id/nav_division"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorDivision"
android:orientation="horizontal"
android:layout_above="@id/bottom_navigation"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:background="@color/colorWhite"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_navigation_main">
</com.google.android.material.bottomnavigation.BottomNavigationView>
</RelativeLayout>
bottomNavigation을 추가하여보자. 여기에 menu를 적용하기 위해 menu res를 만들어야 한다.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_home"
android:icon="@drawable/ic_home"
android:enabled="true"
android:title="@string/home"/>
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
android:enabled="true"
android:title="@string/search"/>
<item
android:id="@+id/action_add_photo"
android:icon="@drawable/ic_add_a_photo"
android:enabled="true"
android:title="@string/gallery"/>
<item
android:id="@+id/action_favorite_alarm"
android:icon="@drawable/ic_favorite_border"
android:enabled="true"
android:title="@string/favorite"/>
<item
android:id="@+id/action_account"
android:icon="@drawable/ic_account"
android:enabled="true"
android:title="@string/account"/>
</menu>
간단하게 id와 icon정도만 정의해주면 된다.
이제 navigation에서 icon이 클릭되었을 때 처리 로직만 만들어주면 간단하게 처리할 수 있다.
icon이 클릭되었을 때 main_content에 Fragment를 바꿔줄 것이다. 일단은 구분만 되도록 색상만 바꾼 간단한 Fragment를 구성해보자.
<?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.appcompat.widget.Toolbar
android:id="@+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="35dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/logo_title">
</ImageView>
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
<LinearLayout
android:id="@+id/toolbar_division"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorDivision"
android:orientation="horizontal"
android:layout_below="@id/my_toolbar"/>
<FrameLayout
android:id="@+id/main_content"
android:layout_below="@id/toolbar_division"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/nav_division"/>
<LinearLayout
android:id="@+id/nav_division"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorDivision"
android:orientation="horizontal"
android:layout_above="@id/bottom_navigation"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:background="@color/colorWhite"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_navigation_main">
</com.google.android.material.bottomnavigation.BottomNavigationView>
</RelativeLayout>
package com.example.firstapp.navigation
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.firstapp.R
class DetailViewFragment: Fragment(){
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
var view = LayoutInflater.from(activity).inflate(R.layout.fragment_detail,container,false)
return view
}
}
MainActivity에서 클릭 처리를 해주자.
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when(item.itemId){
R.id.action_home -> {
var detailViewFragment = DetailViewFragment()
supportFragmentManager.beginTransaction().replace(R.id.main_content, detailViewFragment).commit()
return true
}
R.id.action_search -> {
var gridFragment = GridFragment()
supportFragmentManager.beginTransaction().replace(R.id.main_content, gridFragment).commit()
return true
}
R.id.action_add_photo -> {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){
startActivity(Intent(this, AddPhotoActivity::class.java))
}
return true
}
R.id.action_favorite_alarm -> {
var alarmFragment = AlarmFragment()
supportFragmentManager.beginTransaction().replace(R.id.main_content, alarmFragment).commit()
return true
}
R.id.action_account -> {
var userFragment = UserFragment()
supportFragmentManager.beginTransaction().replace(R.id.main_content, userFragment).commit()
return true
}
}
return false
}
item이 어떤 것이 클릭되냐에 따라 FragmentManager를 통해 replace를 하자.
중간에 에러를 방지하기 위해 Transaction으로 처리하자.

그리고 다른 기능과 다르게 사진을 업로드하기 위해서는 권한과 firebase설정이 필요하다.
https://console.firebase.google.com/
로그인 - Google 계정
하나의 계정으로 모든 Google 서비스를 Google 계정으로 로그인
accounts.google.com
프로젝트에서 storage를 설정하면 된다.
그리고 Manifest에서 read_permission을 설정해주자.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
이제 마지막으로 업로드처리만 해주면 된다.
class AddPhotoActivity : AppCompatActivity() {
var PICK_IMAGE_FROM_ALBUM = 0
var storage: FirebaseStorage? = null
var photoUri: Uri? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_photo)
var addPhotoBtnUpload = findViewById<Button>(R.id.addPhoto_btn_upload)
//Initiate storage
storage = FirebaseStorage.getInstance()
//Open the album
var photoPickerIntent = Intent(Intent.ACTION_PICK)
photoPickerIntent.type = "image/*"
startActivityForResult(photoPickerIntent, PICK_IMAGE_FROM_ALBUM)
//add image upload event
addPhotoBtnUpload.setOnClickListener {
contentUpload()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
var addPhotoImage = findViewById<ImageView>(R.id.addPhoto_image)
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == PICK_IMAGE_FROM_ALBUM){
if(resultCode == Activity.RESULT_OK){
//path to the selected image
photoUri = data?.data
addPhotoImage.setImageURI(photoUri)
}else{
//cancel
finish()
}
}
}
fun contentUpload() {
//make filename
var timestamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
var imageFileName = "IMAGE_" + timestamp + "_.png"
var storageRef = storage?.reference?.child("image")?.child(imageFileName)
storageRef?.putFile(photoUri!!)?.addOnSuccessListener {
Toast.makeText(this, getString(R.string.upload_image),Toast.LENGTH_LONG).show()
}
}
}

화면에 보이는 것과 같이 사진을 선택하는 창이 띄워진다.
사진을 선택하면 다음과 같은 화면이 나온다.

코드에서 보면 선택이 완료된다면 image를 띄워주는 startActivityOnResult함수가 있다.
또한, '사진올리기' 버튼에 리스너를 달아 pufile 처리를 해주었다.