Düğmemiz android sdk sından çıkan ilk haliyle şöyledir:
<Button
android:id="@+id/cust_button"
android:text="Özel Düğme"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Button etiketi içine text özellikleri vs. ekleyelim.
<Button
android:id="@+id/cust_button"
android:text="Özel Düğme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:color="#444"
android:radius="18dp"
android:textColor="#ff0000"
android:gravity="center"
android:textSize="30dp"
android:textStyle="bold"
android:shadowColor="#ff00ff"
android:shadowDx="1"
android:shadowDy="2"
android:shadowRadius="3" />
Bu güzel oldu ama
main.xml
layout dosyamız çok kabardı ve her yeni butona bu özellikler(xml attributes) eklemek istemeyiz. Hem köşeleri hafif oval, kenarlıklı ve basıldığında başka bir görüntüsü olan buton istiyoruz. Bu durumla başa çıkmak için android:background, android:textColor, style
xml özellikleri(attributes) kullanabiliriz. android:background
butonumuzun kavislerini, kenarlıklarını ve varsayılan, basılı ve odaklandığında(focus-bir elemente tab ile ya da fare ile(burada parmağımız) tıklandığında) alacağı halleri tutan xml dosyamızı oluşturmalıyız. Ama önce basıldığında, varsayılan, odaklanıldığında gibi halleri(state) anlayalım.android:background
Android de View'dan türetilmiş elemanların aşağıdaki durumları vardır:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:color="hex_color"
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_selected=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
android:state_window_focused=["true" | "false"] />
</selector>
Yukarıdaki durumlardan bizim düğmemiz(button) için geçerli olan
android:state_focused
ve android:state_pressed
durumlarını ele alacağız.Düğmemiz için yukarıdaki durumlarda nasıl görünmesini istiyorsak bunları
res/drawable
klasörüne xxxx.xml
dosyası adında oluşturacağız:Bu dosya düğmemizin arka plan görüntüleri için kullanılacak.Düğmemize basmadık; o zaman "pressed" durumuna girmeyiz, e focus'ta olmadığımıza göre default durumuna kadar geldik ve bu durumdaki şekili giydirmiş olacağız düğmemize. Akış bu şekilde olduğu için ilk denk geldiği durumu işleyecek bu yüzden en olmadığı en üste ve en varsayılan durumu ise en alta koyacağız.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed: the first item in the state list that matches the current state -->
<item android:state_pressed="true" ></item>
<!-- focused -->
<item android:state_focused="true" ></item>
<!-- default: value should always be last -->
<item></item>
</selector>
Varsayılan(default) durum yani düğmemizin kendi başına mel mel bakındığı durumu::
<!-- default -->
<item>
<shape>
<!-- Opak olarak beyaz (#fff) arka plan -->
<solid android:color="#fff"/>
<!-- Kenarlık diye 1px #ff007f renginde(stroke) -->
<stroke android:width="1px" android:color="#ff007f" />
<!-- Köşeler 18dp çapında yuvarlansın -->
<corners android:radius="18dp" />
</shape>
</item>
Artık diğer durumlarıda xml dosyamıza ekleyelim. FOCUS olduğunda ya da PRESSED olduğunda kenarlık rengini #444 rengine çekelim ve arka plan renginide geçişli(gradient) renk olarak boyayalım(startColor="#3787ff" endColor="#2f72d7" angle="270") ve dosyamızın son halini görelim:
cust_btn_bg.xml
<?xml version="1.0" encoding="utf-8"?>Yukarıdaki gibi her birini item etiketlerinin altına yazabildiğimiz gibi, bu durumları ayrı xml dosyalarına bölüp item etiketine ilgili durumun xml dosyasınıda verebiliriz. Tıpkı aşağıdaki gibi:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed -->
<item android:state_pressed="true" >
<shape>
<stroke android:width="1px" android:color="#444" />
<corners android:radius="18dp" />
<gradient android:startColor="#3787ff" android:endColor="#2f72d7" android:angle="270" />
<corners android:radius="18dp" />
<!-- Düğmenin arka rengini tek renk yapmak istersek: -->
<!-- solid android:color="#ffff00" kullanırız -->
</shape>
</item>
<!-- focused -->
<item android:state_focused="true" >
<shape>
<stroke android:width="1px" android:color="#444" />
<corners android:radius="18dp" />
<gradient android:startColor="#3787ff" android:endColor="#2f72d7" android:angle="270" />
<corners android:radius="18dp" />
</shape>
</item>
<!-- default -->
<item>
<shape>
<solid android:color="#fff"/>
<stroke android:width="1px" android:color="#444" />
<corners android:radius="18dp" />
</shape>
</item>
</selector>
<?xml version="1.0" encoding="utf-8"?>Pressed halini
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed -->
<item android:state_pressed="true" android:drawable="@drawable/cust_btn_pressed_state"/>
<!-- focused -->
<item android:state_focused="true" >
<shape>
<stroke android:width="1px" android:color="#444" />
<corners android:radius="18dp" />
<gradient android:startColor="#3787ff" android:endColor="#2f72d7" android:angle="270" />
<corners android:radius="18dp" />
</shape>
</item>
<!-- default -->
<item>
<shape>
<!-- Opak olarak beyaz (#fff) arka plan -->
<solid android:color="#fff"/>
<!-- Kenarlık diye 1px #ff007f renginde(stroke) -->
<stroke android:width="1px" android:color="#ff007f" />
<!-- Köşeler 18dp çapında yuvarlansın -->
<corners android:radius="18dp" />
</shape>
</item>
</selector>
drawable
klasöründe cust_btn_pressed_state.xml
dosyasına yazıyor ve item
etiketinede android:drawable="@drawable/cust_btn_pressed_state"
xml özelliği içinde belirtiyoruz.Peki cust_btn_pressed.xml dosyamız nasıl oldu:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Artık state_pressed olduğunu buraya yazmamıza gerek yok. Çünkü bir üst xmlden bu xml i çağırıyoruz ve orada state_pressed olarak belirtildi. -->
<item>
<shape>
<stroke android:width="1px" android:color="#444" />
<corners android:radius="18dp" />
<gradient android:startColor="#3787ff" android:endColor="#2f72d7" android:angle="270" />
<corners android:radius="18dp" />
</shape>
</item>
</selector>
android:text
Düğmemizin üstüneki yazıya renk, gölge, ebat, tarz(stil) eklemek için kullandığımız xml özelliklerini(attribute) her düğmeye bu özellikleri tekrar tekrar yazmamak için tarz(style) dosyası oluşturmamız gerek.
styles.xml
dosyasına uygulamamızın css dosyası gibi bakabiliriz. Burada bir css elementi oluşturur style
etiketi içine tarz bilgilerini yazalım.<?xml version="1.0" encoding="utf-8"?>Artık düğmemize(button) şu xml özelliğini(xml attribute) ekleyerek düğmemizin üstündeki metnin tarzını hızlıca atamış oluruz. Dahası bundan sonra aynı tarzda olacak elemanlarada kısaca bu bilgiyi atayabiliriz.
<resources>
<style name="cust_btn_stil">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#ffffff</item>
<item name="android:gravity">center</item>
<item name="android:layout_margin">3dp</item>
<item name="android:padding">10dp</item>
<item name="android:textSize">20dp</item>
<item name="android:textStyle">normal</item>
<item name="android:shadowColor">#e2e</item>
<item name="android:shadowDx">1</item>
<item name="android:shadowDy">1</item>
<item name="android:shadowRadius">2</item>
</style>
</resources>
<Button
android:id="@+id/btnNext"
android:text="@string/btnNext"
android:background="@drawable/cust_btn_bg"
style="@style/cust_btn_tarz" />
android:textColor
cust_btn_text.xml
adlı dosyayı res/drawable
klasöründe saklayalım.Text özelliklerini biraz değiştirerek yukarıdaki styles.xml dosyasında sakladık ama düğmeye basıldığında metin rengi değişik olsun istiyoruz. Bunu sağlamak için cust_btn_text.xml dosyasını aşağıdaki gibi düzenleyelim:<?xml version="1.0" encoding="utf-8"?>Artık düğmemizin metin rengide her durumda farklı bir renk alacak. Bu kaynak dosyasını(resource file hatta drawable file) düğmemizin belirtildiği(declare edildiği) xml etiketinde
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed -->
<item android:state_pressed="true" android:color="#ffff00" />
<!-- focused -->
<item android:state_focused="true" android:color="#fff" />
<!-- default -->
<item android:color="#385487" />
</selector>
android:textColor
xml özelliğinde belirtelim. Artık düğmemizin son hali:<Buttonolacak.
android:id="@+id/btnNext"
android:text="@string/btnNext"
android:background="@drawable/cust_btn_bg"
style="@style/cust_btn_tarz"
android:textColor="@drawable/cust_btn_text" />
Bu kadar yeterli sanırım bu işi anlamak için. Sonuçta çıkan düğmenin renkleri başta belirttiğimiz gibi olmadı çünkü bende öğrenirken oynaya oynaya yoldan çıkarttım düğmemizi :)
Referanslar: Drawable Resources(developer.android.com)
Bitmap File
A bitmap graphic file (.png, .jpg, or .gif). Creates a BitmapDrawable.
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/myimage" />
Nine-Patch File
A PNG file with stretchable regions to allow image resizing based on content (.9.png). Creates a NinePatchDrawable.
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="@drawable/myninepatch" />
Layer List
A Drawable that manages an array of other Drawables. These are drawn in array order, so the element with the largest index is be drawn on top. Creates a LayerDrawable.
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@[package:]drawable/drawable_resource"
android:id="@[+][package:]id/resource_name"
android:top="dimension"
android:right="dimension"
android:bottom="dimension"
android:left="dimension" />
</layer-list>
State List
An XML file that references different bitmap graphics for different states (for example, to use a different image when a button is pressed). Creates a StateListDrawable.
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize=["true" | "false"]
android:dither=["true" | "false"]
android:variablePadding=["true" | "false"] >
<item
android:drawable="@[package:]drawable/drawable_resource"
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_selected=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
android:state_window_focused=["true" | "false"] />
</selector>
Level List
An XML file that defines a drawable that manages a number of alternate Drawables, each assigned a maximum numerical value. Creates a LevelListDrawable.
<level-list
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@drawable/drawable_resource"
android:maxLevel="integer"
android:minLevel="integer" />
</level-list>
Transition Drawable
An XML file that defines a drawable that can cross-fade between two drawable resources. Creates a TransitionDrawable.
<transition
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@[package:]drawable/drawable_resource"
android:id="@[+][package:]id/resource_name"
android:top="dimension"
android:right="dimension"
android:bottom="dimension"
android:left="dimension" />
</transition>
Inset Drawable
An XML file that defines a drawable that insets another drawable by a specified distance. This is useful when a View needs a background drawble that is smaller than the View's actual bounds.
<inset
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/drawable_resource"
android:insetTop="dimension"
android:insetRight="dimension"
android:insetBottom="dimension"
android:insetLeft="dimension" />
Clip Drawable
An XML file that defines a drawable that clips another Drawable based on this Drawable's current level value. Creates a ClipDrawable.
<clip
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/drawable_resource"
android:clipOrientation=["horizontal" | "vertical"]
android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
"fill_vertical" | "center_horizontal" | "fill_horizontal" |
"center" | "fill" | "clip_vertical" | "clip_horizontal"] />
Scale Drawable
An XML file that defines a drawable that changes the size of another Drawable based on its current level value. Creates a ScaleDrawable
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/drawable_resource"
android:scaleGravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
"fill_vertical" | "center_horizontal" | "fill_horizontal" |
"center" | "fill" | "clip_vertical" | "clip_horizontal"]
android:scaleHeight="percentage"
android:scaleWidth="percentage" />
Shape Drawable
An XML file that defines a geometric shape, including colors and gradients. Creates a ShapeDrawable.
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape=["rectangle" | "oval" | "line" | "ring"] >
<corners
android:radius="integer"
android:topLeftRadius="integer"
android:topRightRadius="integer"
android:bottomLeftRadius="integer"
android:bottomRightRadius="integer" />
<gradient
android:angle="integer"
android:centerX="integer"
android:centerY="integer"
android:centerColor="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type=["linear" | "radial" | "sweep"]
android:usesLevel=["true" | "false"] />
<padding
android:left="integer"
android:top="integer"
android:right="integer"
android:bottom="integer" />
<size
android:width="integer"
android:height="integer" />
<solid
android:color="color" />
<stroke
android:width="integer"
android:color="color"
android:dashWidth="integer"
android:dashGap="integer" />
</shape>