Bu içerikte yeni bir Toolbar’ı nasıl oluşturabileceğimizi öğreneceğiz. Sizin de muhtemelen çokça karşılaştığınız bir durum olan bir component’i app’in farklı yerlerinde tekrar ve tekrar kullanılması durumunda her şeyi sürekli yeniden yazmak zorlu ve önerilmeyen yöntemdir.
Bu dersimizin sonunda aşağıdaki gibi toolbarınız olacak ve istediğiniz ekran için istediğiniz şekilde düzenleyebilirsiniz. İhtiyaç doğrultusunda yeni özellikler de ekleyebilirsiniz. (YOUTUBE VİDEOSU İÇİN TIKLAYIN)




Şimdi bu dersimizde kendimize has bir Toolbar’ı nasıl sıfırdan yazabiliriz ve ona farklı farklı özellikleri nasıl verebiliriz hızlıdan yapmaya başlayalım.
Toolbar İçin Hazırlık
Yeni bir projeyi oluşturmuşsunuzdur şimdiye kadar 🙂
İlk olarak aşağıdaki gibi build.gradle dosyasında plugin şu şekilde olsun
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
}
burada önemli olan kapt‘tır. BindingAdapter için bize lazım olacaktır.
yine aynı dosyada android{} içerisinde en altta aşağıdaki buildFeatures‘i yerleştirelim.
android {
...
buildFeatures{
dataBinding true
}
}
Sağ üstte çıkan Sync Now‘a tıklayın ve yaptıklarımızı kabul etsin 🙂
Gerekli ön adımlarımızı yaptığımıza göre artık başlayabiliriz.
Toolbarı Oluşturalım
res>layout>New>Layout Resource File ile my_toolbar isminde bir dosya oluşturalım ve içini aşağıdaki gibi düzenleyelim. Bu dosyada bizim toolbar’da yer alacak her şeyi barındırıyoruz. Neler bulundurabiliriz mesela?
Geri butonu, uygulama ismi için bir text, uygulama logosu için imageView, toolbarın ortasında kullanabileceğimiz bir text(ben sayaç için yerleştirmiştim), menü ikonu, yardım ikonu, arama barı vs.
<?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">
<data>
</data>
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="@color/bg_dark"
app:contentInsetStart="0dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/login_action_bar"
android:layout_width="match_parent"
android:paddingStart="12dp"
android:layout_height="match_parent"
android:background="@color/transparent"
android:contentInsetStart="0dp">
<ImageView
android:id="@+id/ivToolbarLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_attractions_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<ImageView
android:id="@+id/ivBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:padding="10dp"
android:src="@drawable/ic_baseline_arrow_back_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvToolbarText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="16sp"
style="@style/textYellow"
app:layout_constraintStart_toEndOf="@+id/ivBack"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvCounter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
style="@style/textYellow"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/tvToolbarText"/>
<ImageView
android:id="@+id/ivHelp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_help_center_24"
android:visibility="gone"
app:layout_constraintEnd_toStartOf="@+id/ivMenu"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<ImageView
android:id="@+id/ivMenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_menu_24"
android:visibility="gone"
android:layout_marginEnd="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.appcompat.widget.Toolbar>
</layout>
Bunu yaptığınızda ekranınızda birçok yer kırmızı olacaktır ama basit işler. Neler istemişse aşağıda hepsini veriyor olacağım size.
color için colors.xml dosyasına aşağıdakileri ekliyoruz.
<color name="bg_dark">#0D2A43</color>
<color name="transparent">#00A6A7A9</color>
<color name="yellow">#FFC107</color>
style için themes.xml dosyasına aşağıdakileri yerleştiriyoruz.
<style name="textYellow" parent="TextAppearance.AppCompat">
<item name="android:textColor">@color/yellow</item>
</style>
Hazır themes.xml dosyasına gelmişten temayı NoActionBar olarak değiştirin ki uygulamada 2 toolbar gözükmesin 🙂
parent="Theme.MaterialComponents.DayNight.NoActionBar"
imageView yani drawable istenen yerleri de istediğin iconu indirip yerleştirebilirsiniz.
Tasarım dosyamız hazır olduğuna göre şimdi de bunu yönetebileceğimiz MyToolbar isminde bir sınıf oluşturalım ve içini aşağıdaki gibi dolduralım.
/**
* Created by Şahin Karakulak on 9.04.2022
*/
class MyToolbar: ConstraintLayout {
private var binding: MyToolbarBinding
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle)
init {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
binding = DataBindingUtil.inflate(inflater, R.layout.my_toolbar, this, true)
}
fun getMenuIcon(): ImageView = binding.ivMenu
fun getBackIcon(): ImageView = binding.ivBack
fun getTitle(): TextView = binding.tvToolbarText
fun getCounter(): TextView = binding.tvCounter
fun getHelpIcon(): ImageView = binding.ivHelp
fun getToolbarLogo(): ImageView = binding.ivToolbarLogo
fun hide() = binding.root.gone()
fun show() = binding.root.visible()
}
MyToolbar sınıfında sizde kırmızı yanacak olan 2 yer var. gone() ve visible() extension’larını da hızlıca yazalım. Bunun için ViewExtensions isminde bir dosya oluşturalım ve içini aşağıdaki gibi dolduralım. (Başka bir dersimizde de extensions yazmayı detaylıca inceleriz)
/**
* Created by Şahin Karakulak on 19.03.2022
*/
fun View.visible(){
this.visibility = View.VISIBLE
}
fun View.invisible(){
this.visibility = View.INVISIBLE
}
fun View.gone(){
this.visibility = View.GONE
}
MyToolbar isminde bir toolbar’ımız artık var ama asıl amacımız neydi? Tamamen bizim yönetip özellik verip kaldırabileceğimiz bir toolbar olmasıydı. O halde şimdi de bindingAdapter’ı oluşturalım.
ToolbarBindingAdapter isminde bir dosya oluşturalım ve içini aşağıdaki gibi dolduralım.
/**
* Created by Şahin Karakulak on 9.04.2022
*/
@BindingAdapter("bind:setToolbarTitle")
fun setToolbarTitle(view: MyToolbar, title: String?) {
view.getToolbarLogo().gone()
view.getTitle().text = title
view.getTitle().visible()
}
@BindingAdapter("bind:setBackIcon")
fun setBackIcon(view: MyToolbar, isVisible: Boolean){
if(isVisible) view.getBackIcon().visible() else view.getBackIcon().gone()
}
@BindingAdapter("bind:setCounter")
fun setCounter(view: MyToolbar, counterText: String?){
view.getCounter().text = counterText
}
Burada setToolbarTitle, setBackIcon ve setCounter şeklinde attributes var. Bunları nasıl kullanacağımızı birazdan aşağıda göreceğiz.
Toolbar’ı Nasıl Kullanırız?
Tüm yapımızı kurduk. Artık toolbar’ı activity veya fragment ekranlarında nasıl kullanabiliriz onu görelim. Örneğin activity_main.xml dosyamızda kullanmaya çalışalım. Burada dikkat edilmesi gereken şey tüm layoutları kapsayacak olan
<layout></layout>
tag’ını yerleştirmek ve xmlns’leri oraya taşımak. Aşağıdaki bir örnek.
<?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"
xmlns:bind="http://schemas.android.com/tools">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.mrcaracal.myapplicationfornewtoolbar.MyToolbar
android:id="@+id/myNewToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
bind:setBackIcon="@{false}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Bizim oluşturduğumuz toolbarda göze çarpan bir şey varmı? VAR 🙂
bind:setBackIcon="@{false}"
Az önce bunları nasıl kullanabileceğimizi göreceğiz demiştim. Burda ToolbarBindingAdapter dosyasındaki setBackIcon‘a false değerini göndererek oradaki işlemin yapılmasını sağladık. Böylelikle geri butonunu gizledik. Farklı bir ekranda true göndererek geri butonu gösterebiliriz
Diğer bir attribute’mızı da görelim.
bind:setToolbarTitle="@{@string/login}"
Burada da string.xml dosyamızdaki bir string’i çağırdık. Böylelikle Toolbarımızda istediğimiz yazı gözükecektir.
Toolbar’ımızda yer alacak geri butonunu, text’i ve diğerlerini bu şekilde ayarlayabiliriz ama bunları kod tarafında da nasıl düzenleyebileceğimizi de görelim. MainActivity sınıfı içerisinde örnek olarak aşağıdaki gibi istediğimiz şekilde düzenlemeler yapabiliriz.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.myNewToolbar.getToolbarLogo().gone()
binding.myNewToolbar.getTitle().text = "Create a new toolbar"
binding.myNewToolbar.getMenuIcon().visible()
binding.myNewToolbar.getMenuIcon().setOnClickListener {
Toast.makeText(this, "Menu Clicked!", Toast.LENGTH_SHORT).show()
}
}
}
Bu içeriğin de sonuna geldik. Umarım faydalı bir kaynak olmuştur. İyi günler dilerim 🙂