Uygulamanızda statik resimler göstermeniz gerektiğinde, şekil ve resim çizmek için Drawable
sınıfını ve alt sınıflarını kullanabilirsiniz. Drawable
, çizilebilecek bir şeye ilişkin genel bir soyutlamadır. Çeşitli alt sınıflar, belirli görüntü senaryolarına yardımcı olur. Bunları, benzersiz şekillerde davranan kendi çekilebilir nesnelerinizi tanımlamak için genişletebilirsiniz.
Sınıf kurucularını kullanmanın yanı sıra Drawable
öğesini tanımlamanın ve örneklendirmenin iki yolu vardır:
- Projenizde kayıtlı bir resim kaynağını (bit eşlem dosyası) şişirir.
- Çekilebilir özellikleri tanımlayan bir XML kaynağını şişirin.
Not: Bunun yerine, bir dizi nokta, çizgi ve eğriden oluşan bir resmi ve ilişkili renk bilgilerini tanımlayan bir vektör çekilebilir özelliğini kullanmayı tercih edebilirsiniz. Bu şekilde vektör çekilebilirlerinin, kaliteden ödün vermeden farklı boyutlar için ölçeklendirilmesine olanak sağlanır. Daha fazla bilgi için Vektör çizimlerine genel bakış konusuna göz atın.
Kaynak resimlerinden çekilebilir çizimler oluşturma
Proje kaynaklarınızdaki bir görüntü dosyasına referans vererek uygulamanıza grafik ekleyebilirsiniz. Desteklenen dosya türleri PNG (tercih edilir), JPG (kabul edilebilir) ve GIF'tir (önerilmez). Uygulama simgeleri, logolar ve oyunlarda kullanılanlar gibi diğer grafikler bu tekniğe uygundur.
Bir resim kaynağı kullanmak için dosyanızı, projenizin res/drawable/
dizinine ekleyin. Projenize girdikten sonra, kodunuzdaki veya
XML düzeninizdeki resim kaynağına başvurabilirsiniz. Her iki durumda da, dosya türü uzantısı olmayan dosya adı olan bir kaynak kimliği kullanılır. Örneğin, my_image.png
için my_image
olarak başvuruda bulunun.
Not: res/drawable/
dizinine yerleştirilen resim kaynakları, derleme işlemi sırasında aapt
aracı tarafından kayıpsız resim sıkıştırma yöntemiyle otomatik olarak optimize edilebilir. Örneğin, 256'dan fazla renk gerektirmeyen gerçek renkli bir PNG, renk paletine sahip 8 bit bir PNG'ye dönüştürülebilir. Bu, eşit kalitede ancak daha az bellek gerektiren
bir resimle sonuçlanır. Sonuç olarak, bu dizine yerleştirilen görüntü ikili programları derleme sırasında değişebilir. Bir görüntüyü bit eşlem olarak okumak için bit eşlem olarak okumayı planlıyorsanız resimlerinizi res/raw/
klasörüne yerleştirin. aapt
aracı, bunları değiştirmez.
Aşağıdaki kod snippet'i, çekilebilir bir kaynaktan oluşturulan resmi kullanan ve bunu düzene ekleyen bir ImageView
öğesinin nasıl oluşturulacağını gösterir:
Kotlin
private lateinit var constraintLayout: ConstraintLayout override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Instantiate an ImageView and define its properties val i = ImageView(this).apply { setImageResource(R.drawable.my_image) contentDescription = resources.getString(R.string.my_image_desc) // set the ImageView bounds to match the Drawable's dimensions adjustViewBounds = true layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) } // Create a ConstraintLayout in which to add the ImageView constraintLayout = ConstraintLayout(this).apply { // Add the ImageView to the layout. addView(i) } // Set the layout as the content view. setContentView(constraintLayout) }
Java
ConstraintLayout constraintLayout; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a ConstraintLayout in which to add the ImageView constraintLayout = new ConstraintLayout(this); // Instantiate an ImageView and define its properties ImageView i = new ImageView(this); i.setImageResource(R.drawable.my_image); i.setContentDescription(getResources().getString(R.string.my_image_desc)); // set the ImageView bounds to match the Drawable's dimensions i.setAdjustViewBounds(true); i.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); // Add the ImageView to the layout and set the layout as the content view. constraintLayout.addView(i); setContentView(constraintLayout); }
Diğer durumlarda, resim kaynağınızı aşağıdaki örnekte gösterildiği gibi bir Drawable
nesnesi olarak kullanmak isteyebilirsiniz:
Kotlin
val myImage: Drawable = ResourcesCompat.getDrawable(context.resources, R.drawable.my_image, null)
Java
Resources res = context.getResources(); Drawable myImage = ResourcesCompat.getDrawable(res, R.drawable.my_image, null);
Uyarı: Projenizdeki her benzersiz kaynak, kaç farklı nesne sunduğunuzdan bağımsız olarak yalnızca bir durumu koruyabilir. Örneğin, aynı resim kaynağından iki Drawable
nesnesini örneklendirir ve bir nesnenin özelliğini (alfa gibi) değiştirirseniz bu değişiklik diğerini de etkiler. Bir görüntü kaynağının birden çok örneğiyle çalışırken, Drawable
nesnesini doğrudan dönüştürmek yerine bir ara animasyonu gerçekleştirmeniz gerekir.
Aşağıdaki XML snippet'i, XML düzeninde bir ImageView
öğesine çekilebilir kaynağın nasıl ekleneceğini gösterir:
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/my_image" android:contentDescription="@string/my_image_desc" />
Proje kaynaklarını kullanma hakkında daha fazla bilgi için Kaynaklar ve öğeler bölümüne bakın.
Not: Çekilebilir malzemelerinizin kaynağı olarak resim kaynaklarını kullanırken resimlerin çeşitli piksel yoğunlukları için uygun boyutta olduğundan emin olun. Resimler doğru değilse sığacak şekilde büyütülür. Bu da, çizimlerinizde oluşumlara neden olabilir. Daha fazla bilgi için Farklı piksel yoğunluklarını destekleme bölümünü okuyun.
XML kaynaklarından çekilebilir çizimler oluşturma
Başlangıçta kodunuz veya kullanıcı etkileşiminiz tarafından tanımlanan değişkenlere bağlı olmayan, oluşturmak istediğiniz bir Drawable
nesnesi varsa Drawable
öğesini XML'de tanımlamak iyi bir seçenektir. Drawable
öğenizin, kullanıcının uygulamanızla etkileşimi sırasında özelliklerini değiştirmesini bekleseniz bile, nesne örneklendikten sonra özelliklerini değiştirebileceğiniz için nesneyi XML'de tanımlamayı düşünmelisiniz.
Drawable
öğenizi XML'de tanımladıktan sonra, dosyayı projenizin res/drawable/
dizinine kaydedin. Aşağıdaki örnek, Drawable
kaynağından devralan bir TransitionDrawable
kaynağını tanımlayan XML'i göstermektedir:
<!-- res/drawable/expand_collapse.xml --> <transition xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/image_expand"/> <item android:drawable="@drawable/image_collapse"/> </transition>
Ardından Resources#getDrawable()
yöntemini çağırıp XML dosyanızın kaynak kimliğini ileterek nesneyi alın ve örneklendirin. inflate()
yöntemini destekleyen tüm Drawable
alt sınıfları XML'de tanımlanabilir ve uygulamanız tarafından örneklenebilir.
XML şişirmeyi destekleyen her çekilebilir sınıf, nesne özelliklerinin tanımlanmasına yardımcı olan belirli XML özelliklerini kullanır. Aşağıdaki kod TransitionDrawable
öğesini somutlaştırır ve bir ImageView
nesnesinin içeriği olarak ayarlar:
Kotlin
val transition= ResourcesCompat.getDrawable( context.resources, R.drawable.expand_collapse, null ) as TransitionDrawable val image: ImageView = findViewById(R.id.toggle_image) image.setImageDrawable(transition) // Description of the initial state that the drawable represents. image.contentDescription = resources.getString(R.string.collapsed) // Then you can call the TransitionDrawable object's methods. transition.startTransition(1000) // After the transition is complete, change the image's content description // to reflect the new state.
Java
Resources res = context.getResources(); TransitionDrawable transition = (TransitionDrawable) ResourcesCompat.getDrawable(res, R.drawable.expand_collapse, null); ImageView image = (ImageView) findViewById(R.id.toggle_image); image.setImageDrawable(transition); // Description of the initial state that the drawable represents. image.setContentDescription(getResources().getString(R.string.collapsed)); // Then you can call the TransitionDrawable object's methods. transition.startTransition(1000); // After the transition is complete, change the image's content description // to reflect the new state.
Desteklenen XML özellikleri hakkında daha fazla bilgi için yukarıda listelenen sınıflara bakın.
Şekil çekilebilir öğeleri
Dinamik olarak iki boyutlu bir grafik çizmek istediğinizde ShapeDrawable
nesnesi iyi bir seçenek olabilir. Programatik olarak bir ShapeDrawable
nesnesine temel şekiller çizebilir ve uygulamanızın ihtiyaç duyduğu stilleri uygulayabilirsiniz.
ShapeDrawable
, Drawable
sınıfının bir alt sınıfıdır. Bu nedenle, Drawable
olması beklenen her yerde ShapeDrawable
kullanabilirsiniz. Örneğin, bir görünümün setBackgroundDrawable()
yöntemine ileterek görünümün arka planını ayarlamak için bir ShapeDrawable
nesnesi kullanabilirsiniz. Ayrıca şeklinizi kendi özel görünümü olarak
çizleyebilir ve uygulamanızdaki bir düzene ekleyebilirsiniz.
ShapeDrawable
kendi draw()
yöntemine sahip olduğundan, aşağıdaki kod örneğinde gösterildiği gibi onDraw()
etkinliği sırasında ShapeDrawable
nesnesini çizen bir View
alt sınıfı oluşturabilirsiniz:
Kotlin
class CustomDrawableView(context: Context) : View(context) { private val drawable: ShapeDrawable = run { val x = 10 val y = 10 val width = 300 val height = 50 contentDescription = context.resources.getString(R.string.my_view_desc) ShapeDrawable(OvalShape()).apply { // If the color isn't set, the shape uses black as the default. paint.color = 0xff74AC23.toInt() // If the bounds aren't set, the shape can't be drawn. setBounds(x, y, x + width, y + height) } } override fun onDraw(canvas: Canvas) { drawable.draw(canvas) } }
Java
public class CustomDrawableView extends View { private ShapeDrawable drawable; public CustomDrawableView(Context context) { super(context); int x = 10; int y = 10; int width = 300; int height = 50; setContentDescription(context.getResources().getString( R.string.my_view_desc)); drawable = new ShapeDrawable(new OvalShape()); // If the color isn't set, the shape uses black as the default. drawable.getPaint().setColor(0xff74AC23); // If the bounds aren't set, the shape can't be drawn. drawable.setBounds(x, y, x + width, y + height); } protected void onDraw(Canvas canvas) { drawable.draw(canvas); } }
Yukarıdaki kod örneğinde CustomDrawableView
sınıfını diğer özel görünümlerde olduğu gibi kullanabilirsiniz. Örneğin, bunu aşağıdaki örnekte gösterildiği gibi programatik olarak uygulamanızdaki bir etkinliğe ekleyebilirsiniz:
Kotlin
private lateinit var customDrawableView: CustomDrawableView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) customDrawableView = CustomDrawableView(this) setContentView(customDrawableView) }
Java
CustomDrawableView customDrawableView; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); customDrawableView = new CustomDrawableView(this); setContentView(customDrawableView); }
Bunun yerine özel görünümü XML düzeninde kullanmak isterseniz CustomDrawableView
sınıfı, sınıf XML'den şişirildiğinde çağrılan View(Context, AttributeSet)
oluşturucuyu geçersiz kılmalıdır. Aşağıdaki örnekte, XML düzeninde CustomDrawableView
öğesinin nasıl bildirileceği gösterilmektedir:
<com.example.shapedrawable.CustomDrawableView android:layout_width="fill_parent" android:layout_height="wrap_content" />
ShapeDrawable
sınıfı, android.graphics.drawable
paketindeki diğer birçok çekilebilir tür gibi, herkese açık yöntemler kullanarak nesnenin çeşitli özelliklerini tanımlamanıza olanak tanır. Ayarlamak isteyebileceğiniz bazı örnek özellikler arasında alfa şeffaflığı, renk filtresi, parlaklık, opaklık ve renk yer alır.
XML kaynaklarını kullanarak temel çekilebilir şekilleri de tanımlayabilirsiniz. Daha fazla bilgi için Çekilebilir kaynak türleri bölümündeki Şekil çizimi bölümüne bakın.
NinePatch çekmeceleri
NinePatchDrawable
grafiği, bir görünümün arka planı olarak kullanabileceğiniz uzatılabilir bir bit eşlem resmidir. Android, görünümün içeriğine uygun olması için grafiği otomatik olarak yeniden boyutlandırır. NinePatch resminin kullanımına örnek olarak, standart Android düğmeleri tarafından kullanılan arka plan verilebilir. Düğmeler, çeşitli uzunluklardaki dizeleri kapsayacak şekilde genişletilmelidir.
NinePatch grafiği, ekstra 1 piksel kenarlık içeren standart bir PNG resmidir.
Söz konusu değer, projenizin res/drawable/
dizinine 9.png
uzantısıyla kaydedilmelidir.
Resmin uzatılabilir ve statik alanlarını tanımlamak için kenarlığı kullanın. Kenarlığın sol ve üst kısmına bir (veya daha fazla) 1 piksel genişliğinde siyah çizgi çizerek uzatılabilir bir bölüm belirtirsiniz (diğer kenarlık pikselleri tamamen şeffaf veya beyaz olmalıdır). İstediğiniz sayıda uzatılabilir bölümünüz olabilir. Uzatılabilir bölümlerin göreli boyutu aynı kalır, böylece en büyük bölüm her zaman en büyük olmaya devam eder.
Ayrıca sağ tarafa bir çizgi ve alta bir çizgi çizerek resmin isteğe bağlı çekilebilir bir bölümünü (doldurma çizgileri etkili bir şekilde) tanımlayabilirsiniz. Bir View
nesnesi, NinePatch grafiğini arka plan olarak ayarlar ve daha sonra görünümün metnini belirtirse, tüm metin yalnızca sağ ve alt satırlarla (varsa) belirtilen alanı kaplayacak şekilde kendini uzatır.
Dolgu çizgileri dahil edilmezse Android bu çekilebilir alanı tanımlamak için sol ve üst çizgileri kullanır.
Çizgiler arasındaki farkı netleştirmek amacıyla, sol ve üst çizgiler, resmi genişletmek için resmin hangi piksellerinin çoğaltılmasına izin verileceğini tanımlar. Alt ve sağ çizgiler, resim içinde, görünüm içeriğinin doldurmasına izin verilen göreli alanı tanımlar.
Şekil 1'de, bir düğmeyi tanımlamak için kullanılan bir NinePatch grafiği örneği gösterilmektedir:

Şekil 1: Bir düğmeyi tanımlayan NinePatch grafiği örneği
Bu NinePatch grafiği, sol ve üst çizgileri olan uzatılabilir bir alanı ve alt ve sağ çizgileri olan çekilebilir alanı tanımlar. Üstteki resimde bulunan kesik gri çizgiler, resmi esnetmek için görüntünün çoğaltılan bölgelerini belirtir. Alt resimdeki pembe dikdörtgen, görünümün içeriklerine izin verilen bölgeyi belirtir. İçerikler bu bölgeye sığmazsa resim genişletilerek bunların sığması sağlanır.
Draw 9-patch aracı, WYSIWYG grafik düzenleyici kullanarak NinePatch resimlerinizi oluşturmanız için son derece pratik bir yol sunar. Hatta, uzatılabilir alan için tanımladığınız bölge, piksel çoğaltma nedeniyle çizim kusurları oluşturma riskiyle karşı karşıya kalırsa uyarı verir.
Aşağıdaki örnek düzen XML'inde, birkaç düğmeye NinePatch grafiğinin nasıl ekleneceği gösterilmektedir. NinePatch resmi res/drawable/my_button_background.9.png
klasörüne kaydedilir.
<Button android:id="@+id/tiny" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerInParent="true" android:text="Tiny" android:textSize="8sp" android:background="@drawable/my_button_background"/> <Button android:id="@+id/big" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerInParent="true" android:text="Biiiiiiig text!" android:textSize="30sp" android:background="@drawable/my_button_background"/>
Düğmenin metnin etrafına düzgün bir şekilde sığması için layout_width
ve layout_height
özelliklerinin wrap_content
olarak ayarlandığını unutmayın.
Şekil 2'de, yukarıda gösterilen XML ve NinePatch resminden oluşturulan iki düğme gösterilmektedir. Düğmenin genişliğinin ve yüksekliğinin metne göre nasıl değiştiğine ve arka plan resminin buna göre genişlediğine dikkat edin.

Şekil 2: XML kaynağı ve NinePatch grafiği kullanılarak oluşturulan düğmeler
Özel çekilebilir cihazlar
Drawable
sınıfını (veya alt sınıflarından herhangi birini) genişleterek özel çizimler oluşturabilirsiniz.
Uygulanacak en önemli yöntem draw(Canvas)
yöntemidir. Çünkü bu yöntem, çizim talimatlarınızı sağlamak için kullanmanız gereken Canvas
nesnesini sağlar.
Aşağıdaki kodda, daire çizen basit bir Drawable
alt sınıfı gösterilmektedir:
Kotlin
class MyDrawable : Drawable() { private val redPaint: Paint = Paint().apply { setARGB(255, 255, 0, 0) } override fun draw(canvas: Canvas) { // Get the drawable's bounds val width: Int = bounds.width() val height: Int = bounds.height() val radius: Float = Math.min(width, height).toFloat() / 2f // Draw a red circle in the center canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), radius, redPaint) } override fun setAlpha(alpha: Int) { // This method is required } override fun setColorFilter(colorFilter: ColorFilter?) { // This method is required } override fun getOpacity(): Int = // Must be PixelFormat.UNKNOWN, TRANSLUCENT, TRANSPARENT, or OPAQUE PixelFormat.OPAQUE }
Java
public class MyDrawable extends Drawable { private final Paint redPaint; public MyDrawable() { // Set up color and text size redPaint = new Paint(); redPaint.setARGB(255, 255, 0, 0); } @Override public void draw(Canvas canvas) { // Get the drawable's bounds int width = getBounds().width(); int height = getBounds().height(); float radius = Math.min(width, height) / 2; // Draw a red circle in the center canvas.drawCircle(width/2, height/2, radius, redPaint); } @Override public void setAlpha(int alpha) { // This method is required } @Override public void setColorFilter(ColorFilter colorFilter) { // This method is required } @Override public int getOpacity() { // Must be PixelFormat.UNKNOWN, TRANSLUCENT, TRANSPARENT, or OPAQUE return PixelFormat.OPAQUE; } }
Ardından, çekilebilir dosyanızı burada gösterildiği gibi bir ImageView
ekleme gibi istediğiniz yere ekleyebilirsiniz:
Kotlin
val myDrawing = MyDrawable() val image: ImageView = findViewById(R.id.imageView) image.setImageDrawable(myDrawing) image.contentDescription = resources.getString(R.string.my_image_desc)
Java
MyDrawable mydrawing = new MyDrawable(); ImageView image = findViewById(R.id.imageView); image.setImageDrawable(mydrawing); image.setContentDescription(getResources().getString(R.string.my_image_desc));
Android 7.0 (API düzeyi 24) ve sonraki sürümlerde, XML ile özel çiziminizin örneklerini aşağıdaki yöntemlerle de tanımlayabilirsiniz:
- XML öğesi adı olarak tam nitelikli sınıf adını kullanma. Bu yaklaşımda özel çekilebilir sınıf sınıfının herkese açık üst düzey sınıf olması gerekir:
<com.myapp.MyDrawable xmlns:android="http://schemas.android.com/apk/res/android" android:color="#ffff0000" />
- XML etiketi adı olarak
drawable
kullanma ve class özelliğinden tam nitelikli sınıf adını belirtme. Bu yaklaşım, hem herkese açık üst düzey sınıflar hem de herkese açık statik iç sınıflar için kullanılabilir:<drawable xmlns:android="http://schemas.android.com/apk/res/android" class="com.myapp.MyTopLevelClass$MyDrawable" android:color="#ffff0000" />
Çekilebilir alanlara renk tonu ekleme
Android 5.0 (API düzeyi 21) ve sonraki sürümlerde, alfa maskeleri olarak tanımlanan bit eşlemleri ve dokuz yamayı renklendirebilirsiniz. Renk kaynaklarını çözen renk kaynakları veya tema özellikleriyle renklendirme yapabilirsiniz (örneğin, ?android:attr/colorPrimary
). Genellikle bu öğeleri yalnızca bir kez oluşturur ve temanızla eşleşecek şekilde otomatik olarak renklendirirsiniz.
setTint()
yöntemiyle BitmapDrawable
, NinePatchDrawable
veya VectorDrawable
nesnelerine tonlama uygulayabilirsiniz. android:tint
ve android:tintMode
özelliklerini kullanarak düzenlerinizde ton rengini ve modunu da ayarlayabilirsiniz.
Görselden belirgin renkleri çıkarabilirsiniz
Android Destek Kitaplığı, bir görselden belirgin renkleri ayıklamanıza olanak tanıyan Palette
sınıfını içerir.
Çekilebilir öğelerinizi Bitmap
olarak yükleyip renklerine erişmek için Palette
ile aktarabilirsiniz.
Daha fazla bilgi için Palet API'si ile renk seçme bölümünü okuyun.