Merhabalar,
Bugünki dersimizde Google I/O2018 ‘de tanıtılan ve benim yeni yeni projelerimde kullandığım BottomAppBar ‘ı detaylı bir şekilde inceleyeceğiz.
BottomAppBar Tasarım olarak aşağıdaki gibidir.

Mevcuttaki toolbar ‘lar en üst ‘te konumlanmış ve kullanım açısından zorken, BottomAppBar kullanım açısından kullanıcılara daha kolay bir arayüz sunuyor. En önemli özelliği tek el kullanımı sağlamasıdır.
MaterialComponent kütüphanesini projemize dahil etmek için;
- Build.gradle (Project) ‘i açın.
- allproject altında google’ ın ekli olduğuna emin olun.
allprojects {
repositories {
google()
jcenter()
}
}
- Projeyi implement ‘e edin.
|
1 |
implementation <strong>'com.google.android.material:material:1.2.0-alpha02</strong> |
Daha detaylı bilgiye aşağıdaki adresten erişebilirsiniz.
https://material.io/develop/android/docs/getting-started/
Son Versiyonları aşağıdan öğrenebilirsiniz.
https://maven.google.com/web/index.html
https://mvnrepository.com/artifact/com.google.android.material/material
Unutmayın ! : BottomAppBar her zaman Coordinator Layout ‘un içerisinde olmak zorundadır. Detaylı Bilgi için;
https://developer.android.com/reference/android/support/design/widget/CoordinatorLayout
Gelelim Tasarımımızı yapmaya,
Layout Dosyamız –> activity_main.xml
|
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 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/tv_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.bottomappbar.BottomAppBar android:id="@+id/bottom_app_bar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:layout_gravity="bottom" app:backgroundTint="@color/colorPrimary" style="@style/Widget.MaterialComponents.BottomAppBar" app:fabAlignmentMode="center" app:navigationIcon="@drawable/ic_menu"/> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_add_black_24dp" app:fabSize="normal" app:layout_anchor="@id/bottom_app_bar" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.constraintlayout.widget.ConstraintLayout> |
Burada neler yaptığımızı anlatırsak. Bir tane constraintLayout içerisine text view ve coordinatorLayout ekledik. BottomAppBar Coordinator layout ile entegre ‘dir. Yukarıda daha detaylı bilgiye erişebilirsiniz. İçerisine de bir fab button attık.
Tasarımımız aşağıdaki şekilde olacaktır.

BottomAppBar aşağıdaki özelliklere sahiptir. Sizde bu özellikleri kendi tasarımınıza uygun olacak şekilde güncelleyebilirsiniz.

app:backgroundTint –> Arka Plan rengi için kullanılır.
app:fabAlignmentMode –> End ve Center özelliği sahiptir. Yukardaki resimde center iken herhangi bir işlemde end yapabilirsiniz. Örnek aşağıdaki resimdedir. Bu proje de de örnek olarak uygulanmıştır.

app:fabAttached –> Fab button’un bottomappbar ile bütünleşik mi olacağı yoksa ayrı olarak mı sunulacağına ilişkin ayardır.

app:fabCradleDiameter –> Fab button ile bottomAppBar arasındaki açıyı ayarlıyor.

app:fabCradleRoundedCornerRadius –> Köşe eğrisinin yarıçapının buluşma noktasındaki yarıçapını ve BottomAppBar’ın yatay kısmını belirtir.

app:fabCradleVerticalOffSet –> fab Buttonunun aşağıdaki yerini belirtir.

Gelelim MainActivity Kısmına :
|
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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
package com.umiitkose.todolist.bottomappbarexample import android.os.Build import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.widget.Toast import androidx.annotation.RequiresApi import com.google.android.material.bottomappbar.BottomAppBar import com.google.android.material.floatingactionbutton.FloatingActionButton import com.umiitkose.todolist.bottomappbarexample.utils.toast import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { private var currentFabAlignmentMode = BottomAppBar.FAB_ALIGNMENT_MODE_CENTER @RequiresApi(Build.VERSION_CODES.LOLLIPOP) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(bottom_app_bar) val addVisibilityChanged: FloatingActionButton.OnVisibilityChangedListener = object : FloatingActionButton.OnVisibilityChangedListener() { override fun onShown(fab: FloatingActionButton?) { super.onShown(fab) } override fun onHidden(fab: FloatingActionButton?) { super.onHidden(fab) bottom_app_bar.toggleFabAlignment() bottom_app_bar.replaceMenu( if(currentFabAlignmentMode == BottomAppBar.FAB_ALIGNMENT_MODE_CENTER) R.menu.bottomappbar_menu_two else R.menu.bottomappbar_menu ) fab?.setImageDrawable( if(currentFabAlignmentMode == BottomAppBar.FAB_ALIGNMENT_MODE_CENTER) getDrawable(R.drawable.ic_save_black_24dp) else getDrawable(R.drawable.ic_add_black_24dp) ) fab?.show() } } fab.setOnClickListener { Toast.makeText(this,"Fab Click", Toast.LENGTH_LONG).show() fab.hide(addVisibilityChanged) invalidateOptionsMenu() bottom_app_bar.navigationIcon = if (bottom_app_bar.navigationIcon != null) null else getDrawable(R.drawable.ic_search) when(tv_text.text) { getString(R.string.primary_screen_text) -> tv_text.text = getString(R.string.secondary_sceen_text) getString(R.string.secondary_sceen_text) -> tv_text.text = getString(R.string.primary_screen_text) } } } private fun BottomAppBar.toggleFabAlignment() { currentFabAlignmentMode = fabAlignmentMode fabAlignmentMode = currentFabAlignmentMode.xor(1) } override fun onCreateOptionsMenu(menu: Menu?): Boolean { val inflater = menuInflater.inflate(R.menu.bottomappbar_menu,menu) return true } override fun onOptionsItemSelected(item: MenuItem): Boolean { when(item!!.itemId){ R.id.app_bar_fav ->toast("Fav Menu item ",this) R.id.app_bar_settings ->toast("Settings Menu item ",this) R.id.app_bar_search ->toast("Search Menu item ",this) android.R.id.home -> { val bottomNavDrawerFragment = BottomNavigationDrawerFragment() bottomNavDrawerFragment.show(supportFragmentManager, bottomNavDrawerFragment.tag) } } return true } } |
menu kısmı için –> bottomappbar
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:tools="https://schemas.android.com/tools" xmlns:app="https://schemas.android.com/apk/res-auto" xmlns:android="https://schemas.android.com/apk/res/android"> <item android:id="@+id/app_bar_fav" android:icon="@drawable/ic_favorite_border_black_24dp" android:title="Favori" app:showAsAction="ifRoom"/> <item android:id="@+id/app_bar_search" android:icon="@drawable/ic_search" android:title="Search" app:showAsAction="ifRoom"/> <item android:id="@+id/app_bar_settings" android:title="Settings" app:showAsAction="never"/> </menu> |
CoordinatorLayout ‘un bir child elemanı olan BottomSheet ‘i ekleyeceğiz. Detaylı Bilgi için;
https://material.io/develop/android/components/bottom-sheet-behavior/
O zaman hadi başlayalım tasarıma :
|
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 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/tv_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.bottomappbar.BottomAppBar android:id="@+id/bottom_app_bar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:layout_gravity="bottom" app:backgroundTint="@color/colorPrimary" style="@style/Widget.MaterialComponents.BottomAppBar" app:fabAlignmentMode="center" app:navigationIcon="@drawable/ic_menu"/> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_add_black_24dp" app:fabSize="normal" app:layout_anchor="@id/bottom_app_bar" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.constraintlayout.widget.ConstraintLayout> |
Menü Kısmı :
|
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 63 64 |
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto"> <group android:checkableBehavior="none"> <item android:id="@+id/nav1" android:icon="@drawable/ic_search" android:title="@string/nav_item1" /> <item android:id="@+id/nav2" android:icon="@drawable/ic_search" android:title="@string/nav_item2" /> <item android:id="@+id/nav3" android:icon="@drawable/ic_search" android:title="@string/nav_item3" /> <item android:id="@+id/nav4" android:icon="@drawable/ic_search" android:title="@string/nav_item1" /> <item android:id="@+id/nav5" android:icon="@drawable/ic_search" android:title="@string/nav_item1" /> <item android:id="@+id/nav6" android:icon="@drawable/ic_search" android:title="@string/nav_item1" /> <item android:id="@+id/nav7" android:icon="@drawable/ic_search" android:title="@string/nav_item1" /> <item android:id="@+id/nav8" android:icon="@drawable/ic_search" android:title="@string/nav_item1" /> <item android:id="@+id/nav9" android:icon="@drawable/ic_search" android:title="@string/nav_item1" /> <item android:id="@+id/nav10" android:icon="@drawable/ic_search" android:title="@string/nav_item1" /> <item android:id="@+id/nav11" android:icon="@drawable/ic_search" android:title="@string/nav_item1" /> <item android:id="@+id/nav12" android:icon="@drawable/ic_search" android:title="@string/nav_item1" /> <item android:id="@+id/nav13" android:icon="@drawable/ic_search" android:title="@string/nav_item1" /> <item android:id="@+id/nav14" android:icon="@drawable/ic_search" android:title="@string/nav_item1" /> </group> </menu> |
ve son olarak Bottom Navigation Drawer ‘ı görüntülemek için Fragment yazmaya..
|
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 63 64 65 66 67 68 |
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_bottomsheet, container, false) } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) navigation_view.setNavigationItemSelectedListener { menuItem -> // Bottom Navigation Drawer menu item clicks when (menuItem.itemId) { R.id.nav1 -> toast(getString(R.string.nav_item1),requireContext()) } // Add code here to update the UI based on the item selected // For example, swap UI fragments here true } close_imageview.setOnClickListener { this.dismiss() } disableNavigationViewScrollbars(navigation_view) } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog dialog.setOnShowListener { dialog -> val d = dialog as BottomSheetDialog val bottomSheet = d.findViewById<View>(R.id.design_bottom_sheet) as FrameLayout? val bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet!!) bottomSheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { override fun onSlide(bottomSheet: View, slideOffset: Float) { if (slideOffset > 0.5) { close_imageview.visibility = View.VISIBLE } else { close_imageview.visibility = View.GONE } } override fun onStateChanged(bottomSheet: View, newState: Int) { when (newState) { BottomSheetBehavior.STATE_HIDDEN -> dismiss() // else -> close_imageview.visibility = View.GONE } } }) } return dialog } private fun disableNavigationViewScrollbars(navigationView: NavigationView?) { val navigationMenuView = navigationView?.getChildAt(0) as NavigationMenuView navigationMenuView.isVerticalScrollBarEnabled = false } } |
Uygulama Resimleri :
Projeyle ilgili tüm kodlara aşağıdaki adresten ulaşabilirsiniz.
https://github.com/umiitkose/BottomAppBar
Okuduğunuz için teşekkür ederim, İyi Çalışmalar Herkese..




