Android SharedPreferences Kullanımı

Android’te 5 farklı veri saklama yolu vardır. Bunlardan biri Shared Preferences’tir.

Öncelikle buna neden ihtiyaç duyduğumuzu açıklayalım.

Biliyorsunuz ki bazen uygulamalarımızda verileri saklamak isteriz fakat bu verileri değişkenlerde saklayamayız çünkü uygulamayı kapattığımız anda o verilerde silinmekte. Tabii ki akıllara hemen ikinci seçenek olan veritabanı oluşturup verileri orada tutmak geliyor.

Sqlite ile bir veri tabanı oluşturmak. Ancak bu yöntem küçük verilerin saklanması için oldukça zahmetlidir.

Küçük verilerin saklanması için bir veri tabanı ne kadar uygun değilse büyük verilerin saklanması için de SharedPreferences kullanmak o kadar uygun değildir.Shared preferences ile önemli verileri saklamamalısınız. Bunun yerine önemi fazla olmayan verileri saklamanız uygulamanın sağlığı açısından çok daha iyi olacaktır.

İşte böyle durumlarda Key-value mantığı ile çalışan Shared Preferences imdadımıza yetişir ve bize pratiklik kazandırır. Genelde programların ayarlar bölümündeki veriler ve seçenekler bu yol ile kaydedilmektedir.

Nedir bu SharedPreferences?

Sharedpreferences üstte anlattığım durumundan bizi kurtarmak için tasarlanmış bir Sınıf. Bu sınıf bize çeşitli kullanıcı ayarlarını veya en yüksek skor vb  değerleri saklamakullanma ya da gerektiğinde değiştirebilme gibi imkanlar sağlıyor. Üstelik programı kapatsak bile sakladığımız veriler kaybolmuyor.

SharedPreferences HashMap yani key-value ( anahtar-değer) şeklinde çalışan bir yapısı vardır. Çalışma şekli verileri bir xml dosyası içine kaydeder ve biz bir değer istediğimiz zaman bu xml dosyasından okuyarak bize getirir.

Peki Bu Veriler Nerede ve Nasıl Saklanıyor?

SharedPreferences ile oluşturduğumuz veriler kullandığımız android cihazımızda xml dosyası olarak depolanmakta. Uzantısı tam olarak şöyle, bu yazıda biz Ayarlar olarak tanımladığımız için Ayarlar olarak saklanıyor.:

/data/data/PAKET_ADI/shared_prefs/Ayarlar.xml

SharedPreferences’in içinde String, Int, Boolean, Float, Long tipinde değerler depolanabilir. Uygulama kapansa dahi kaydedilen bu değerler silinmez veya kaybolmaz.

SharedPreference uygulamaya özeldir. Yani izin verilmediği sürece diğer uygulamalar bu içeriğe ulaşamaz.

Kodlamaya geçmeden önce metotlarımızı tanıyalım

setSharedPreference metodu ile istediğimiz veriyi gönderdiğimiz parametreler ile saklayabiliriz.

getSharedPreference daha önce kaydedilen bir veriyi kullanmak istediğimiz zaman kullanırız.

clearSharedPreference metodu ile kaydedilen verilerin temizleme işlemi yapılır.

removeSharedPreference gönderdiğimiz key ile kaydedilen bir verinin kaldırılma işlemi yapılır.

putString String bir veri saklamak için kullanılır. Saklanacak verinin tipine göre değişir.

Yavaş yavaş başlayalım;

Projeye Dahil Etme

import android.content.SharedPreferences;

SharedPreferences Nesnesini Oluşturma

Kütüphanemizi import ettikten sonra bir adet nesne oluşturuyoruz:

SharedPreferences ayarSP= getSharedPreferences("Ayarlar", Context.MODE_PRIVATE);

ayarlar_1 isminde bir nesne oluşturduk. İlk parametrede  verilerin cihazımızda hangi isimle tutulacağını yazıyoruz. Mesela ben Ayarlar kullandık. İkinci değer’e ise Context.MODE_PRIVATE yazıyoruz, bunu yazmamızın sebebi dışarıdan erişilmesini engellemek ve güvenli hale getirmek.

Burada şuna karar vermemiz gerekiyor. Sakladığımız bilgilere sadece bulunduğumuz activity’den mi yoksa uygulamamızdaki herhangi bir aktivity’den mi ulaşağız.

Eğer sadece verilerin kaydedildiği activity’den ulaşacaksak;

SharedPreferences ayarSP= context.getPreferences(context.getPackageName(), Context.MODE_PRIVATE);
SharedPreferences ayarSP= this.getPrefer
ences(Context.MODE_PRIVATE);

Bilgilere uygulamamızdaki herhangi bir activity’den ulaşacaksak;

SharedPreferences ayarSP= context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
SharedPreferences ayarSP= getSharedPreferences(Ayarlar,MODE_PRIVATE);

kodlarını kullanarak izin alıyoruz.

Yani getPreferences yerine getSharedPreferences kullanıyoruz ve her bir tercihimize ad konulmuş olmalı.

Kayıt Okumak

SharedPreferences ayarSP= getSharedPreferences(Ayarlar,MODE_PRIVATE);
String adiString = sharedPref.getString("adi","Kayıt Yok");
int noInt = sharedPref.getInt("numara",0);
Boolean kabulBoolean= sharedPref.getBoolean("kabulmu",false);

En üstte oluşturduğumuz ayarlar nesnesini kullanarak ulaşmak istediğiniz değişkenin türünü seçip(getInt), birinci parametreye sakladığımız key’in adını, ikinci parametreye ise eğer öyle bir key yoksa geriye döndüreceği default değeri yazıyoruz.

Kayıt Eklemek

Oluşturduğumuz preference’e bir veri eklemek istiyoruz. Örnek vermek gerekirse numara isminde bir key oluşturup ona bir değer yazmak istiyoruz. Bunun için ilk önce SharedPreferences.Editor kullanmamız gerekiyor, editor’u oluşturalım:

  SharedPreferences.Editor editor = ayarSP.edit(); 

editor oluşturduktan sonra artık ayarSP isimli SharedPreference‘mize veri ekleyebilir/değişebilir/silebiliriz. Şimdi numara key’i oluşturup bir değer girelim 

int girilenNumara= 200;
editor.putInt("numara", girilenNumara);

Gördüğünüz üzere editor nesnesini kullanarak putInt ile birlikte numara key‘ine değerimizi eklemiş olduk. Tabi siz dilerseniz putInt yerine ihtiyacınız olan başka birşey de kullanabilirsiniz. Boolean değer tutacaksanız putBooleanString tutacaksanız putString kullanabilirsiniz. Son olarak yaptığımız bu değeri kaydetmek kaldı. Bunun için de yazdığımız kodun altına şunu ekliyoruz:

editor.commit();

kodları toparlarsak, değer okuma işlemi;

SharedPreferences ayarSP= getSharedPreferences(Ayarlar,MODE_PRIVATE);
  SharedPreferences.Editor editor = ayarSP.edit(); 
  int girilenNumara= 200;
  String adi= "nurullah";
  Boolean onay= true;
  editor.putInt("numara",girilenNumara); //int değer ekleniyor
  editor.putString("adi",adi); //string değer ekleniyor
  editor.putBoolean("kabulmu",onay); //boolean değer ekleniyor
  editor.commit(); //Kayıt

veya

SharedPreferences sharedPreferences;
sharedPreferences=this.getSharedPreferences("Ayarlar", Context.MODE_PRIVATE);
String adiEkle= editText.getText().toString();
sharedPreferences.edit().putString("adi",adiEkle).apply();

Kayıt Silme (Tamamını Silme)

SharedPreferences ayarSP= getSharedPreferences(Ayarlar,MODE_PRIVATE);
//SharedPreferences ayarSP= context.getSharedPreferences(Ayarlar,Context.MODE_PRIVATE);
        SharedPreferences.Editor editor=settings.edit();
        editor.clear();
        editor.commit();

Kayıt Değiştirme

Diyelim numara kısmını değiştirmek istiyoruz. Bunun için üstte yazdığımız gibi SharedPreference.Editor kullanmamız gerekiyor, tabi editor nesnesin çalışabilmesi için SharedPreference nesnesini de oluşturmayı unutmayın:

SharedPreferences ayarSP= getSharedPreferences(Ayarlar,MODE_PRIVATE);
SharedPreferences.Editor editor=settings.edit();

editor isminde bir Editor nesnesi oluşturduk. Artık ayarlar Preferences’in deki değişkenleri istediğimiz gibi değiştirebiliriz.

int girilenNumara= 234;
editor.putInt("numara", girilenNumara);

Gördüğünüz üzere daha önce veri girdiğimiz numara key’ini putInt diyip key ismini ve değişecek değeri yazdık. Böylece önceki değeri güncellemiş olduk. Tabi güncellemenin kaydedilmesi için commit etmemiz gerekiyor.

editor.commit();

commit() fonksiyonu ile verilerimizi başarılı bir şekilde değiştirmiş oluyoruz.

Kayıt Silme (Seçilen Kayıtları Silme)

Diyelim artık oluşturduğumuz numara isimli key‘e ihtiyacımız yok ve silmek istiyoruz. Bunun için SharedPreference nesnesi ve editor nesnesi gerekiyor. Bu nesnelerin üstte nasıl oluşturulduğu yazıyor. Silmek için editor’ü kullanıp remove fonksiyonu’na hangi isimli key’i sileceğimizi yazıp commit‘liyoruz.

SharedPreferences ayarSP= getSharedPreferences(Ayarlar,MODE_PRIVATE);
SharedPreferences.Editor editor=settings.edit();
editor.remove("numara");
editor.commit();

veya

sharedPreferences.edit().remove("numara").apply();

Aşağıda SharedPreferences ile ilgili bi kaç tablo verdikten soran kodlamaya geçelim.

ParametreAçıklama
MODE_PRIVATEVerilerin tutulduğu dosyaya sadece uygulamamız erişebilir.
MODE_WORLD_READABLE Verilerin tutulduğu dosyayı cihazdaki tüm uygulamalar okuyabilir.
MODE_WORLD_WRITEABLE Verilerin tutulduğu dosyayı cihazdaki tüm uygulamalar okuyabilir ve yazabilir.
MODE_APPENDeni kaydedilen verileri mevcut verilen üzerine yazar.
MODE_ENABLE_WRITE_AHEAD_LOGGINGVeritabanı açık bayrağı. Veritabanına yazmayı, logine esnasında mümkün kılar.
MODE_MULTI_PROCESS SharedPreferences objesi yüklenmiş olmasına rağmen tercihlerdeki değişiklikleri kontrol eden metottur

MetotlarAçıklama
SharedPreferences.contains()Girilen isimde bir preference içerip içermediğini kontrol eder
SharedPreferences.edit()Editör’ü çağırarak preference üzerinde istediğimiz değişiklikleri gerçekleştiririz
SharedPreferences.getAll()Preference’daki tüm verilere (anahtar/değer) ulaşırız.
SharedPreferences.getBoolean()Tercih dosyasındaki boolean tipi değerleri getirir. İki parametre alır. İlk parametre Strink key değeri yani istediğimiz değerin anahtarını, ikinci parametrede ise döndürülecek değer.
SharedPreferences.getFloat()Tercih dosyasındaki float tipi değerleri getirir. İki parametre alır. İlk parametre Strink key değeri yani istediğimiz değerin anahtarını, ikinci parametrede ise döndürülecek değer.
SharedPreferences.getInt()Tercih dosyasındaki int tipi değerleri getirir. İki parametre alır. İlk parametre Strink key değeri yani istediğimiz değerin anahtarını, ikinci parametrede ise döndürülecek değer.
SharedPreferences.getLong()Tercih dosyasındaki long tipi değerleri getirir. İki parametre alır. İlk parametre Strink key değeri yani istediğimiz değerin anahtarını, ikinci parametrede ise döndürülecek değer.
SharedPreferences.getString()Tercih dosyasındaki string tipi değerleri getirir. İki parametre alır. İlk parametre Strink key değeri yani istediğimiz değerin anahtarını, ikinci parametrede ise döndürülecek değer.
SharedPreferences.getStringSet()Tercih dosyasındaki Set<string> tipi değerleri getirir. İki parametre alır. İlk parametre Strink key değeri yani istediğimiz değerin anahtarını, ikinci parametrede ise default olarak döndürülecek değer.

KomutAçıklama
SharedPreferences.Editor.clear()Tüm tercihleri kaldırır.
SharedPreferences.Editor.remove()Belirli tercihleri kaldırır.
SharedPreferences.Editor.putBoolean()Boolean veri tipli bir tercih oluşturur. İki parametre alır. İlk parametremiz adlandırılan String değerli tercihimiz, ikincisi default değerimiz.
SharedPreferences.Editor.putFloat()Float veri tipli bir tercih oluşturur. İki parametre alır. İlk parametremiz adlandırılan String değerli tercihimiz, ikincisi default değerimiz.
SharedPreferences.Editor.putInt()int veri tipli bir tercih oluşturur. İki parametre alır. İlk parametremiz adlandırılan String değerli tercihimiz, ikincisi default değerimiz.
SharedPreferences.Editor.putLong()Long veri tipli bir tercih oluşturur. İki parametre alır. İlk parametremiz adlandırılan String değerli tercihimiz, ikincisi default değerimiz.
SharedPreferences.Editor.putString()String veri tipli bir tercih oluşturur. İki parametre alır. İlk parametremiz adlandırılan String değerli tercihimiz, ikincisi default değerimiz.
SharedPreferences.Editor.putStringSet()Set<String> veri tipli bir tercih oluşturur. İki parametre alır. İlk parametremiz adlandırılan String değerli tercihimiz, ikincisi default değerimiz.
SharedPreferences.Editor.commit()Tüm değişikliklerimizi işler.
SharedPreferences.Editor.apply()Commit() metodu gibi işleve sahiptir ancak apply metodu yazma işlemi yapana kadar beklemez ve akış yoluna devam eder ve boolean değer döndürmez

Şimdi programlamaya geçersek;

Aşağıda anlatılanlara ilişkin örnek mevcuttur, bu örneğin kodlarını

BURADAN github bağlantısından indirebilirsiniz.

activity_sharedpreferences_deneme.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".SharedPreferencesDeneme">

    <LinearLayout
        android:id="@+id/layoutA"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="50dp"
        android:gravity="center"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <EditText
            android:id="@+id/editTextad"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="isim gir" />

        <EditText
            android:id="@+id/editTextyas"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Yaş gir" />

        <CheckBox
            android:id="@+id/CheckBoxonay"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:checked="false"
            android:text="Onaylıyor musunuz?" />

        <Button
            android:id="@+id/button_Kaydet"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Kaydet" />

        <Button
            android:id="@+id/button_oku"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Oku" />

        <Button
            android:id="@+id/button_tamamini_sil"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Tamamını Sil" />

        <Button
            android:id="@+id/button_secileni_sil"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Sadece İsimi SİL" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
SharedPreferencesDeneme.class
package com.mobilprogramlar.sharedpreferenceskullanm;
import androidx.appcompat.app.AppCompatActivity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

/*
www.ossmatematik.com
www.mobilprogramlar.com
https://github.com/netmatematiknet/SharedpreferencesKullanimi.git
*/

public class SharedPreferencesDeneme extends AppCompatActivity {
    int yas2;
    String ad2;
    Boolean onay2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sharedpreferences_deneme);

        final SharedPreferences sharedPrefNT = getSharedPreferences("Ayarlar", MODE_PRIVATE);

        final EditText adEditText = findViewById(R.id.editTextad);
        final EditText yasEditText = findViewById(R.id.editTextyas);
        final CheckBox onayCheckBox = findViewById(R.id.CheckBoxonay);
        final Button kaydetBtn = findViewById(R.id.button_Kaydet);
        final Button okuBtn = findViewById(R.id.button_oku);
        final Button silTamaminiBtn = findViewById(R.id.button_tamamini_sil);
        final Button silSecileniBtn = findViewById(R.id.button_secileni_sil);

        kaydetBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String ad = adEditText.getText().toString();
                String yas = yasEditText.getText().toString();

                if (!ad.matches("")){
                    sharedPrefNT.edit().putString("isim", ad).apply();
                    //veya
                    //SharedPreferences.Editor editor = sharedPrefNT.edit();
                    //editor.putString("isim",ad);
                    //editor.apply();
                }
                if (!yas.matches("")){
                    int yas1 = Integer.parseInt(yas);
                    sharedPrefNT.edit().putInt("yas", yas1).apply();
                }
                if(onayCheckBox.isChecked()) {
                    boolean onay=true;
                    sharedPrefNT.edit().putBoolean("Onaylama", onay).apply();
                }else{
                    boolean onay=false;
                    sharedPrefNT.edit().putBoolean("Onaylama", onay).apply();
                }


            }
        });
        okuBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ad2 = sharedPrefNT.getString("isim",null);
                yas2 = sharedPrefNT.getInt("yas",0);
                onay2 = sharedPrefNT.getBoolean("Onaylama",false);
                Toast.makeText(getApplicationContext(),"isim:"+ad2+" yas:"+yas2+" Onaylama:"+onay2,Toast.LENGTH_SHORT).show();
            }
        });
        silTamaminiBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sharedPrefNT.edit().clear().apply();
                //veya
                //SharedPreferences.Editor editor=sharedPrefNT.edit();
                //editor.clear().apply();
                Toast.makeText(getApplicationContext(),"Tüm Kayıtlar SİLİNDİ",Toast.LENGTH_SHORT).show();
            }
        });
        silSecileniBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sharedPrefNT.edit().remove("isim").apply();
                //veya
                //SharedPreferences.Editor editor=sharedPrefNT.edit();
                //editor.remove("isim").apply();
                Toast.makeText(getApplicationContext(),"Sadece İsim SİLİNDİ",Toast.LENGTH_SHORT).show();
            }
        });

    }
}

SharedPreferences’i de global alanda tanımlıyoruz. Bunları global alanda tanımlamamızın nedeni, sadece onCreate metodu içerisinde değil, buton nesnesinin onClick olayında da kullanacak olmamızdan kaynaklanıyor.

Ve sharedPreferences ile “isim” anahtar kelimesine kaydettiğimiz veriyi ad adında oluşturmuş olduğumuz string değişken içerisine çekiyoruz. Aldığı paramatrelerden 1.si anahtar kelime, 2.si ise eğer “isim” anahtar kelimesinin içerisi boşsa, yerine yazılacak default ifade anlamına gelmektedir. Ben eğer “isim” anahtar kelimesinin içerisi boşsa, default değer almasını istemiyorum. Null(boş) olmasını istiyorum.

Floating Action Button (FAB) Nasıl Yapılır

Floating Action Button Nedir?

Malzeme Tasarımında tanıtılan yeni bir bileşen Floating Action Button (nedir).Sağ alt kısımdaki UI’nin üzerinde yüzen yüksek dairesel bir görünüştür. Genellikle, ekranın en önemli eylemini vurgulayan farklı görseliyle dikkat çeker.

 

Bu nispeten basit eğitimde Web de genelde Lolipop öncesi örnekler mevcut ama Google ın getirdiği Api 26 zorunluluğu ile artık bütün apk ların yenilenmesi gerekmekte.

Floating action buttons (Kayan eylem düğmeleri) FAB, tanıtılan bir eylem için kullanılır. UI’nin üzerinde yüzen daire içine alınmış bir simge ile ayırt edilirler ve değişim, başlatma ve aktarma çapa noktası içeren hareket davranışları vardır. – Materyal Tasarımı kaynağı

Gradle ayarlarını aşağıdaki altı çizili yerlerden belirtilen değerlere göre ayarlayalım.

 

Api leri ise yine aşağıdaki şekiilerdeki gibi …

 

 

Geldik dosyalara, önce activity_main

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    android:layout_weight="1"
    tools:context=".MainActivity">

    <RelativeLayout
        android:background="@color/background"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.mobilprogramlar.floadnt.FloatingActionButton
            android:id="@+id/pink_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:fab_colorNormal="@color/pink"
            app:fab_icon="@drawable/ic_fab_star" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@id/pink_icon"
            android:text="Text below button"
            android:layout_centerHorizontal="true"
            style="@style/menu_labels_style"
            android:layout_marginBottom="48dp"/>

        <com.mobilprogramlar.floadnt.AddFloatingActionButton
            android:id="@+id/semi_transparent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="16dp"
            app:fab_colorNormal="@color/blue_semi_transparent"
            app:fab_colorPressed="@color/blue_semi_transparent_pressed"
            app:fab_plusIconColor="@color/white"
            />
        <com.mobilprogramlar.floadnt.FloatingActionButton
            android:id="@+id/setter"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@id/semi_transparent"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="16dp" />

        <com.mobilprogramlar.floadnt.AddFloatingActionButton
            android:id="@+id/normal_plus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:fab_colorNormal="@color/white"
            app:fab_colorPressed="@color/white_pressed"
            app:fab_plusIconColor="@color/half_black"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_marginBottom="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginStart="16dp"/>

        <com.mobilprogramlar.floadnt.FloatingActionsMenu
            android:id="@+id/right_labels"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_weight="1"
            app:fab_addButtonColorNormal="@color/white"
            app:fab_addButtonColorPressed="@color/white_pressed"
            app:fab_addButtonPlusIconColor="@color/half_black"
            app:fab_addButtonSize="mini"
            app:fab_labelStyle="@style/menu_labels_style"
            app:fab_labelsPosition="right"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_above="@id/normal_plus"
            android:layout_marginLeft="16dp">

            <com.mobilprogramlar.floadnt.FloatingActionButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:fab_colorNormal="@color/white"
                app:fab_colorPressed="@color/white_pressed"
                app:fab_title="Label on the right" />

            <com.mobilprogramlar.floadnt.FloatingActionButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:fab_colorNormal="@color/white"
                app:fab_colorPressed="@color/white_pressed"
                app:fab_size="mini"
                app:fab_title="Another one on the right" />

        </com.mobilprogramlar.floadnt.FloatingActionsMenu>

        <!-- -->

        <com.mobilprogramlar.floadnt.FloatingActionsMenu
            android:id="@+id/multiple_actions"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            app:fab_addButtonColorNormal="@color/white"
            app:fab_addButtonColorPressed="@color/white_pressed"
            app:fab_addButtonPlusIconColor="@color/half_black"
            app:fab_labelStyle="@style/menu_labels_style"
            android:layout_marginBottom="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginEnd="16dp">

            <com.mobilprogramlar.floadnt.FloatingActionButton
                android:id="@+id/action_a"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:fab_colorNormal="@color/white"
                app:fab_colorPressed="@color/white_pressed"
                app:fab_title="Action Aaaaa" />

            <com.mobilprogramlar.floadnt.FloatingActionButton
                android:id="@+id/action_b"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:fab_colorNormal="@color/white"
                app:fab_colorPressed="@color/white_pressed"
                app:fab_title="Action with a very long name that won\'t fit on the screen" />
        </com.mobilprogramlar.floadnt.FloatingActionsMenu>

        <!-- -->

        <com.mobilprogramlar.floadnt.FloatingActionsMenu
            android:id="@+id/multiple_actions_down"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_alignParentTop="true"
            android:layout_marginTop="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginEnd="16dp"
            app:fab_addButtonColorNormal="@color/white"
            app:fab_addButtonColorPressed="@color/white_pressed"
            app:fab_addButtonPlusIconColor="@color/half_black"
            app:fab_addButtonSize="mini"
            app:fab_expandDirection="down"
            app:fab_labelStyle="@style/menu_labels_style">

            <com.mobilprogramlar.floadnt.FloatingActionButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:fab_colorNormal="@color/white"
                app:fab_colorPressed="@color/white_pressed"
                app:fab_size="mini" />

            <com.mobilprogramlar.floadnt.FloatingActionButton
                android:id="@+id/button_remove"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:fab_colorNormal="@color/white"
                app:fab_colorPressed="@color/white_pressed"
                app:fab_title="Click to remove" />

            <com.mobilprogramlar.floadnt.FloatingActionButton
                android:id="@+id/button_gone"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:fab_colorNormal="@color/white"
                app:fab_colorPressed="@color/white_pressed" />

            <com.mobilprogramlar.floadnt.FloatingActionButton
                android:id="@+id/action_enable"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:fab_colorNormal="@color/white"
                app:fab_colorPressed="@color/white_pressed"
                app:fab_title="Set bottom menu enabled/disabled" />
        </com.mobilprogramlar.floadnt.FloatingActionsMenu>

        <com.mobilprogramlar.floadnt.FloatingActionsMenu
            android:id="@+id/multiple_actions_left"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/multiple_actions_down"
            android:layout_toStartOf="@+id/multiple_actions_down"
            android:layout_alignParentTop="true"
            app:fab_addButtonColorNormal="@color/white"
            app:fab_addButtonColorPressed="@color/white_pressed"
            app:fab_addButtonPlusIconColor="@color/half_black"
            app:fab_addButtonSize="mini"
            app:fab_addButtonStrokeVisible="false"
            app:fab_expandDirection="left"
            android:layout_marginTop="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginEnd="16dp">

            <com.mobilprogramlar.floadnt.FloatingActionButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:fab_colorNormal="@color/white"
                app:fab_colorPressed="@color/white_pressed" />

            <com.mobilprogramlar.floadnt.FloatingActionButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:fab_colorNormal="@color/white"
                app:fab_colorPressed="@color/white_pressed"
                app:fab_size="mini" />

            <com.mobilprogramlar.floadnt.FloatingActionButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:visibility="gone"
                app:fab_colorNormal="@color/white"
                app:fab_colorPressed="@color/white_pressed"
                app:fab_size="mini" />
        </com.mobilprogramlar.floadnt.FloatingActionsMenu>

        <com.mobilprogramlar.floadnt.FloatingActionButton
            android:id="@+id/setter_drawable"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@id/setter"
            android:layout_centerHorizontal="true" />
    </RelativeLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

 

Sıra java kodlarında bize yardımcı 4 adet java dosyamız var;

AddFloatingActionButton

package com.mobilprogramlar.floadnt;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.Shape;
import android.util.AttributeSet;
import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes;

public class AddFloatingActionButton extends FloatingActionButton {
  int mPlusColor;

  public AddFloatingActionButton(Context context) {
    this(context, null);
  }

  public AddFloatingActionButton(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public AddFloatingActionButton(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  void init(Context context, AttributeSet attributeSet) {
    TypedArray attr = context.obtainStyledAttributes(attributeSet, R.styleable.AddFloatingActionButton, 0, 0);
    mPlusColor = attr.getColor(R.styleable.AddFloatingActionButton_fab_plusIconColor, getColor(android.R.color.white));
    attr.recycle();
    super.init(context, attributeSet);
  }

  public int getPlusColor() {
    return mPlusColor;
  }

  public void setPlusColorResId(@ColorRes int plusColor) {
    setPlusColor(getColor(plusColor));
  }

  public void setPlusColor(int color) {
    if (mPlusColor != color) {
      mPlusColor = color;
      updateBackground();
    }
  }

  @Override
  public void setIcon(@DrawableRes int icon) {
    throw new UnsupportedOperationException("Use FloatingActionButton if you want to use custom icon");
  }

  @Override
  Drawable getIconDrawable() {
    final float iconSize = getDimension(R.dimen.fab_icon_size);
    final float iconHalfSize = iconSize / 2f;

    final float plusSize = getDimension(R.dimen.fab_plus_icon_size);
    final float plusHalfStroke = getDimension(R.dimen.fab_plus_icon_stroke) / 2f;
    final float plusOffset = (iconSize - plusSize) / 2f;

    final Shape shape = new Shape() {
      @Override
      public void draw(Canvas canvas, Paint paint) {
        canvas.drawRect(plusOffset, iconHalfSize - plusHalfStroke, iconSize - plusOffset, iconHalfSize + plusHalfStroke, paint);
        canvas.drawRect(iconHalfSize - plusHalfStroke, plusOffset, iconHalfSize + plusHalfStroke, iconSize - plusOffset, paint);
      }
    };
    ShapeDrawable drawable = new ShapeDrawable(shape);
    final Paint paint = drawable.getPaint();
    paint.setColor(mPlusColor);
    paint.setStyle(Style.FILL);
    paint.setAntiAlias(true);
    return drawable;
  }
}

 

FloatingActionButton dosyası

package com.mobilprogramlar.floadnt;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.ShapeDrawable.ShaderFactory;
import android.graphics.drawable.StateListDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.util.AttributeSet;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.ColorRes;
import androidx.annotation.DimenRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatImageButton;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

public class FloatingActionButton extends AppCompatImageButton {

  public static final int SIZE_NORMAL = 0;
  public static final int SIZE_MINI = 1;

  @Retention(RetentionPolicy.SOURCE)
  @IntDef({ SIZE_NORMAL, SIZE_MINI })
  public @interface FAB_SIZE {
  }

  int mColorNormal;
  int mColorPressed;
  int mColorDisabled;
  String mTitle;
  @DrawableRes
  private int mIcon;
  private Drawable mIconDrawable;
  private int mSize;
  private float mCircleSize;
  private float mShadowRadius;
  private float mShadowOffset;
  private int mDrawableSize;
  boolean mStrokeVisible;

  public FloatingActionButton(Context context) {
    this(context, null);
  }

  public FloatingActionButton(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs);
  }

  public FloatingActionButton(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context, attrs);
  }

  void init(Context context, AttributeSet attributeSet) {
    TypedArray attr = context.obtainStyledAttributes(attributeSet, R.styleable.FloatingActionButton, 0, 0);
    mColorNormal = attr.getColor(R.styleable.FloatingActionButton_fab_colorNormal, getColor(android.R.color.holo_blue_dark));
    mColorPressed = attr.getColor(R.styleable.FloatingActionButton_fab_colorPressed, getColor(android.R.color.holo_blue_light));
    mColorDisabled = attr.getColor(R.styleable.FloatingActionButton_fab_colorDisabled, getColor(android.R.color.darker_gray));
    mSize = attr.getInt(R.styleable.FloatingActionButton_fab_size, SIZE_NORMAL);
    mIcon = attr.getResourceId(R.styleable.FloatingActionButton_fab_icon, 0);
    mTitle = attr.getString(R.styleable.FloatingActionButton_fab_title);
    mStrokeVisible = attr.getBoolean(R.styleable.FloatingActionButton_fab_stroke_visible, true);
    attr.recycle();

    updateCircleSize();
    mShadowRadius = getDimension(R.dimen.fab_shadow_radius);
    mShadowOffset = getDimension(R.dimen.fab_shadow_offset);
    updateDrawableSize();
    updateBackground();
  }

  private void updateDrawableSize() {
    mDrawableSize = (int) (mCircleSize + 2 * mShadowRadius);
  }

  private void updateCircleSize() {
    mCircleSize = getDimension(mSize == SIZE_NORMAL ? R.dimen.fab_size_normal : R.dimen.fab_size_mini);
  }

  public void setSize(@FAB_SIZE int size) {
    if (size != SIZE_MINI && size != SIZE_NORMAL) {
      throw new IllegalArgumentException("Use @FAB_SIZE constants only!");
    }

    if (mSize != size) {
      mSize = size;
      updateCircleSize();
      updateDrawableSize();
      updateBackground();
    }
  }

  @FAB_SIZE
  public int getSize() {
    return mSize;
  }

  public void setIcon(@DrawableRes int icon) {
    if (mIcon != icon) {
      mIcon = icon;
      mIconDrawable = null;
      updateBackground();
    }
  }

  public void setIconDrawable(@NonNull Drawable iconDrawable) {
    if (mIconDrawable != iconDrawable) {
      mIcon = 0;
      mIconDrawable = iconDrawable;
      updateBackground();
    }
  }

  public int getColorNormal() {
    return mColorNormal;
  }

  public void setColorNormalResId(@ColorRes int colorNormal) {
    setColorNormal(getColor(colorNormal));
  }

  public void setColorNormal(int color) {
    if (mColorNormal != color) {
      mColorNormal = color;
      updateBackground();
    }
  }

  public int getColorPressed() {
    return mColorPressed;
  }

  public void setColorPressedResId(@ColorRes int colorPressed) {
    setColorPressed(getColor(colorPressed));
  }

  public void setColorPressed(int color) {
    if (mColorPressed != color) {
      mColorPressed = color;
      updateBackground();
    }
  }

  public int getColorDisabled() {
    return mColorDisabled;
  }

  public void setColorDisabledResId(@ColorRes int colorDisabled) {
    setColorDisabled(getColor(colorDisabled));
  }

  public void setColorDisabled(int color) {
    if (mColorDisabled != color) {
        mColorDisabled = color;
        updateBackground();
    }
  }

  public void setStrokeVisible(boolean visible) {
    if (mStrokeVisible != visible) {
      mStrokeVisible = visible;
      updateBackground();
    }
  }

  public boolean isStrokeVisible() {
    return mStrokeVisible;
  }

  int getColor(@ColorRes int id) {
    return getResources().getColor(id);
  }

  float getDimension(@DimenRes int id) {
    return getResources().getDimension(id);
  }

  public void setTitle(String title) {
    mTitle = title;
    TextView label = getLabelView();
    if (label != null) {
      label.setText(title);
    }
  }

  TextView getLabelView() {
    return (TextView) getTag(R.id.fab_label);
  }

  public String getTitle() {
    return mTitle;
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    setMeasuredDimension(mDrawableSize, mDrawableSize);
  }

  void updateBackground() {
    final float strokeWidth = getDimension(R.dimen.fab_stroke_width);
    final float halfStrokeWidth = strokeWidth / 2f;

    LayerDrawable layerDrawable = new LayerDrawable(
        new Drawable[] {
            getResources().getDrawable(mSize == SIZE_NORMAL ? R.drawable.fab_bg_normal : R.drawable.fab_bg_mini),
            createFillDrawable(strokeWidth),
            createOuterStrokeDrawable(strokeWidth),
            getIconDrawable()
        });

    int iconOffset = (int) (mCircleSize - getDimension(R.dimen.fab_icon_size)) / 2;
    int circleInsetHorizontal = (int) (mShadowRadius);
    int circleInsetTop = (int) (mShadowRadius - mShadowOffset);
    int circleInsetBottom = (int) (mShadowRadius + mShadowOffset);

    layerDrawable.setLayerInset(1,
        circleInsetHorizontal,
        circleInsetTop,
        circleInsetHorizontal,
        circleInsetBottom);

    layerDrawable.setLayerInset(2,
        (int) (circleInsetHorizontal - halfStrokeWidth),
        (int) (circleInsetTop - halfStrokeWidth),
        (int) (circleInsetHorizontal - halfStrokeWidth),
        (int) (circleInsetBottom - halfStrokeWidth));

    layerDrawable.setLayerInset(3,
        circleInsetHorizontal + iconOffset,
        circleInsetTop + iconOffset,
        circleInsetHorizontal + iconOffset,
        circleInsetBottom + iconOffset);

    setBackgroundCompat(layerDrawable);
  }

  Drawable getIconDrawable() {
    if (mIconDrawable != null) {
      return mIconDrawable;
    } else if (mIcon != 0) {
      return getResources().getDrawable(mIcon);
    } else {
      return new ColorDrawable(Color.TRANSPARENT);
    }
  }

  private StateListDrawable createFillDrawable(float strokeWidth) {
    StateListDrawable drawable = new StateListDrawable();
    drawable.addState(new int[] { -android.R.attr.state_enabled }, createCircleDrawable(mColorDisabled, strokeWidth));
    drawable.addState(new int[] { android.R.attr.state_pressed }, createCircleDrawable(mColorPressed, strokeWidth));
    drawable.addState(new int[] { }, createCircleDrawable(mColorNormal, strokeWidth));
    return drawable;
  }

  private Drawable createCircleDrawable(int color, float strokeWidth) {
    int alpha = Color.alpha(color);
    int opaqueColor = opaque(color);
    ShapeDrawable fillDrawable = new ShapeDrawable(new OvalShape());

    final Paint paint = fillDrawable.getPaint();
    paint.setAntiAlias(true);
    paint.setColor(opaqueColor);

    Drawable[] layers = {
        fillDrawable,
        createInnerStrokesDrawable(opaqueColor, strokeWidth)
    };

    LayerDrawable drawable = alpha == 255 || !mStrokeVisible
        ? new LayerDrawable(layers)
        : new TranslucentLayerDrawable(alpha, layers);

    int halfStrokeWidth = (int) (strokeWidth / 2f);
    drawable.setLayerInset(1, halfStrokeWidth, halfStrokeWidth, halfStrokeWidth, halfStrokeWidth);

    return drawable;
  }

  private static class TranslucentLayerDrawable extends LayerDrawable {
    private final int mAlpha;

    public TranslucentLayerDrawable(int alpha, Drawable... layers) {
      super(layers);
      mAlpha = alpha;
    }

    @Override
    public void draw(Canvas canvas) {
      Rect bounds = getBounds();
      canvas.saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, mAlpha, Canvas.ALL_SAVE_FLAG);
      super.draw(canvas);
      canvas.restore();
    }
  }

  private Drawable createOuterStrokeDrawable(float strokeWidth) {
    ShapeDrawable shapeDrawable = new ShapeDrawable(new OvalShape());

    final Paint paint = shapeDrawable.getPaint();
    paint.setAntiAlias(true);
    paint.setStrokeWidth(strokeWidth);
    paint.setStyle(Style.STROKE);
    paint.setColor(Color.BLACK);
    paint.setAlpha(opacityToAlpha(0.02f));
    return shapeDrawable;
  }

  private int opacityToAlpha(float opacity) {
    return (int) (255f * opacity);
  }

  private int darkenColor(int argb) {
    return adjustColorBrightness(argb, 0.9f);
  }

  private int lightenColor(int argb) {
    return adjustColorBrightness(argb, 1.1f);
  }

  private int adjustColorBrightness(int argb, float factor) {
    float[] hsv = new float[3];
    Color.colorToHSV(argb, hsv);

    hsv[2] = Math.min(hsv[2] * factor, 1f);

    return Color.HSVToColor(Color.alpha(argb), hsv);
  }

  private int halfTransparent(int argb) {
    return Color.argb(
        Color.alpha(argb) / 2,
        Color.red(argb),
        Color.green(argb),
        Color.blue(argb)
    );
  }

  private int opaque(int argb) {
    return Color.rgb(
        Color.red(argb),
        Color.green(argb),
        Color.blue(argb)
    );
  }

  private Drawable createInnerStrokesDrawable(final int color, float strokeWidth) {
    if (!mStrokeVisible) {
      return new ColorDrawable(Color.TRANSPARENT);
    }

    ShapeDrawable shapeDrawable = new ShapeDrawable(new OvalShape());

    final int bottomStrokeColor = darkenColor(color);
    final int bottomStrokeColorHalfTransparent = halfTransparent(bottomStrokeColor);
    final int topStrokeColor = lightenColor(color);
    final int topStrokeColorHalfTransparent = halfTransparent(topStrokeColor);

    final Paint paint = shapeDrawable.getPaint();
    paint.setAntiAlias(true);
    paint.setStrokeWidth(strokeWidth);
    paint.setStyle(Style.STROKE);
    shapeDrawable.setShaderFactory(new ShaderFactory() {
      @Override
      public Shader resize(int width, int height) {
        return new LinearGradient(width / 2, 0, width / 2, height,
            new int[] { topStrokeColor, topStrokeColorHalfTransparent, color, bottomStrokeColorHalfTransparent, bottomStrokeColor },
            new float[] { 0f, 0.2f, 0.5f, 0.8f, 1f },
            TileMode.CLAMP
        );
      }
    });

    return shapeDrawable;
  }

  @SuppressWarnings("deprecation")
  @SuppressLint("NewApi")
  private void setBackgroundCompat(Drawable drawable) {
    if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
      setBackground(drawable);
    } else {
      setBackgroundDrawable(drawable);
    }
  }

  @Override
  public void setVisibility(int visibility) {
    TextView label = getLabelView();
    if (label != null) {
      label.setVisibility(visibility);
    }

    super.setVisibility(visibility);
  }
}

 

FloatingActionsMenu

package com.mobilprogramlar.floadnt;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.ContextThemeWrapper;
import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

public class FloatingActionsMenu extends ViewGroup {
  public static final int EXPAND_UP = 0;
  public static final int EXPAND_DOWN = 1;
  public static final int EXPAND_LEFT = 2;
  public static final int EXPAND_RIGHT = 3;
  public static final int LABELS_ON_LEFT_SIDE = 0;
  public static final int LABELS_ON_RIGHT_SIDE = 1;

  private static final int ANIMATION_DURATION = 300;
  private static final float COLLAPSED_PLUS_ROTATION = 0f;
  private static final float EXPANDED_PLUS_ROTATION = 90f + 45f;

  private int mAddButtonPlusColor;
  private int mAddButtonColorNormal;
  private int mAddButtonColorPressed;
  private int mAddButtonSize;
  private boolean mAddButtonStrokeVisible;
  private int mExpandDirection;
  private int mButtonSpacing;
  private int mLabelsMargin;
  private int mLabelsVerticalOffset;
  private boolean mExpanded;
  private AnimatorSet mExpandAnimation = new AnimatorSet().setDuration(ANIMATION_DURATION);
  private AnimatorSet mCollapseAnimation = new AnimatorSet().setDuration(ANIMATION_DURATION);
  private AddFloatingActionButton mAddButton;
  private RotatingDrawable mRotatingDrawable;
  private int mMaxButtonWidth;
  private int mMaxButtonHeight;
  private int mLabelsStyle;
  private int mLabelsPosition;
  private int mButtonsCount;

  private TouchDelegateGroup mTouchDelegateGroup;
  private OnFloatingActionsMenuUpdateListener mListener;

  public interface OnFloatingActionsMenuUpdateListener {
    void onMenuExpanded();
    void onMenuCollapsed();
  }

  public FloatingActionsMenu(Context context) {
    this(context, null);
  }

  public FloatingActionsMenu(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs);
  }

  public FloatingActionsMenu(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context, attrs);
  }

  private void init(Context context, AttributeSet attributeSet) {
    mButtonSpacing = (int) (getResources().getDimension(R.dimen.fab_actions_spacing) - getResources().getDimension(R.dimen.fab_shadow_radius) - getResources().getDimension(R.dimen.fab_shadow_offset));
    mLabelsMargin = getResources().getDimensionPixelSize(R.dimen.fab_labels_margin);
    mLabelsVerticalOffset = getResources().getDimensionPixelSize(R.dimen.fab_shadow_offset);

    mTouchDelegateGroup = new TouchDelegateGroup(this);
    setTouchDelegate(mTouchDelegateGroup);

    TypedArray attr = context.obtainStyledAttributes(attributeSet, R.styleable.FloatingActionsMenu, 0, 0);

    mAddButtonPlusColor = attr.getColor(R.styleable.FloatingActionsMenu_fab_addButtonPlusIconColor, getColorWrapper(context,android.R.color.white));
    mAddButtonColorNormal = attr.getColor(R.styleable.FloatingActionsMenu_fab_addButtonColorNormal, getColorWrapper(context,android.R.color.holo_blue_dark));
    mAddButtonColorPressed = attr.getColor(R.styleable.FloatingActionsMenu_fab_addButtonColorPressed, getColorWrapper(context,android.R.color.holo_blue_light));

    mAddButtonSize = attr.getInt(R.styleable.FloatingActionsMenu_fab_addButtonSize, FloatingActionButton.SIZE_NORMAL);
    mAddButtonStrokeVisible = attr.getBoolean(R.styleable.FloatingActionsMenu_fab_addButtonStrokeVisible, true);
    mExpandDirection = attr.getInt(R.styleable.FloatingActionsMenu_fab_expandDirection, EXPAND_UP);
    mLabelsStyle = attr.getResourceId(R.styleable.FloatingActionsMenu_fab_labelStyle, 0);
    mLabelsPosition = attr.getInt(R.styleable.FloatingActionsMenu_fab_labelsPosition, LABELS_ON_LEFT_SIDE);
    attr.recycle();

    if (mLabelsStyle != 0 && expandsHorizontally()) {
      throw new IllegalStateException("Action labels in horizontal expand orientation is not supported.");
    }
    createAddButton(context);
  }

  public void setOnFloatingActionsMenuUpdateListener(OnFloatingActionsMenuUpdateListener listener) {
    mListener = listener;
  }

  private boolean expandsHorizontally() {
    return mExpandDirection == EXPAND_LEFT || mExpandDirection == EXPAND_RIGHT;
  }

  private static class RotatingDrawable extends LayerDrawable {
    public RotatingDrawable(Drawable drawable) {
      super(new Drawable[] { drawable });
    }

    private float mRotation;

    @SuppressWarnings("UnusedDeclaration")
    public float getRotation() {
      return mRotation;
    }

    @SuppressWarnings("UnusedDeclaration")
    public void setRotation(float rotation) {
      mRotation = rotation;
      invalidateSelf();
    }

    @Override
    public void draw(Canvas canvas) {
      canvas.save();
      canvas.rotate(mRotation, getBounds().centerX(), getBounds().centerY());
      super.draw(canvas);
      canvas.restore();
    }
  }

  private void createAddButton(Context context) {
    mAddButton = new AddFloatingActionButton(context) {
      @Override
      void updateBackground() {
        mPlusColor = mAddButtonPlusColor;
        mColorNormal = mAddButtonColorNormal;
        mColorPressed = mAddButtonColorPressed;
        mStrokeVisible = mAddButtonStrokeVisible;
        super.updateBackground();
      }

      @Override
      Drawable getIconDrawable() {
        final RotatingDrawable rotatingDrawable = new RotatingDrawable(super.getIconDrawable());
        mRotatingDrawable = rotatingDrawable;
        final OvershootInterpolator interpolator = new OvershootInterpolator();
        final ObjectAnimator collapseAnimator = ObjectAnimator.ofFloat(rotatingDrawable, "rotation", EXPANDED_PLUS_ROTATION, COLLAPSED_PLUS_ROTATION);
        final ObjectAnimator expandAnimator = ObjectAnimator.ofFloat(rotatingDrawable, "rotation", COLLAPSED_PLUS_ROTATION, EXPANDED_PLUS_ROTATION);
        collapseAnimator.setInterpolator(interpolator);
        expandAnimator.setInterpolator(interpolator);

        mExpandAnimation.play(expandAnimator);
        mCollapseAnimation.play(collapseAnimator);
        return rotatingDrawable;
      }
    };

    mAddButton.setId(R.id.fab_expand_menu_button);
    mAddButton.setSize(mAddButtonSize);
    mAddButton.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        toggle();
      }
    });

    addView(mAddButton, super.generateDefaultLayoutParams());
    mButtonsCount++;
  }

  public void addButton(FloatingActionButton button) {
    addView(button, mButtonsCount - 1);
    mButtonsCount++;

    if (mLabelsStyle != 0) {
      createLabels();
    }
  }

  public void removeButton(FloatingActionButton button) {
    removeView(button.getLabelView());
    removeView(button);
    button.setTag(R.id.fab_label, null);
    mButtonsCount--;
  }

  private static int getColorWrapper(Context context, int id) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
      return context.getColor(id);
    } else {
      return context.getResources().getColor(id);
    }
  }



  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    measureChildren(widthMeasureSpec, heightMeasureSpec);
    int width = 0;
    int height = 0;
    mMaxButtonWidth = 0;
    mMaxButtonHeight = 0;
    int maxLabelWidth = 0;

    for (int i = 0; i < mButtonsCount; i++) {
      View child = getChildAt(i);
      if (child.getVisibility() == GONE) {
        continue;
      }
      switch (mExpandDirection) {
      case EXPAND_UP:
      case EXPAND_DOWN:
        mMaxButtonWidth = Math.max(mMaxButtonWidth, child.getMeasuredWidth());
        height += child.getMeasuredHeight();
        break;
      case EXPAND_LEFT:
      case EXPAND_RIGHT:
        width += child.getMeasuredWidth();
        mMaxButtonHeight = Math.max(mMaxButtonHeight, child.getMeasuredHeight());
        break;
      }

      if (!expandsHorizontally()) {
        TextView label = (TextView) child.getTag(R.id.fab_label);
        if (label != null) {
          maxLabelWidth = Math.max(maxLabelWidth, label.getMeasuredWidth());
        }
      }
    }

    if (!expandsHorizontally()) {
      width = mMaxButtonWidth + (maxLabelWidth > 0 ? maxLabelWidth + mLabelsMargin : 0);
    } else {
      height = mMaxButtonHeight;
    }

    switch (mExpandDirection) {
    case EXPAND_UP:
    case EXPAND_DOWN:
      height += mButtonSpacing * (mButtonsCount - 1);
      height = adjustForOvershoot(height);
      break;
    case EXPAND_LEFT:
    case EXPAND_RIGHT:
      width += mButtonSpacing * (mButtonsCount - 1);
      width = adjustForOvershoot(width);
      break;
    }

    setMeasuredDimension(width, height);
  }

  private int adjustForOvershoot(int dimension) {
    return dimension * 12 / 10;
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    switch (mExpandDirection) {
    case EXPAND_UP:
    case EXPAND_DOWN:
      boolean expandUp = mExpandDirection == EXPAND_UP;

      if (changed) {
        mTouchDelegateGroup.clearTouchDelegates();
      }

      int addButtonY = expandUp ? b - t - mAddButton.getMeasuredHeight() : 0;
      int buttonsHorizontalCenter = mLabelsPosition == LABELS_ON_LEFT_SIDE
          ? r - l - mMaxButtonWidth / 2
          : mMaxButtonWidth / 2;
      int addButtonLeft = buttonsHorizontalCenter - mAddButton.getMeasuredWidth() / 2;
      mAddButton.layout(addButtonLeft, addButtonY, addButtonLeft + mAddButton.getMeasuredWidth(), addButtonY + mAddButton.getMeasuredHeight());

      int labelsOffset = mMaxButtonWidth / 2 + mLabelsMargin;
      int labelsXNearButton = mLabelsPosition == LABELS_ON_LEFT_SIDE
          ? buttonsHorizontalCenter - labelsOffset
          : buttonsHorizontalCenter + labelsOffset;

      int nextY = expandUp ?
          addButtonY - mButtonSpacing :
          addButtonY + mAddButton.getMeasuredHeight() + mButtonSpacing;

      for (int i = mButtonsCount - 1; i >= 0; i--) {
        final View child = getChildAt(i);

        if (child == mAddButton || child.getVisibility() == GONE) continue;

        int childX = buttonsHorizontalCenter - child.getMeasuredWidth() / 2;
        int childY = expandUp ? nextY - child.getMeasuredHeight() : nextY;
        child.layout(childX, childY, childX + child.getMeasuredWidth(), childY + child.getMeasuredHeight());

        float collapsedTranslation = addButtonY - childY;
        float expandedTranslation = 0f;
        child.setTranslationY(mExpanded ? expandedTranslation : collapsedTranslation);
        child.setAlpha(mExpanded ? 1f : 0f);

        LayoutParams params = (LayoutParams) child.getLayoutParams();
        params.mCollapseDir.setFloatValues(expandedTranslation, collapsedTranslation);
        params.mExpandDir.setFloatValues(collapsedTranslation, expandedTranslation);
        params.setAnimationsTarget(child);

        View label = (View) child.getTag(R.id.fab_label);
        if (label != null) {
          int labelXAwayFromButton = mLabelsPosition == LABELS_ON_LEFT_SIDE
              ? labelsXNearButton - label.getMeasuredWidth()
              : labelsXNearButton + label.getMeasuredWidth();

          int labelLeft = mLabelsPosition == LABELS_ON_LEFT_SIDE
              ? labelXAwayFromButton
              : labelsXNearButton;

          int labelRight = mLabelsPosition == LABELS_ON_LEFT_SIDE
              ? labelsXNearButton
              : labelXAwayFromButton;

          int labelTop = childY - mLabelsVerticalOffset + (child.getMeasuredHeight() - label.getMeasuredHeight()) / 2;
          label.layout(labelLeft, labelTop, labelRight, labelTop + label.getMeasuredHeight());
          Rect touchArea = new Rect(
              Math.min(childX, labelLeft),
              childY - mButtonSpacing / 2,
              Math.max(childX + child.getMeasuredWidth(), labelRight),
              childY + child.getMeasuredHeight() + mButtonSpacing / 2);
          mTouchDelegateGroup.addTouchDelegate(new TouchDelegate(touchArea, child));

          label.setTranslationY(mExpanded ? expandedTranslation : collapsedTranslation);
          label.setAlpha(mExpanded ? 1f : 0f);

          LayoutParams labelParams = (LayoutParams) label.getLayoutParams();
          labelParams.mCollapseDir.setFloatValues(expandedTranslation, collapsedTranslation);
          labelParams.mExpandDir.setFloatValues(collapsedTranslation, expandedTranslation);
          labelParams.setAnimationsTarget(label);
        }

        nextY = expandUp ?
            childY - mButtonSpacing :
            childY + child.getMeasuredHeight() + mButtonSpacing;
      }
      break;

    case EXPAND_LEFT:
    case EXPAND_RIGHT:
      boolean expandLeft = mExpandDirection == EXPAND_LEFT;

      int addButtonX = expandLeft ? r - l - mAddButton.getMeasuredWidth() : 0;
      int addButtonTop = b - t - mMaxButtonHeight + (mMaxButtonHeight - mAddButton.getMeasuredHeight()) / 2;
      mAddButton.layout(addButtonX, addButtonTop, addButtonX + mAddButton.getMeasuredWidth(), addButtonTop + mAddButton.getMeasuredHeight());

      int nextX = expandLeft ?
          addButtonX - mButtonSpacing :
          addButtonX + mAddButton.getMeasuredWidth() + mButtonSpacing;

      for (int i = mButtonsCount - 1; i >= 0; i--) {
        final View child = getChildAt(i);
        if (child == mAddButton || child.getVisibility() == GONE) continue;
        int childX = expandLeft ? nextX - child.getMeasuredWidth() : nextX;
        int childY = addButtonTop + (mAddButton.getMeasuredHeight() - child.getMeasuredHeight()) / 2;
        child.layout(childX, childY, childX + child.getMeasuredWidth(), childY + child.getMeasuredHeight());

        float collapsedTranslation = addButtonX - childX;
        float expandedTranslation = 0f;
        child.setTranslationX(mExpanded ? expandedTranslation : collapsedTranslation);
        child.setAlpha(mExpanded ? 1f : 0f);

        LayoutParams params = (LayoutParams) child.getLayoutParams();
        params.mCollapseDir.setFloatValues(expandedTranslation, collapsedTranslation);
        params.mExpandDir.setFloatValues(collapsedTranslation, expandedTranslation);
        params.setAnimationsTarget(child);
        nextX = expandLeft ?
            childX - mButtonSpacing :
            childX + child.getMeasuredWidth() + mButtonSpacing;
      }
      break;
    }
  }

  @Override
  protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(super.generateDefaultLayoutParams());
  }

  @Override
  public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
    return new LayoutParams(super.generateLayoutParams(attrs));
  }

  @Override
  protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
    return new LayoutParams(super.generateLayoutParams(p));
  }

  @Override
  protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
    return super.checkLayoutParams(p);
  }

  private static Interpolator sExpandInterpolator = new OvershootInterpolator();
  private static Interpolator sCollapseInterpolator = new DecelerateInterpolator(3f);
  private static Interpolator sAlphaExpandInterpolator = new DecelerateInterpolator();

  private class LayoutParams extends ViewGroup.LayoutParams {

    private ObjectAnimator mExpandDir = new ObjectAnimator();
    private ObjectAnimator mExpandAlpha = new ObjectAnimator();
    private ObjectAnimator mCollapseDir = new ObjectAnimator();
    private ObjectAnimator mCollapseAlpha = new ObjectAnimator();
    private boolean animationsSetToPlay;

    public LayoutParams(ViewGroup.LayoutParams source) {
      super(source);

      mExpandDir.setInterpolator(sExpandInterpolator);
      mExpandAlpha.setInterpolator(sAlphaExpandInterpolator);
      mCollapseDir.setInterpolator(sCollapseInterpolator);
      mCollapseAlpha.setInterpolator(sCollapseInterpolator);
      mCollapseAlpha.setProperty(View.ALPHA);
      mCollapseAlpha.setFloatValues(1f, 0f);
      mExpandAlpha.setProperty(View.ALPHA);
      mExpandAlpha.setFloatValues(0f, 1f);

      switch (mExpandDirection) {
      case EXPAND_UP:
      case EXPAND_DOWN:
        mCollapseDir.setProperty(View.TRANSLATION_Y);
        mExpandDir.setProperty(View.TRANSLATION_Y);
        break;
      case EXPAND_LEFT:
      case EXPAND_RIGHT:
        mCollapseDir.setProperty(View.TRANSLATION_X);
        mExpandDir.setProperty(View.TRANSLATION_X);
        break;
      }
    }

    public void setAnimationsTarget(View view) {
      mCollapseAlpha.setTarget(view);
      mCollapseDir.setTarget(view);
      mExpandAlpha.setTarget(view);
      mExpandDir.setTarget(view);

      // Now that the animations have targets, set them to be played
      if (!animationsSetToPlay) {
        addLayerTypeListener(mExpandDir, view);
        addLayerTypeListener(mCollapseDir, view);
        mCollapseAnimation.play(mCollapseAlpha);
        mCollapseAnimation.play(mCollapseDir);
        mExpandAnimation.play(mExpandAlpha);
        mExpandAnimation.play(mExpandDir);
        animationsSetToPlay = true;
      }
    }

    private void addLayerTypeListener(Animator animator, final View view) {
      animator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
          view.setLayerType(LAYER_TYPE_NONE, null);
        }

        @Override
        public void onAnimationStart(Animator animation) {
          view.setLayerType(LAYER_TYPE_HARDWARE, null);
        }
      });
    }
  }

  @Override
  protected void onFinishInflate() {
    super.onFinishInflate();

    bringChildToFront(mAddButton);
    mButtonsCount = getChildCount();

    if (mLabelsStyle != 0) {
      createLabels();
    }
  }

  private void createLabels() {
    Context context = new ContextThemeWrapper(getContext(), mLabelsStyle);

    for (int i = 0; i < mButtonsCount; i++) {
      FloatingActionButton button = (FloatingActionButton) getChildAt(i);
      String title = button.getTitle();

      if (button == mAddButton || title == null ||
          button.getTag(R.id.fab_label) != null) continue;

      TextView label = new TextView(context);
      label.setTextAppearance(getContext(), mLabelsStyle);
      label.setText(button.getTitle());
      addView(label);
      button.setTag(R.id.fab_label, label);
    }
  }

  public void collapse() {
    collapse(false);
  }
  public void collapseImmediately() {
    collapse(true);
  }
  private void collapse(boolean immediately) {
    if (mExpanded) {
      mExpanded = false;
      mTouchDelegateGroup.setEnabled(false);
      mCollapseAnimation.setDuration(immediately ? 0 : ANIMATION_DURATION);
      mCollapseAnimation.start();
      mExpandAnimation.cancel();

      if (mListener != null) {
        mListener.onMenuCollapsed();
      }
    }
  }

  public void toggle() {
    if (mExpanded) {
      collapse();
    } else {
      expand();
    }
  }

  public void expand() {
    if (!mExpanded) {
      mExpanded = true;
      mTouchDelegateGroup.setEnabled(true);
      mCollapseAnimation.cancel();
      mExpandAnimation.start();

      if (mListener != null) {
        mListener.onMenuExpanded();
      }
    }
  }

  public boolean isExpanded() {
    return mExpanded;
  }

  @Override
  public void setEnabled(boolean enabled) {
    super.setEnabled(enabled);
    mAddButton.setEnabled(enabled);
  }

  @Override
  public Parcelable onSaveInstanceState() {
    Parcelable superState = super.onSaveInstanceState();
    SavedState savedState = new SavedState(superState);
    savedState.mExpanded = mExpanded;
    return savedState;
  }

  @Override
  public void onRestoreInstanceState(Parcelable state) {
    if (state instanceof SavedState) {
      SavedState savedState = (SavedState) state;
      mExpanded = savedState.mExpanded;
      mTouchDelegateGroup.setEnabled(mExpanded);

      if (mRotatingDrawable != null) {
        mRotatingDrawable.setRotation(mExpanded ? EXPANDED_PLUS_ROTATION : COLLAPSED_PLUS_ROTATION);
      }

      super.onRestoreInstanceState(savedState.getSuperState());
    } else {
      super.onRestoreInstanceState(state);
    }
  }

  public static class SavedState extends BaseSavedState {
    public boolean mExpanded;
    public SavedState(Parcelable parcel) {
      super(parcel);
    }

    private SavedState(Parcel in) {
      super(in);
      mExpanded = in.readInt() == 1;
    }

    @Override
    public void writeToParcel(@NonNull Parcel out, int flags) {
      super.writeToParcel(out, flags);
      out.writeInt(mExpanded ? 1 : 0);
    }

    public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
      @Override
      public SavedState createFromParcel(Parcel in) {
        return new SavedState(in);
      }

      @Override
      public SavedState[] newArray(int size) {
        return new SavedState[size];
      }
    };
  }
}

 

TouchDelegateGroup

package com.mobilprogramlar.floadnt;

import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.TouchDelegate;
import android.view.View;
import androidx.annotation.NonNull;
import java.util.ArrayList;

public class TouchDelegateGroup extends TouchDelegate {
  private static final Rect USELESS_HACKY_RECT = new Rect();
  private final ArrayList<TouchDelegate> mTouchDelegates = new ArrayList<TouchDelegate>();
  private TouchDelegate mCurrentTouchDelegate;
  private boolean mEnabled;

  public TouchDelegateGroup(View uselessHackyView) {
    super(USELESS_HACKY_RECT, uselessHackyView);
  }

  public void addTouchDelegate(@NonNull TouchDelegate touchDelegate) {
    mTouchDelegates.add(touchDelegate);
  }

  public void removeTouchDelegate(TouchDelegate touchDelegate) {
    mTouchDelegates.remove(touchDelegate);
    if (mCurrentTouchDelegate == touchDelegate) {
      mCurrentTouchDelegate = null;
    }
  }

  public void clearTouchDelegates() {
    mTouchDelegates.clear();
    mCurrentTouchDelegate = null;
  }

  @Override
  public boolean onTouchEvent(@NonNull MotionEvent event) {
    if (!mEnabled) return false;

    TouchDelegate delegate = null;

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
      for (int i = 0; i < mTouchDelegates.size(); i++) {
        TouchDelegate touchDelegate = mTouchDelegates.get(i);
        if (touchDelegate.onTouchEvent(event)) {
          mCurrentTouchDelegate = touchDelegate;
          return true;
        }
      }
      break;

    case MotionEvent.ACTION_MOVE:
      delegate = mCurrentTouchDelegate;
      break;

    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
      delegate = mCurrentTouchDelegate;
      mCurrentTouchDelegate = null;
      break;
    }

    return delegate != null && delegate.onTouchEvent(event);
  }

  public void setEnabled(boolean enabled) {
    mEnabled = enabled;
  }
}

 

MainActivity

package com.mobilprogramlar.floadnt;

import androidx.appcompat.app.AppCompatActivity;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.pink_icon).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "Clicked pink Floating Action Button", Toast.LENGTH_SHORT).show();
            }
        });

        FloatingActionButton button = (FloatingActionButton) findViewById(R.id.setter);
        button.setSize(FloatingActionButton.SIZE_MINI);
        button.setColorNormalResId(R.color.pink);
        button.setColorPressedResId(R.color.pink_pressed);
        button.setIcon(R.drawable.ic_fab_star);
        button.setStrokeVisible(false);

        final View actionB = findViewById(R.id.action_b);

        FloatingActionButton actionC = new FloatingActionButton(getBaseContext());
        actionC.setTitle("Hide/Show Action above");
        actionC.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                actionB.setVisibility(actionB.getVisibility() == View.GONE ? View.VISIBLE : View.GONE);
            }
        });

        final FloatingActionsMenu menuMultipleActions = (FloatingActionsMenu) findViewById(R.id.multiple_actions);
        menuMultipleActions.addButton(actionC);

        final FloatingActionButton removeAction = (FloatingActionButton) findViewById(R.id.button_remove);
        removeAction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ((FloatingActionsMenu) findViewById(R.id.multiple_actions_down)).removeButton(removeAction);
            }
        });

        ShapeDrawable drawable = new ShapeDrawable(new OvalShape());
        drawable.getPaint().setColor(getResources().getColor(R.color.white));
        ((FloatingActionButton) findViewById(R.id.setter_drawable)).setIconDrawable(drawable);

        final FloatingActionButton actionA = (FloatingActionButton) findViewById(R.id.action_a);
        actionA.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                actionA.setTitle("Action A clicked");
            }
        });

        findViewById(R.id.button_gone).setVisibility(View.GONE);

        final FloatingActionButton actionEnable = (FloatingActionButton) findViewById(R.id.action_enable);
        actionEnable.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                menuMultipleActions.setEnabled(!menuMultipleActions.isEnabled());
            }
        });

        FloatingActionsMenu rightLabels = (FloatingActionsMenu) findViewById(R.id.right_labels);
        FloatingActionButton addedOnce = new FloatingActionButton(this);
        addedOnce.setTitle("Added once");
        rightLabels.addButton(addedOnce);

        FloatingActionButton addedTwice = new FloatingActionButton(this);
        addedTwice.setTitle("Added twice");
        rightLabels.addButton(addedTwice);
        rightLabels.removeButton(addedTwice);
        rightLabels.addButton(addedTwice);
    }
}

 

 

Value dizininin altına attrss.xml, colors.xml, dimens.xml, ids.xml, string.xml ve styles.xml dosyalarını ekliyoruz.

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="FloatingActionButton">
        <attr name="fab_colorPressed" format="color"/>
        <attr name="fab_colorDisabled" format="color"/>
        <attr name="fab_colorNormal" format="color"/>
        <attr name="fab_icon" format="reference"/>
        <attr name="fab_size" format="enum">
            <enum name="normal" value="0"/>
            <enum name="mini" value="1"/>
        </attr>
        <attr name="fab_title" format="string"/>
        <attr name="fab_stroke_visible" format="boolean"/>
    </declare-styleable>
    <declare-styleable name="AddFloatingActionButton">
        <attr name="fab_plusIconColor" format="color"/>
    </declare-styleable>
    <declare-styleable name="FloatingActionsMenu">
        <attr name="fab_addButtonColorPressed" format="color"/>
        <attr name="fab_addButtonColorNormal" format="color"/>
        <attr name="fab_addButtonSize" format="enum">
            <enum name="normal" value="0"/>
            <enum name="mini" value="1"/>
        </attr>
        <attr name="fab_addButtonPlusIconColor" format="color"/>
        <attr name="fab_addButtonStrokeVisible" format="boolean"/>
        <attr name="fab_labelStyle" format="reference"/>
        <attr name="fab_labelsPosition" format="enum">
            <enum name="left" value="0"/>
            <enum name="right" value="1"/>
        </attr>
        <attr name="fab_expandDirection" format="enum">
            <enum name="up" value="0"/>
            <enum name="down" value="1"/>
            <enum name="left" value="2"/>
            <enum name="right" value="3"/>
        </attr>
    </declare-styleable>
</resources>

 

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#008577</color>
    <color name="colorPrimaryDark">#00574B</color>
    <color name="colorAccent">#D81B60</color>

    <color name="black_semi_transparent">#B2000000</color>
    <color name="background">#e5e5e5</color>
    <color name="half_black">#808080</color>
    <color name="white">#fafafa</color>
    <color name="white_pressed">#f1f1f1</color>
    <color name="pink">#e91e63</color>
    <color name="pink_pressed">#ec407a</color>
    <color name="blue_semi_transparent">#805677fc</color>
    <color name="blue_semi_transparent_pressed">#80738ffe</color>
</resources>

 

dimans.xml

<resources>
    <dimen name="fab_size_normal">56dp</dimen>
    <dimen name="fab_size_mini">40dp</dimen>

    <dimen name="fab_icon_size">24dp</dimen>

    <dimen name="fab_plus_icon_size">14dp</dimen>
    <dimen name="fab_plus_icon_stroke">2dp</dimen>

    <dimen name="fab_shadow_offset">3dp</dimen>
    <dimen name="fab_shadow_radius">9dp</dimen>

    <dimen name="fab_stroke_width">1dp</dimen>

    <dimen name="fab_actions_spacing">16dp</dimen>
    <dimen name="fab_labels_margin">8dp</dimen>
</resources>

 

ids.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="fab_expand_menu_button" type="id"/>
    <item name="fab_label" type="id"/>
</resources>

String.xml

<resources>
    <string name="app_name">Fload NT</string>
    <string name="text_below_button">Text below button</string>
</resources>

Styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="menu_labels_style">
        <item name="android:background">@drawable/fab_label_background</item>
        <item name="android:textColor">@color/white</item>
    </style>

</resources>

 

drawable klasörünün altına ise

fab_label_background.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/black_semi_transparent"/>
    <padding
        android:left="16dp"
        android:top="4dp"
        android:right="16dp"
        android:bottom="4dp"/>
    <corners
        android:radius="2dp"/>
</shape>

Ayrıca alttaki 3 resim dosyasını da drawable klasörü altına ekliyoruz.

farklı telefon boyutları için bu resimlerin faklı ebatlarını yazının sonunda ki dosyanın tamamını indirebileceğiniz linki verdiğimde oradan indirebilirsiniz.

Sonuç;

Anlatılanların tamamının Android Studio daki kaynak kod ve reimleri aşağıdaki linkten indirebilirsiniz.

İndir

 

Android Studio’ya Genel Bakış

Android Studio, IntelliJ IDEA’ya dayanan Android uygulama geliştirme resmi IDE’sidir . IntelliJ’den beklediğiniz özelliklerin yanı sıra, Android Studio şunları sunar:

  • Esnek Gradle tabanlı yapı sistemi
  • Değişkenler ve çoklu apkdosya oluşturma
  • Ortak uygulama özellikleri oluşturmanıza yardımcı olacak kod şablonları
  • Sürükle ve bırak tema düzenleme desteği ile zengin düzen düzenleyici
  • Performansı, kullanılabilirliği, sürüm uyumluluğunu ve diğer sorunları yakalamak için Lint araçları
  • ProGuard ve uygulama imzalama yetenekleri
  • Google Cloud Platform için yerleşik destek , Google Cloud Messaging ve App Engine’i entegre etmeyi kolaylaştırır
  • Ve daha fazlası

Şimdi Android Studio’yu indirin .

Android Studio veya IntelliJ IDEA arayüzünde yeniyseniz, bu sayfa bazı temel Android Studio özelliklerine giriş sağlar.

Proje ve Dosya Yapısı


Android Proje Görünümü

Varsayılan olarak, Android Studio profil dosyalarınızı Android proje görünümünde görüntüler. Bu görünüm, Android projelerinin temel kaynak dosyalarına hızlı erişim sağlayan ve yeni Gradle tabanlı yapı sistemiyle çalışmanıza yardımcı olan, projenizin yapısının düzleştirilmiş halini gösterir . Android proje görünümü:

  • Tüm modüllerin derleme dosyalarını proje hiyerarşisinin en üst düzeyinde gruplandırır.
  • Modül hiyerarşisinin en üst düzeyindeki en önemli kaynak dizinlerini gösterir.
  • Her modül için tüm manifest dosyalarını gruplandırır.
  • Tüm Gradle kaynak kümelerindeki kaynak dosyalarını gösterir.
  • Farklı yerel, oryantasyon ve ekran türleri için kaynak dosyalarını kaynak türü başına tek bir grupta gruplandırır.
  • Şekil 1. Android proje görünümünü göster.

    Şekil 2. Proje Oluşturma Dosyaları.

 

Android proje görünümü altında proje hiyerarşisinin en üst düzeyinde tüm yapı dosyaları gösterir Gradle Script . Her proje modülü, proje hiyerarşisinin en üst düzeyinde bir klasör olarak görünür ve bu üç öğeyi en üst düzeyde içerir:

  • java/ – Modül için kaynak dosyalar.
  • manifests/ – Modül için dosya listesi.
  • res/ – Modül için kaynak dosyaları.

Örneğin, Android proje görünümü ic_launcher.png aynı öğenin altındaki farklı ekran yoğunlukları için kaynağın tüm örneklerini gruplandırır .

Not: Diskteki proje yapısı bu düzleştirilmiş gösterimden farklıdır.  Ayrılmış proje görünümünü geri seçmek geçmek için Project dan Projenizi seçin.

Yeni Proje ve Dizin Yapısı

Android Studio’da yeni bir projenin Proje görünümünü kullandığınızda, proje yapısının Eclipse’de kullandığınızdan farklı göründüğünü fark etmelisiniz.

Android Studio’nun her örneği bir veya daha fazla uygulama modülüne sahip bir proje içerir. Her uygulama modülü klasörü, söz konusu modül için eksiksiz kaynak kümelerini içerir.

Her uygulama modülü klasör dahil olmak üzere bu modül için komple kaynak setleri içeren src / main ve src / androidTest dizinleri, kaynakları, derleme dosyası ve Android bildirimi dahil.

Çoğunlukla, src/main kaynak kod güncellemeleri için her bir modülün dizinindeki dosyaları, derleme belirtimi için gradle.build dosyasını ve src/androidTesttest senaryosu oluşturma için dizindeki dosyaları değiştirmeniz gerekecektir .

 

Şekil 3. Android Studio proje yapısı

 

Yeni dosyalar oluşturma

Proje bölmesinde uygun dizini tıklatarak ve ALT + INSERTWindows ve Linux ya COMMAND + Nda Mac’te tuşuna basarak hızlıca yeni kod ve kaynak dosyaları ekleyebilirsiniz . Seçilen dizinin türüne bağlı olarak, Android Studio uygun dosya türünü oluşturmayı teklif eder.

Örneğin, bir layout (düzen) dizini seçtiyseniz ALT + INSERT, Windows’a basın ve Layout resource file (Mizanpaj kaynak dosyası)’nı seçtiğinizde , dosyayı adlandırabilmeniz ( .xmlson eki hariç tutabilirsiniz ) ve bir kök görünümü öğesi seçebilmeniz için bir iletişim kutusu açılır . Sonra editör, düzen tasarım editörüne geçer, böylece düzeninizi tasarlamaya başlayabilirsiniz.

Android Yapı Sistemi


Android Yapı Sistemi

Android yapı sistemi, uygulamalarınızı oluşturmak, test etmek, çalıştırmak ve paketlemek için kullandığınız araç takımıdır. Bu derleme sistemi, Eclipse ADT ile kullanılan Ant sisteminin yerini almaktadır. Android Studio menüsünden entegre bir araç olarak ve komut satırından bağımsız olarak çalışabilir. Yapı sisteminin özelliklerini aşağıdakiler için kullanabilirsiniz:

  • Derleme işlemini özelleştirin, yapılandırın ve genişletin.
  • Uygulamanız için aynı projeyi ve modülleri kullanarak farklı özelliklere sahip birden fazla APK oluşturun.
  • Kaynak kümeler arasında kodu ve kaynakları yeniden kullanın.

Android derleme sisteminin esnekliği, uygulamanızın çekirdek kaynak dosyalarını değiştirmeden tüm bunları başarmanıza olanak sağlar. Bir Android Studio projesi oluşturmak için, bkz . Android Studio’dan İnşa Etme ve Çalıştırma .

Package (Paket) Tanımlama için Application ID (Uygulama Kimliği)

Android derleme sistemiyle, applicationId niteliği, yayınlanacak uygulama paketlerini benzersiz şekilde tanımlamak için kullanılır. Uygulama kimliği, dosyanın android bölümünde ayarlanmıştır build.gradle.

apply plugin: 'com.android.application'

    android {
        compileSdkVersion 19
        buildToolsVersion "19.1"

    defaultConfig {
        applicationId "com.example.my.app"
        minSdkVersion 15
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    ...

Not: applicationID, AndroidManifest.xml dosyasında değil, yalnızca build.gradle dosyasında belirtilir.

Yapı değişkenlerini kullanırken yapı sistemi, her ürün çeşidi ve yapı türü için farklı paketler tanımlamanızı sağlar. Yapı türündeki uygulama kimliği, ürün çeşitleri için belirtilenlere ek olarak eklenir.

productFlavors {
        pro {
            applicationId = "com.example.my.pkg.pro"
        }
        free {
            applicationId = "com.example.my.pkg.free"
        }
    }
    buildTypes {
        debug {
            applicationIdSuffix ".debug"
        }
    }
    ....

Paket adı hala bildirim dosyasında belirtilmelidir. Kaynak kodunuzda R sınıfınıza atıfta bulunmak ve göreceli etkinlik / hizmet kayıtlarını çözmek için kullanılır.

package="com.example.app">

Not: Birden fazla bildiriminiz varsa (örneğin, ürün lezzetine özgü bir bildirim ve yapı türü bildirimi), bu bildirimlerde paket adı isteğe bağlıdır. Bu bildirimlerde belirtilmişse, paket adının, src/main/klasördeki bildirimlerde belirtilen paket adıyla aynı olması gerekir .

Hata Ayıklama ve Performans


Android Sanal Aygıt (AVD) Yöneticisi

AVD Manager, uygulama önizlemeniz için en popüler cihaz yapılandırmalarını, ekran boyutlarını ve çözünürlüklerini seçmenize yardımcı olacak bağlantıları içeren ekranları güncelledi.

Açmak ve uygulamanızı emülatörde çalıştırmak için yeni sanal cihazlar oluşturmak için araç çubuğundaki Android Sanal Aygıt Yöneticisi’ni tıklayın.  .

AVD Manager, Nexus 6 ve Nexus 9 cihazları için emülatörlerle gelir ve ayrıca belirli emülatör özelliklerine göre özel Android cihaz kaplamaları oluşturmayı ve bu kaplamaları donanım profillerine atamayı destekler. Android Studio, Intel® x86 Donanım Hızlandırılmış Uygulama Yöneticisi (HAXM) emülatör hızlandırıcısını kurar ve hızlı uygulama prototiplemesi için varsayılan bir emülatör oluşturur.

Hafıza Monitörü

Android Studio, bir bellek izleme görünümü sağlar; böylece serbest bırakılmış nesneleri bulmak, bellek sızıntılarını bulmak ve bağlı cihazın kullandığı bellek miktarını izlemek için uygulamanızın bellek kullanımını daha kolay izleyebilirsiniz. Uygulamanız bir cihazda veya taklitçide çalışırken , bellek monitörünü başlatmak için sağ alt köşedeki Bellek Monitörü sekmesine tıklayın.

Yeni Lint denetimleri

Lint, aşağıdakileri sağlamak için birkaç yeni kontrole sahip:

  • Cipher.getInstance() güvenli değerlerle kullanılır
  • Özel Görünümler’de, özel görünüm için ilişkilendirilmiş bildirimle stillenebilir, sınıf adıyla aynı temel adı kullanır.
  • fragment(parça) injection. için güvenlik kontrolü.
  • Artık mülk ataması artık beklendiği gibi çalışmıyor.
  • Gradle eklentisi sürümü, SDK ile uyumludur.
  • Soldan sağa doğrulama
  • Gerekli API sürümü
  • diğerleri

Lint hatasının üzerine gelmek, kolay hata çözümü için tam açıklama açıklama satırını görüntüler. Ayrıca ek hata bilgisi için hata mesajının sonunda yararlı bir köprü vardır.

Android Studio ile Lint’i belirli bir yapı değişkeni veya tüm yapı biçimleri için çalıştırabilirsiniz. LintOptions özelliğini, build.gradle dosyasındaki Android ayarlarına ekleyerek Lint’i yapılandırabilirsiniz .

android {
        lintOptions {
           // set to true to turn off analysis progress reporting by lint
           quiet true
           // if true, stop the gradle build if errors are found
           abortOnError false
           // if true, only report errors
           ignoreWarnings true

Dinamik düzen önizlemesi

Android Studio, hem Tasarım Görünümünde düzenlerle çalışmanıza olanak sağlar

Şekil 5. Tasarım Görünümü ile Hello World Uygulaması

ve bir Metin Görünümü .

Şekil 6. Metin Görünümü ile Hello World Uygulaması

Farklı cihaz görüntüleri, ekran yoğunlukları, kullanıcı arayüzü modları, yerel ayarlar ve Android sürümleri (çoklu API sürüm oluşturma) için mizanpaj değişikliklerini kolayca seçin ve önizleyin.

Şekil 7. API Sürümü Oluşturma

Tasarım Görünümünde, öğeleri Paletten Önizleme veya Bileşen Ağacı’na sürükleyip bırakabilirsiniz. Metin Görünümü, cihazın görüntüsünü önizlerken doğrudan XML ayarlarını düzenlemenizi sağlar.

Mesajları günlüğe kaydet

Uygulamanızı Android Studio ile oluşturup çalıştırdığınızda , pencerenin altındaki Android’i tıklatarak adb ve cihaz günlüğü iletilerini (logcat) DDMS bölmesinde görüntüleyebilirsiniz .

Eğer uygulamanızı hata ayıklamak istiyorsanız Android Debug Monitor , sen tıklayarak başlatabilirsiniz Monitor  araç çubuğunda. Hata Ayıklama Monitörü, uygulamanızı profillendirmek, cihaz davranışlarını kontrol etmek ve daha pek çok şey için tüm DDMS araç setini bulabileceğiniz yerdir . Ayrıca mizanpajlarınızı optimize etmenize yardımcı olacak Hiyerarşi Görüntüleyici araçlarını da içerir .

Kurulum, Kurulum ve Güncelleme Yönetimi


Android Studio kurulum ve kurulum sihirbazları

Güncelleştirilmiş bir kurulum ve kurulum sihirbazları, adım adım kurulum ve kurulum işlemlerinde size yardımcı olur; sihirbaz, Java Development Kit (JDK) ve kullanılabilir RAM gibi sistem gereksinimlerini denetler ve ardından isteğe bağlı yükleme seçenekleri ister; Intel® HAXM emülatörü hızlandırıcısı.

Güncelleştirilmiş bir kurulum sihirbazı, kurulum işleminde size yardımcı olur; çünkü sihirbaz sistem imajınızı ve öykünme gereksinimlerinizi (GPU) günceller ve ardından hızlı ve güvenilir emülasyon için Android 5’e (Lollipop) dayalı optimize edilmiş bir varsayılan Android Sanal Cihazı (AVD) oluşturur.

Genişletilmiş şablon ve form faktörü desteği

Android Studio, Google Hizmetleri için yeni şablonları desteklemektedir ve mevcut cihaz türlerini genişletmektedir.

Android Wear ve TV desteği

Kolay platformlar arası geliştirme için, Proje Sihirbazı, Android Wear ve TV için uygulamalarınızı oluşturmak için yeni şablonlar sunar.

Şekil 9. Yeni Form Faktörleri

Uygulama oluşturma sırasında, Proje Sihirbazı projeniz için en iyi minSdkVersion’u seçmenize yardımcı olacak bir API Seviyesi iletişim kutusu görüntüler .

Google App Engine entegrasyonu (Google Cloud Platform / Mesajlaşma)

Hızlı bulut entegrasyonu. Google bulutuna bağlanmak ve bir bulut bitiş noktası oluşturmak için Google App Engine’i kullanmak,

[su_box title=”Kod” box_color=”#e15e26″ radius=”7″]

File > New Module > App Engine Java Servlet Module

[/su_box]

Dosya> Yeni Modül> App Engine Java Servlet Modülü’nü seçmek ve modül, paket ve müşteri adlarını belirlemek kadar kolaydır .

Şekil 10. Kurulum Sihirbazı

Kanalları güncelle

Android Studio, Android Studio’yu kod seviyesi tercihinize göre güncel tutmak için dört güncelleme kanalı sunar:

  • Kanarya kanalı : Kanarya yapıları, haftalık olarak güncellenen, kanama kenarı salmalarını sağlar. Bu yapılar test edilmekle birlikte, insanların mümkün olan en kısa sürede yeni olanları görmelerini istediğimiz için hala hatalara maruz kalıyorlar. Bu üretim için önerilmez.
  • Dev Kanalı : Dev yapımı, zaman testinden kurtulan eski kanarya yapısı elle toplanır. Yaklaşık iki haftada bir veya aylık olarak güncellenirler.
  • Beta kanalı : Beta sürümleri, üretim sürümünden önce beta kalitesinde sürümler için kullanılır.
  • Kararlı kanal : Kararlı, üretime hazır sürümler için kullanılır.

Varsayılan olarak, Android Studio Kararlı kanalı kullanır . Kullanım  File > Settings > Updates

Dosya> Ayarlar> Güncellemeler kanal ayarını değiştirmek için.

Diğer Önemli Noktalar


Çeviri editörü

Çoklu dil desteği, Çeviri Düzenleyicisi eklentisi ile geliştirilmiştir; böylece uygulamanın çeviri dosyasına kolayca yerel ayar ekleyebilirsiniz. Renk kodları, bir yerel ayarın eksiksiz olup olmadığını veya hala dize çevirileri olmadığını gösterir. Ayrıca, eklentinizi çeviri için Google Play Developer Console (Google Play Geliştirici Konsolu)’na dışa aktarmak için kullanabilirsiniz, ardından çevirilerinizi projenize geri yükleyip içeri aktarın.

Çeviri Düzenleyicisine erişmek için bir strings.xmldosya açın ve Düzenleyiciyi Aç bağlantısını tıklayın.

Şekil 11. Çeviri Editörü

En yeni Android API’leri için editör desteği

Android Studio, yeni Materyal Tasarımı temalarını, widget’larını ve gölge katmanları ve API sürüm oluşturma gibi grafikleri destekler (düzeni farklı UI sürümlerinde gösterir).

Ayrıca, <ripple> ve <animated-selector> gibi yeni çizilebilir XML etiketleri ve özellikleri desteklenir.

GitHub’da Android kod örneklerine kolay erişim

Tıklanması İthalat Örnekleri gelen Dosya menüsünden veya Hoş Geldiniz sayfasında GitHub’dan Google kod örneklerine kesintisiz erişim sağlar.

Şekil 12. Kod Örnek Erişimi

Şekil 13. Alınan Kod Örneği

 

https://code.tutsplus.com/tutorials/integrating-google-play-services-on-android–cms-19828

 

 

IQ nedir? Zeka nedir?

Bilimde, Zeka terimi genellikle akademik veya bilişsel zeka olarak adlandırdığımız şeye refere eder. Zeka konusundaki kitaplarında profesörler Resing ve Drenth (2007) * ‘Zeka nedir?’ Aşağıdaki tanımı kullanarak: “Bilgi edinmek için gerekli olan bilişsel veya entelektüel yeteneklerin tümü ve bu bilgiyi iyi tanımlanmış bir amacı ve yapısına sahip sorunları çözmek için iyi kullanmak.”

Sıradan bir dilde, zekanın ne kadar akıllı ya da zeki olduğunuzu ifade ettiği söylenebilir.

 IQ puanı, bu kabiliyeti sizin gibi aynı yaştaki kişilerin çoğunluğu ile karşılaştırmanın standart bir yoludur. 100 puan, genel yaş grubunuzdaki bu insanlarla karşılaştırıldığında, temelde ortalama bir zekanız olduğu anlamına gelir. Psikologların çoğu 95 ila 105 arasında puan alanların normal bir istihbarat olduğunu veya ortalama bir IQ’su olduğunu söyler. Gerçek IQ puanı, artı veya eksi beş puan değişebilir çünkü tam bir IQ puanı almak çok zordur. Unutmayın, puanınızı olumsuz yönde etkileyebilecek birçok dış faktör vardır. Örneğin, sınava girerken kendinizi iyi hissetmiyorsanız. Ya da belki o gün bir şeyden rahatsız olursunuz. Bu şeyler puanınızı etkileyebilir. Bunlara ek olarak, IQ, bir insanın yaşamdaki tüm yeteneklerinin sonu değil. IQ puanı, el becerisi (açıkçası), müzikal yetenek ve yaşamda bir çok farklı başarıya yol açabilecek bir takım yetenekler gibi şeyleri ölçmede başarısız olur. Bununla birlikte, bir IQ sınavındaki puanınız, yaşamınızın birçok aşamasında kritik olabilecek problemleri düşünme, sebep etme ve çözme yeteneğinin oldukça doğru bir göstergesidir.

Psikoloji alanında kullanılan ilk zeka testleri

Binet ve Simon tarafından tasarlanan ölçekler, 20. yüzyılın başında yaygın olarak kabul edilen ilk akıllı testlerdi. I. Dünya Savaşı’nda askeri personeli değerlendirmek için kullanılan Alfa ve Beta ordusu testleri çok popüler oldu.

Son yıllarda, Wechsler ölçekleri, zeka ölçmek için psikoloji alanında en yaygın kullanılan araçlardır. Bu testlerin tasarımcısı Wechsler, ilk ölçeğini 1930’larda yayınladı. Testini yapmak için Binet Alpha ve Beta testlerinden materyaller kullandı. Testinin önemli bir özelliği, IQ hesaplanırken bu testin dikkate alınmasıydı. Diğer bir deyişle, IQ hesaplamasında yaş düzeltmesi yapılır. Bu özellik nedeniyle, IQ ömrü boyunca sabit kalır.

Zeka Bölümü (IQ)

IQ, Intelligence Quotient’in kısaltmasıdır. Peki IQ nedir? IQ, zekanızın bir ölçüsüdür ve bir sayıyla ifade edilir.

Bir kişinin IQ’si, kişinin bir zeka testi yaptırmasıyla hesaplanabilir. Ortalama IQ 100’dür. 100’den yüksek bir puan alırsanız, ortalama bir kişiden daha zekisin ve daha düşük bir puan (biraz) daha az akıllı olduğunuz anlamına gelir.

Bir IQ, yaş grubunuzla karşılaştırıldığında, belirli bir zeka testinde puanınızın ne olduğunu size söyler. Test ortalama 100 puan ve 15 puan standart sapmaya sahiptir. Bu standart sapma ne anlama geliyor? Bu, nüfusun yüzde 68’inin 85-115 aralığında bir IQ aldığı anlamına gelir. Nüfusun yüzde 95’i 70-130 aralığında puan alıyor.

Bazı örnekler

IQ’nuz 100 olduğunda bunun anlamı nedir? Bu, nüfusun yarısının sizden daha yüksek puan aldığı anlamına gelir. Diğer yarı puanlar senden daha düşük. 130 IQ’nuzun anlamı nedir? Bu, yaş grubunuzun yüzde 97,5’inin sizden düşük olduğu anlamına gelir. Sadece yüzde 2,5 puan daha yüksek.

IQ puanı anlamında daha fazla puan açıklayan hoş bir grafiğe bakınız .

IQ testinin tarihçesi

Paul Broca (1824-1880) ve Sir Francis Galton (1822-1911) istihbarat ölçmeyi düşünen ilk bilim insanları arasındaydı. İnsan kafatasının boyutunu ölçerek zekayı belirleyebileceklerini düşünüyorlardı. Kafatasının büyüdükçe, kişinin daha zeki olduğunu varsaydılar.

Aynı zamanda, bilim adamı Wilhelm Wundt (1932-1920) istihbarat ölçüsü olarak iç gözlem – insanın kendi düşüncelerini yansıtma yeteneği – kullandı. Bugünlerde metotları ve fikirlerinin modası geçmiş olduğu düşünülmekte ve artık IQ testleri için kullanılmamaktadır, ancak IQ testi tarihinin temel bir bölümünü oluşturmaktadır .

İlk ‘gerçek’ IQ testi

IQ tarihindeki ilk modern zeka testi, 1904’te Alfred Binet (1857-1911) ve Theodore Simon (1873-1961) tarafından geliştirilmiştir. Fransız Eğitim Bakanlığı bu araştırmacılardan zihinsel engelli çocukların normal zeki fakat tembel çocuklardan ayırt edilmesini sağlayacak bir test geliştirmelerini istedi. Sonuç, Simon-Binet IQ testi oldu. Bu IQ testi, mantıksal akıl yürütme, kafiyeli sözcükleri bulma ve nesneleri adlandırma gibi çeşitli bileşenlerden oluşur.

IQ testinin skoru, çocuğun yaşı ile birlikte, çocuğun entelektüel gelişimi hakkında bilgi sağlar: Çocuk diğer çocuklardan önce mi, yoksa onu mı geciktiriyor? IQ (zihinsel yaş / kronolojik yaş) X 100 olarak hesaplandı. Test, hem Avrupa hem de Amerika’da büyük bir başarıya ulaştı.