Notasyonların Android projelerinde kullanımı

Herkese esenlikler dilerim

Bu yazıda android uygulama geliştirirken var olan bir sorun ve bu sorunun çözümünden ziyade notasyonları projemizde aktif bir şekilde kullanmaya yöneltmeyi amaçlıyorum. Hadi bitirelim şu işi!


Sorunumuz nedir?

Button btn = (Button) findViewById(R.id.button1);

Android uygulaması geliştirirken yukarıdaki gibi sürekli bir casting ve atama içinde oluyoruz. Layout’umuzda bulunan onlarca eleman göz önünde bulundurulursa bu durum hem yorucu hem de göz zevkimizi bozuyor.


Nasıl bir çözüm üretebiliriz?

Notasyonlar(Annotations)

Java 5 ile kullanıma sunulmuş bir özelliktir. Notasyonlar doğrudan programın akışına etki etmezler. Sınıf, metod, değişken vb. yapıların açıklamalarıdır.

@Override
void biseylerYap() {
    // onu bunu boşver sen şimdi diyeceklerimi yap
}

yukarıdaki kod parçacığında @Override notasyonu var olan bir metodun değiştirilip yeni bir iş yaptığını belirtmek içindir. Örnekte gördüğümüz notasyon sadece belirteç olarak kullanılsa da notasyonlar değer de alabilirler.

Harikaa! Madem bu notasyonlar değer alabiliyor ozaman aşağıdaki gibi bir tanımlama ile view elemanının nesneye atanmasını sağlayabilirim.

@FindViewById(R.id.button1)
Button btn;

Notasyonumuzu oluşturalım

Layoutlarımızda bulunan elemanlarımızın id değerlerini belirteceğimiz bir notasyon oluşturalım

package paket_adiniz;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME) (1)
@Target(ElementType.FIELD) (2)
public @interface FindViewById {
    int value() default 0;
}
1 @Retention notasyonu, notasyonumuza ne zaman erişileceğini belirtir. Biz çalışma zamanında erişeceğimiz için RetentionPolicy.RUNTIME seçiyoruz.
2 @Target notasyonu, notasyonumuzun hangi elemanlarda kullanılabileceğini belirtir. Biz sınıf değişkenimizde kullanacağımız için ElementType.FIELD seçiyoruz.

RetentionPolicy

Nerede kullanılır

RetentionPolicy.CLASS

Bytecode seviyesinde işlemlerde kullanılır.

RetentionPolicy.SOURCE

Derleyiciyi yönlendirmek için kullanılır. Derlemeden sonra erişilemez.

RetentionPolicy.RUNTIME

Çalışma zamanında erişilebilir.

ElementType

Nerede kullanılır

ElementType.TYPE

Sınıf, arayüzlerde

ElementType.METHOD

Metodlarda

ElementType.FIELD

Sınıf değişkenlerde

ElementType.PARAMETER

Metod parametrelerinde

ElementType.CONSTRUCTOR

Kurucu metodlarda

ElementType.ANNOTATION_TYPE

Notasyonlarda (annotationception)

ElementType.PACKAGE

Paket tanımlamalarında


Elemanlarımızı nesnelere atayalım

Eveeet, aşağıdaki tanımlamayı yapabilir durumdayız şuan. Şimdi sıra geldi bu notasyonu kullanarak btn nesnesine R.id.button1 id değerli elemanımızı atamaya.

@FindViewById(R.id.button1)
Button btn;

Yeni bir sınıf oluşturalım ve sınıfımızın adına ViewBinder diyelim.

package paket_adiniz;

import android.app.Activity;
import java.lang.reflect.Field;

public class ViewBinder {

    public static void bind(Activity activity) {

        for (Field field : activity.getClass().getDeclaredFields()) { (1)
            FindViewById annotation = field.getAnnotation(FindViewById.class); (2)
            if (annotation != null) {
                field.setAccessible(true); (3)
                field.set(activity,activity.findViewById(annotation.value())); (4)
            }
        }
    }

}
1 Parametre olarak verilen activity nesnesinin değişkenleri üzerinde gez.
2 O an bulunulan değişkenin FindViewById notasyonunu getir. Eğer değişken bu notasyona sahip değilse null dönecektir.
3 Değişkene atama yapılabilmesi için erişilebilir yapıyoruz. Bu sayede private değişkenlere de erişilebilir.
4 Değişkenin’in hangi nesneye ait olduğunu ve hangi değeri alacağını belirterek o değişkene atama yapılır. yani şunu yapmış olursunuz mainActivity.btn = mainActivity.findViewById(annotation.value())

Sonuç

Notasyonlar ile daha birçok güzel araç yapılabilir. Bu sizin hayallerinize ve ihtiyaçlarınıza göre şekil alacaktır. Tüm blog boyunca oluşturmaya çalıştırdığımız kod aşağıdadır. Esen kalın.

FindViewById.java

package paket_adiniz;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FindViewById {
    int value() default 0;
}

ViewBinder.java

package paket_adiniz;

import android.app.Activity;
import java.lang.reflect.Field;


public class ViewBinder {

    public static void bind(Activity activity) {

        for (Field field : activity.getClass().getDeclaredFields()) {
            FindViewById annotation = field.getAnnotation(FindViewById.class);

            if (annotation != null) {
                field.setAccessible(true);
                field.set(activity, activity.findViewById(annotation.value()));
            }
        }
    }

}

MainActivity.java

package paket_adiniz;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import android.widget.TextView;

import paket_adiniz.R;
import paket_adiniz.viewbinder.FindViewById;
import paket_adiniz.viewbinder.ViewBinder;

public class MainActivity extends AppCompatActivity {

    @FindViewById(R.id.button1)
    Button btn1;
    @FindViewById(R.id.textView1)
    TextView tv1;

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

}
No Comments

Post a Comment

Comment
Name
Email
Website