Bu codelab, Kotlin'deki Gelişmiş Android kursuna dahildir. Codelab'ler sırasında sırayla çalıştığınızda bu kurstan en yüksek değeri elde edersiniz ancak zorunlu değildir. Tüm kurs codelab'leri Kotlin Codelab'de Gelişmiş Android açılış sayfasında listelenmiştir.
Giriş
Bu codelab'in amacı doğrultusunda, klips bir resmin, tuvalin veya bit eşlemin bölgelerinin seçici bir şekilde çizilmiş veya ekrana çizilmemiş olan bölgelerini tanımlamanın bir yoludur. Kırpmanın amaçlarından biri, aşırı çizimi azaltmaktır. Geri çekme, ekrandaki bir pikselin son resmi görüntülemek için birden fazla kez çizilmesidir. Fazla çizimi azalttığınızda, çizim performansını en üst düzeye çıkarmak için ekranın bir pikseli veya bölgesinin çizilme sayısını en aza indirirsiniz. Ayrıca, kullanıcı arayüzü tasarımında ve animasyonunda ilginç efektler oluşturmak için kırpma özelliğini kullanabilirsiniz.
Örneğin, aşağıda gösterildiği gibi, çakışan kartlar yığınını çizdiğinizde, her kartı en alttan aşağıya doğru tamamen çizmek yerine, genellikle yalnızca görünür bölümleri çizmek daha verimli olur. "Kırpma işlemlerinin de maliyeti olduğundan ve genel olarak Android sistemi çizim optimizasyonu açısından oldukça başarılı olduğundan "Genellikle" denir.
Kartların yalnızca görünür kısımlarını çizmek için her karta bir kırpma bölgesi belirtirsiniz. Örneğin, aşağıdaki şemada bir resme kırpma dikdörtgeni uygulandığında yalnızca bu dikdörtgenin içindeki bölüm gösterilir.
Kırpma bölgesi genellikle dikdörtgendir ancak herhangi bir şekil veya şekil bileşimi (metin bile olabilir) olabilir. Kırpma bölgesinin dahil olduğu bölgenin dahil edilip edilmeyeceğini de belirtebilirsiniz. Örneğin, dairesel bir kırpma bölgesi oluşturup yalnızca dairenin dışında kalan öğeleri görüntüleyebilirsiniz.
Bu codelab'de, çeşitli kırpma yöntemleriyle denemeler yapacaksınız.
Bilmeniz gerekenler
Aşağıdaki konular hakkında bilgi sahibi olmalısınız:
Activity
ile uygulama oluşturma ve Android Studio'yu kullanarak uygulama çalıştırma.Canvas
oluşturma ve çizim yapma.- Özel
View
oluşturma veonDraw()
ileonSizeChanged()
değerlerini geçersiz kılma.
Neler öğreneceksiniz?
Canvas
üzerinde çizilen nesneler nasıl kırpılır?- Bir tuvalin çizim durumlarını kaydetme ve geri yükleme.
- Tuvale ve metne dönüşüm uygulama.
Yapacaklarınız
- Ekran üzerinde kesik şekiller çizmenin farklı yollarını ve bu şekillerin görünürlüğüyle ilgili sonuçları gösteren bir uygulama oluşturun.
- Çevrilmiş ve çevrilmiş metinler de çizeceksiniz.
ClippingExample uygulaması, bir tuvalin hangi kısımlarının görünümde gösterileceğini belirlemek için şekilleri nasıl kullanabileceğinizi ve birleştirebileceğinizi gösterir. Son uygulamanız aşağıdaki ekran görüntüsünde bulunacaktır.
Bu uygulamayı sıfırdan derleyeceğiniz için bir proje oluşturmanız, boyutlar ile dizeleri tanımlamanız ve bazı değişkenleri bildirmeniz gerekir.
1. Adım: ClippingExample projesi oluşturun
- Boş Etkinlik şablonuyla
ClippingExample
adında bir Kotlin projesi oluşturun. Paket adı ön eki içincom.example.android
kullanın. MainActivity.kt
'yi açın.onCreate()
yönteminde varsayılan içerik görünümünü değiştirin ve içerik görünümünü yeni birClippedView
örneği olarak ayarlayın. Bu, daha sonra oluşturacağınız klip oluşturma örnekleri için özel görünümünüz olacaktır.
setContentView(ClippedView(this))
MainActivity.kt
ile aynı düzeyde, yeni bir Kotlin dosyası ve sınıfı oluşturarakClippedView
adında,View
uzantısındaki bir görünüm oluşturun. Fotoğrafa aşağıda gösterilen imzayı verin. Çalışmanızın kalanı buClippedView
içinde yer alacak.@JvmOverloads
ek açıklaması, Kotlin derleyicisine bu işlev için varsayılan parametre değerlerinin yerini alacak aşırı yüklemeler oluşturma talimatı verir.
class ClippedView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
}
2. Adım: Boyut ve dize kaynaklarını ekleyin
res/values/dimens.xml
ürününde yeni kaynaklar dosyasında, kırpılmış görünümler için kullanacağınız boyutları tanımlayın. Bu varsayılan boyutlar, oldukça küçük bir ekrana sığacak şekilde kodlanır ve boyutlandırılır.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="clipRectRight">90dp</dimen>
<dimen name="clipRectBottom">90dp</dimen>
<dimen name="clipRectTop">0dp</dimen>
<dimen name="clipRectLeft">0dp</dimen>
<dimen name="rectInset">8dp</dimen>
<dimen name="smallRectOffset">40dp</dimen>
<dimen name="circleRadius">30dp</dimen>
<dimen name="textOffset">20dp</dimen>
<dimen name="strokeWidth">4dp</dimen>
<dimen name="textSize">18sp</dimen>
</resources>
Uygulamanın daha büyük bir ekranda iyi görünmesi (ve ayrıntıları daha kolay görebilmek için) yalnızca daha büyük ekranlar için geçerli olan daha büyük değerlere sahip bir dimens
dosyası oluşturabilirsiniz.
- Android Studio'da, values klasörünü sağ tıklayın ve Yeni > Değerler kaynak dosyası'nı seçin.
- New Resource File iletişim kutusunda,
dimens
dosyasını çağırın. Kullanılabilir niteleyiciler'de En Küçük Ekran Genişliği'ni seçin ve >> düğmesini tıklayarak Cosen niteleyicilerine ekleyin. En küçük ekran genişliği kutusuna 480 sayısını girip Tamam'ı tıklayın.
- Dosya, aşağıda gösterildiği gibi değerler klasörünüzde gösterilmelidir.
- Dosyayı göremiyorsanız uygulamanın Proje Dosyaları görünümüne geçin. Yeni dosyanın tam yolu aşağıda gösterilmiştir:
ClippingExample/app/src/main/res/values-sw480dp/dimens.xml
.
values-sw480dp/dimens.xml
dosyasının varsayılan içeriğini aşağıdaki boyutlarla değiştirin.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="clipRectRight">120dp</dimen>
<dimen name="clipRectBottom">120dp</dimen>
<dimen name="rectInset">10dp</dimen>
<dimen name="smallRectOffset">50dp</dimen>
<dimen name="circleRadius">40dp</dimen>
<dimen name="textOffset">25dp</dimen>
<dimen name="strokeWidth">6dp</dimen>
</resources>
strings.xml
satırına aşağıdaki dizeleri ekleyin. Bunlar, zemindeki metni görüntülemek için kullanılır.
<string name="clipping">Clipping</string>
<string name="translated">translated text</string>
<string name="skewed">"Skewed and "</string>
3. Adım: Boyama ve Yol nesnesi oluşturun ve başlatın
- Projenizin Android görünümüne geri dönün.
ClippedView
dilinde, çizilecek birPaint
değişkeni tanımlayın. Takma ad kaldırma özelliğini etkinleştirin ve aşağıda gösterildiği gibi boyutlarda tanımlanan fırça genişliği ve metin boyutunu kullanın.
private val paint = Paint().apply {
// Smooth out edges of what is drawn without affecting shape.
isAntiAlias = true
strokeWidth = resources.getDimension(R.dimen.strokeWidth)
textSize = resources.getDimension(R.dimen.textSize)
}
ClippedView
ürününde, çizilenin yolunu yerel olarak depolamak için birPath
oluşturun ve ilk kullanıma hazırlayın.android.graphics.Path
aktarın.
private val path = Path()
4. Adım: Şekilleri ayarlayın
Bu uygulamada, çeşitli şekillerde kırpılmış birkaç satır ve şekilli iki sütun görüntülüyorsunuz.
Bunların hepsi ortaktır:
- Kapsayıcı görevi gören büyük bir dikdörtgen (kare)
- Büyük dikdörtgenin üzerinde çapraz bir çizgi
- Daire
- Kısa bir metin dizesi
Bu adımda, kaynaklardan bu şekiller için boyutlar ayarlarsınız. Böylece boyutları daha sonra yalnızca bir kez kullanabilirsiniz.
ClippedView
öğesindepath
altına, tüm şekil grubunun etrafındaki kırpma dikdörtgeninin boyutları için değişkenler ekleyin.
private val clipRectRight = resources.getDimension(R.dimen.clipRectRight)
private val clipRectBottom = resources.getDimension(R.dimen.clipRectBottom)
private val clipRectTop = resources.getDimension(R.dimen.clipRectTop)
private val clipRectLeft = resources.getDimension(R.dimen.clipRectLeft)
- Bir dikdörtgenin başlangıcı ve küçük bir dikdörtgenin ofseti için değişkenler ekleyin.
private val rectInset = resources.getDimension(R.dimen.rectInset)
private val smallRectOffset = resources.getDimension(R.dimen.smallRectOffset)
- Bir dairenin yarıçapı için değişken ekleyin. Bu, dairenin içinde çizilen dairenin yarıçapıdır.
private val circleRadius = resources.getDimension(R.dimen.circleRadius)
- Dikdörtgenin içine çizilen metin için bir ofset ve metin boyutu ekleyin.
private val textOffset = resources.getDimension(R.dimen.textOffset)
private val textSize = resources.getDimension(R.dimen.textSize)
4. Adım: Satır ve sütun konumlarını ayarlayın
Bu uygulamanın şekilleri, yukarıda ayarlanan boyutların değerleriyle belirlenen iki sütun ve dört satırda görüntülenir. Matematik bölümü bu codelab'in bir parçası değildir, ancak bu adımda verilen koda kopyalarken ona bakın.
- İki sütun için koordinatları ayarlayın.
private val columnOne = rectInset
private val columnTwo = columnOne + rectInset + clipRectRight
- Dönüştürülen metnin son satırı da dahil olmak üzere her satır için koordinatları ekleyin.
private val rowOne = rectInset
private val rowTwo = rowOne + rectInset + clipRectBottom
private val rowThree = rowTwo + rectInset + clipRectBottom
private val rowFour = rowThree + rectInset + clipRectBottom
private val textRow = rowFour + (1.5f * clipRectBottom)
- Uygulamanızı çalıştırın. Uygulama, uygulama adının altında boş bir beyaz ekranla açılır.
onDraw()
uygulamasında, aşağıdaki uygulama ekran görüntüsünde gösterildiği gibi yedi farklı kırpılmış dikdörtgen çizmek için yöntemleri çağırıyorsunuz. Dikdörtgenlerin tümü aynı şekilde çizilir. Tek fark, tanımlanmış kırpma bölgeleri ve ekrandaki konumudur.
Dikdörtgenleri çizmek için kullanılan algoritma, aşağıdaki şema ve açıklamada gösterildiği gibi çalışır. Özetle, Canvas
başlangıç noktasını taşıyarak bir dizi dikdörtgen çizersiniz. Kavramsal olarak bu, aşağıdaki adımlardan oluşur:
(1) Önce Canvas
, dikdörtgenin çizilmesini istediğiniz yere çevirirsiniz. Yani, bir sonraki dikdörtgenin ve diğer tüm şekillerin nerede çizilmesi gerektiğini hesaplamak yerine, Canvas
kaynağını, yani koordinat sistemini taşırsınız.
(2) Ardından, tuvalin yeni kaynağındaki dikdörtgeni çiziyorsunuz. Yani şekilleri, çevrilmiş koordinat sisteminde aynı konumda çizersiniz. Bu yöntem çok daha basit ve biraz daha verimlidir.
(3) Son olarak, Canvas
'i orijinal Origin
durumuna geri yüklersiniz.
Algoritmayı uygulayacağınız şekilde aşağıda bulabilirsiniz:
onDraw()
içinde,Canvas
öğesini gri arka plan rengiyle doldurmak ve orijinal şekilleri çizmek için bir işlev çağırın.- Her kırpılmış dikdörtgen ve çizilecek metin için bir işlev çağırın.
Her dikdörtgen veya metin için:
- Baştaki durumuna sıfırlamak için
Canvas
öğesinin mevcut durumunu kaydedin. - Tuvalin
Origin
öğesini çizmek istediğiniz konuma çevirin. - Kırpma şekilleri ve yolları uygulayın.
- Dikdörtgen veya metin çizin.
Canvas
durumunu geri yükleyin.
Adım: onDraw() geçersiz kılma
onDraw()
öğesini, aşağıdaki kodda gösterildiği gibi geçersiz kılın. Çizdiğiniz her şekil için bir işlev çağırırsınız. Bunu daha sonra uygularsınız.
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
drawBackAndUnclippedRectangle(canvas)
drawDifferenceClippingExample(canvas)
drawCircularClippingExample(canvas)
drawIntersectionClippingExample(canvas)
drawCombinedClippingExample(canvas)
drawRoundedRectangleClippingExample(canvas)
drawOutsideClippingExample(canvas)
drawSkewedTextExample(canvas)
drawTranslatedTextExample(canvas)
// drawQuickRejectExample(canvas)
}
- Kodun derlenmeye devam etmesi için çizim işlevlerinin her biri için bir saplama oluşturun. Aşağıdaki kodu kopyalayabilirsiniz.
private fun drawBackAndUnclippedRectangle(canvas: Canvas){
}
private fun drawDifferenceClippingExample(canvas: Canvas){
}
private fun drawCircularClippingExample(canvas: Canvas){
}
private fun drawIntersectionClippingExample(canvas: Canvas){
}
private fun drawCombinedClippingExample(canvas: Canvas){
}
private fun drawRoundedRectangleClippingExample(canvas: Canvas){
}
private fun drawOutsideClippingExample(canvas: Canvas){
}
private fun drawTranslatedTextExample(canvas: Canvas){
}
private fun drawSkewedTextExample(canvas: Canvas){
}
private fun drawQuickRejectExample(canvas: Canvas){
}
Uygulama, aynı dikdörtgeni çizer ve önce kırpma olmadan, altı kez çeşitli kırpma yolları uygulayarak altı kez şekillendirir. drawClippedRectangle()
yöntemi, aşağıda gösterildiği gibi bir dikdörtgen çizim kodunu dikkate alır.
1. Adım: DrawClippedRectangle() yöntemini oluşturun
Canvas
türündecanvas
bağımsız değişkenini alan birdrawClippedRectangle()
yöntemi oluşturun.
private fun drawClippedRectangle(canvas: Canvas) {
}
drawClippedRectangle()
yönteminin içinde, tüm şekil için kırpma dikdörtgeninin sınırlarını ayarlayın. Yalnızca kare çizmeyi sınırlandıran bir kırpma dikdörtgeni uygulayın.
canvas.clipRect(
clipRectLeft,clipRectTop,
clipRectRight,clipRectBottom
)
Canvas.clipRect(...)
yöntemi, gelecekte çizim çizimlerinin üzerine yazılabileceği ekran alanını azaltır. Kırpma sınırlarını, geçerli kırpma dikdörtgeninin ve clipRect()
dikdörtgenine iletilen dikdörtgenin uzamsal kesişimi olarak ayarlar. clipRect()
yönteminin, bölgeler için farklı formlar kabul eden ve kırpma dikdörtgeninde farklı işlemlere izin veren birçok varyantı vardır.
canvas
öğesini beyaz renkle doldurun. Evet. Dikdörtgenler çizmediğiniz için tüm tuval kesiliyor! Kırpma dikdörtgeni nedeniyle, yalnızca kırpma dikdörtgeni tarafından tanımlanan bölge doldurularak beyaz bir dikdörtgen oluşturuyor. Yüzenin geri kalanı gri renkte kalır.
canvas.drawColor(Color.WHITE)
- Rengi kırmızı olarak değiştirin ve kırpma dikdörtgeninin içinde bir çapraz çizgi çizin.
paint.color = Color.RED
canvas.drawLine(
clipRectLeft,clipRectTop,
clipRectRight,clipRectBottom,paint
)
- Rengi yeşile ayarlayın ve kırpma dikdörtgeninin içine bir daire çizin.
paint.color = Color.GREEN
canvas.drawCircle(
circleRadius,clipRectBottom - circleRadius,
circleRadius,paint
)
- Rengi maviye ayarlayın ve metni kırpma dikdörtgeninin sağ kenarıyla hizalayın. Metin çizmek için
canvas.drawText()
simgesini kullanın.
paint.color = Color.BLUE
// Align the RIGHT side of the text with the origin.
paint.textSize = textSize
paint.textAlign = Paint.Align.RIGHT
canvas.drawText(
context.getString(R.string.clipping),
clipRectRight,textOffset,paint
)
2. Adım: DrawBackAndUnclippedRectangle() yöntemini uygulayın
drawClippedRectangle()
yönteminin nasıl çalıştığını görmek için, aşağıda gösterildiği gibidrawBackAndUnclippedRectangle()
yöntemini uygulayarak ilk klipsiz dikdörtgeni çizin.canvas
öğesini kaydedin, ilk satıra ve sütun konumuna çevirin,drawClippedRectangle()
çağrısı yaparak çizin, ardındancanvas
öğesini önceki durumuna geri yükleyin.
private fun drawBackAndUnclippedRectangle(canvas: Canvas){
canvas.drawColor(Color.GRAY)
canvas.save()
canvas.translate(columnOne,rowOne)
drawClippedRectangle(canvas)
canvas.restore()
}
- Uygulamanızı çalıştırın. Dairenin, kırmızı çizginin ve gri bir arka plan üzerinde metnin yer aldığı ilk beyaz dikdörtgeni görürsünüz.
Aşağıdaki kırpma örneği yöntemlerinde, grafik efektleri elde etmek ve kırpma bölgelerinde ihtiyacınız olan şekli şekillendirmek için çeşitli kırpma bölgeleri kombinasyonlarını uygulayabilirsiniz.
Bu yöntemlerin her biri aynı kalıbı izler.
- Tuvalin geçerli durumunu kaydedin:
canvas.
save(
)
Etkinlik bağlamı bir çizim durumu yığını tutar. Çizim durumları, mevcut dönüşüm matrisini ve mevcut kırpma bölgesinden oluşur. Mevcut durumu kaydedebilir, çizim durumunu değiştiren işlemleri (tuvali çevirme veya döndürme gibi) gerçekleştirip kaydedilen çizim durumunu geri yükleyebilirsiniz. (Not: Bu, Git! içindeki "sash"" komutu gibidir.
Çiziminiz dönüşümleri içerdiğinde, dönüşümleri tersine çevirme ve zincirleme olarak geri alma hataya açıktır. Örneğin, çevirir, esneter ve sonra döndürürseniz hızlı bir şekilde karmaşıklaşabilir. Bunun yerine, tuvalin durumunu kaydedin, dönüşümlerinizi uygulayın, çizin ve ardından önceki durumu geri yükleyin.
Örneğin, bir kırpma bölgesi tanımlayabilir ve bu durumu kaydedebilirsiniz. Ardından zemini çevirin, kırpma bölgesi ekleyin ve döndürün. Biraz çizim yaptıktan sonra, orijinal kırpma durumunu geri yükleyebilir ve şemada gösterildiği gibi farklı bir çeviri ile sapma dönüşümü yapabilirsiniz.
- Tuvalin kaynağını satır/sütun koordinatlarına çevirin:
canvas.
translate
()
Tuvalin kaynağını taşımak ve aynı şeyi yeni bir koordinat sisteminde çizmek, tüm öğeleri çizmekten çok daha kolaydır. (İpucu: Öğeleri döndürmek için aynı tekniği kullanabilirsiniz.)
- Varsa dönüşümleri
path
öğesine uygulayın. - Kırpma uygula:
canvas.clipPath(path)
- Şekil çizin:
drawClippedRectangle() or drawText()
- Önceki tuval durumunu geri yükle:
canvas.restore()
1. Adım: DrawDifferenceCliplingExample(tuval) uygulayın
İkinci dikdörtgeni çizmek için kod ekleyin. Bu dikdörtgen, resim çerçevesi efekti oluşturmak için iki kırpma dikdörtgeni arasındaki farkı kullanır.
Aşağıdakileri yapan kodu kullanın:
- Kanvası kaydedin.
- Tuvalin kaynağını ilk satıra, ikinci sütuna, ilk dikdörtgenin sağındaki açık alana çevirin.
- İki kırpma dikdörtgeni uygulayın.
DIFFERENCE
operatörü, ikinci dikdörtgeni ilkinden çıkarır.
- Değiştirilen tuvali çizmek için
drawClippedRectangle()
yöntemini çağırın. - Tuval durumunu geri yükleyin.
private fun drawDifferenceClippingExample(canvas: Canvas) {
canvas.save()
// Move the origin to the right for the next rectangle.
canvas.translate(columnTwo,rowOne)
// Use the subtraction of two clipping rectangles to create a frame.
canvas.clipRect(
2 * rectInset,2 * rectInset,
clipRectRight - 2 * rectInset,
clipRectBottom - 2 * rectInset
)
// The method clipRect(float, float, float, float, Region.Op
// .DIFFERENCE) was deprecated in API level 26. The recommended
// alternative method is clipOutRect(float, float, float, float),
// which is currently available in API level 26 and higher.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O){
canvas.clipRect(
4 * rectInset,4 * rectInset,
clipRectRight - 4 * rectInset,
clipRectBottom - 4 * rectInset,
Region.Op.DIFFERENCE
)
} else {
canvas.clipOutRect(
4 * rectInset,4 * rectInset,
clipRectRight - 4 * rectInset,
clipRectBottom - 4 * rectInset
)
}
drawClippedRectangle(canvas)
canvas.restore()
}
- Uygulamanızı çalıştırın. Uygulama aşağıdaki gibi görünmelidir.
2. Adım: DrawCircularClippingExample(uygulama)
Ardından, kodun sonuna dairesel bir yoldan oluşturulmuş dairesel kırpma bölgesini kullanan bir daire çizin. Bunu yapmak için daireyi kaldırın (çizim yapmayın) ve yerine gri arka plan gösterin.
private fun drawCircularClippingExample(canvas: Canvas) {
canvas.save()
canvas.translate(columnOne, rowTwo)
// Clears any lines and curves from the path but unlike reset(),
// keeps the internal data structure for faster reuse.
path.rewind()
path.addCircle(
circleRadius,clipRectBottom - circleRadius,
circleRadius,Path.Direction.CCW
)
// The method clipPath(path, Region.Op.DIFFERENCE) was deprecated in
// API level 26. The recommended alternative method is
// clipOutPath(Path), which is currently available in
// API level 26 and higher.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
canvas.clipPath(path, Region.Op.DIFFERENCE)
} else {
canvas.clipOutPath(path)
}
drawClippedRectangle(canvas)
canvas.restore()
}
3. Adım: DrawIntersectionClippingSample'ı(canvas) uygulayın
Ardından, ikinci satır ve sütunda iki kırpma dikdörtgeninin kesişimini çizmek için kod ekleyin.
Ekran çözünürlüğünüze bağlı olarak bu bölgenin görünümünün farklılık göstereceğini unutmayın. Görünür bölgenin boyutunu değiştirmek için smallRectOffset
boyutuyla denemeler yapın. Daha küçük bir smallRectOffset
, ekranda daha geniş bir alan oluşturur.
private fun drawIntersectionClippingExample(canvas: Canvas) {
canvas.save()
canvas.translate(columnTwo,rowTwo)
canvas.clipRect(
clipRectLeft,clipRectTop,
clipRectRight - smallRectOffset,
clipRectBottom - smallRectOffset
)
// The method clipRect(float, float, float, float, Region.Op
// .INTERSECT) was deprecated in API level 26. The recommended
// alternative method is clipRect(float, float, float, float), which
// is currently available in API level 26 and higher.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
canvas.clipRect(
clipRectLeft + smallRectOffset,
clipRectTop + smallRectOffset,
clipRectRight,clipRectBottom,
Region.Op.INTERSECT
)
} else {
canvas.clipRect(
clipRectLeft + smallRectOffset,
clipRectTop + smallRectOffset,
clipRectRight,clipRectBottom
)
}
drawClippedRectangle(canvas)
canvas.restore()
}
4. Adım: DrawBirleşik Klip Örneği(canvas) uygulayın
Ardından, şekilleri, daireyi ve dikdörtgeni birleştirin ve bir kırpma bölgesi tanımlamak için herhangi bir yol çizin.
private fun drawCombinedClippingExample(canvas: Canvas) {
canvas.save()
canvas.translate(columnOne, rowThree)
path.rewind()
path.addCircle(
clipRectLeft + rectInset + circleRadius,
clipRectTop + circleRadius + rectInset,
circleRadius,Path.Direction.CCW
)
path.addRect(
clipRectRight / 2 - circleRadius,
clipRectTop + circleRadius + rectInset,
clipRectRight / 2 + circleRadius,
clipRectBottom - rectInset,Path.Direction.CCW
)
canvas.clipPath(path)
drawClippedRectangle(canvas)
canvas.restore()
}
5. Adım: Çizimleri YuvarlatılmışDikdörtgenKlip Örneği(Tuval) uygulayın
Ardından, yaygın olarak kullanılan bir kırpma şekli olan yuvarlak bir dikdörtgen ekleyin.
- Üst düzeyde bir dikdörtgen değişkeni oluşturun ve başlatın.
RectF
, kayan noktanın dikdörtgen koordinatlarını tutan bir sınıftır.
private var rectF = RectF(
rectInset,
rectInset,
clipRectRight - rectInset,
clipRectBottom - rectInset
)
drawRoundedRectangleClippingExample()
işlevini uygulayın.addRoundRect()
işlevi bir dikdörtgen, köşe yarıçapının x ve y değerleri için değerler ve yuvarlak dikdörtgenin çemberini döndürme yönü.Path.Direction
kapalı yollara (ör. dikdörtgenler, ovaller) yönlere nasıl odaklanıldığını belirtir.CCW
, saat yönünün kısaltmasıdır.
private fun drawRoundedRectangleClippingExample(canvas: Canvas) {
canvas.save()
canvas.translate(columnTwo,rowThree)
path.rewind()
path.addRoundRect(
rectF,clipRectRight / 4,
clipRectRight / 4, Path.Direction.CCW
)
canvas.clipPath(path)
drawClippedRectangle(canvas)
canvas.restore()
}
6. Adım: çizimOutsideClippingExample(uygulama)
Kırpma dikdörtgeninin girintilerini iki katına çıkararak dikdörtgenin dışını kırpın.
private fun drawOutsideClippingExample(canvas: Canvas) {
canvas.save()
canvas.translate(columnOne,rowFour)
canvas.clipRect(2 * rectInset,2 * rectInset,
clipRectRight - 2 * rectInset,
clipRectBottom - 2 * rectInset)
drawClippedRectangle(canvas)
canvas.restore()
}
7. Adım: DrawtranslatedTextExample özelliğini uygulayın(canvas)
Metin çizmek, diğer şekillerden tamamen farklı değildir ve metne dönüşüm uygulayabilirsiniz. Örneğin, tuvali çevirip metni çizerek metni çevirebilirsiniz.
- Aşağıdaki işlevi uygulayın.
private fun drawTranslatedTextExample(canvas: Canvas) {
canvas.save()
paint.color = Color.GREEN
// Align the RIGHT side of the text with the origin.
paint.textAlign = Paint.Align.LEFT
// Apply transformation to canvas.
canvas.translate(columnTwo,textRow)
// Draw text.
canvas.drawText(context.getString(R.string.translated),
clipRectLeft,clipRectTop,paint)
canvas.restore()
}
- Çevrilmiş metni görmek için uygulamanızı çalıştırın.
8. Adım: DrawSkewedTextExample(canvas) yöntemini uygulayın
Ayrıca metni çarpıtabilirsiniz. Yani bunu çeşitli şekillerde bozabilirsiniz.
ClippedView
işlevinde aşağıdaki işlevi oluşturun.
private fun drawSkewedTextExample(canvas: Canvas) {
canvas.save()
paint.color = Color.YELLOW
paint.textAlign = Paint.Align.RIGHT
// Position text.
canvas.translate(columnTwo, textRow)
// Apply skew transformation.
canvas.skew(0.2f, 0.3f)
canvas.drawText(context.getString(R.string.skewed),
clipRectLeft, clipRectTop, paint)
canvas.restore()
}
- Çevrilen metnin önüne çizilen çarpık metni görmek için uygulamanızı çalıştırın.
quickReject()
Canvas
yöntemi, belirli bir dikdörtgenin veya yolun, tüm dönüşümler uygulandıktan sonra görünür olan bölgelerin dışında tamamen yer alıp almayacağını kontrol etmenizi sağlar.
quickReject()
yöntemi, daha karmaşık çizimler oluştururken ve bunu mümkün olduğunca hızlı bir şekilde yapmanız gerektiğinde çok kullanışlıdır. quickReject()
sayesinde, hangi nesneleri çizmenize gerek olmadığını verimli bir şekilde belirleyebilirsiniz ve kendi kesişim mantığınızı yazmanıza gerek kalmaz.
- Ekranda dikdörtgen veya yol hiç görünmezse
quickReject()
yöntemitrue
değerini döndürür. Kısmi çakışmalar için kendi kontrolünüzü yapmanız gerekir. EdgeType
, en yakın piksele yuvarlama içinAA
(Karşıtlık: Kenarları yuvarlayarak kenarlardan başlayarak yuvarlayın) veyaBW
(Siyah Beyaz: Yalnızca en yakın piksel sınırına yuvarlayarak kenarlara davranın).
quickReject()
ürününün birkaç sürümü vardır ve bunları dokümanlarda da bulabilirsiniz.
| quickReddet |
| quickReddet |
| quickReddet |
Bu alıştırmada, daha önce olduğu gibi yeni bir satıra, metnin altına ve clipRect
içine bir çizim çizeceksiniz.
- İlk olarak,
clipRect
ile çakışan bir dikdörtgeninClipRectangle
ilequickReject()
öğesini çağırırsınız. Bu nedenle,quickReject()
yanlış değerini döndürür,clipRect
BLACK
ile doldurulur veinClipRectangle
dikdörtgen çizilir.
- Kodu değiştirin ve
notInClipRectangle
ilequickReject()
numaralı telefonu arayın.quickReject()
artık "true" (doğru) değerini döndürüyor.clipRect
WHITE
ile dolu venotInClipRectangle
çizilmiyor.
Karmaşık çizimleriniz olduğunda, hangi şeklin kırpma bölgesinin tamamen dışında olduğunu ve hangilerinde kırpma bölgesinin tamamen içinde olduğunun yanı sıra ek hesaplamalar yapmanız ve çizimler yapmanız gerekebilir.
Adım: quickDismiss() ile deneme yapın
- Üst düzeyde, ek bir satırın y koordinatları için değişken oluşturun.
private val rejectRow = rowFour + rectInset + 2*clipRectBottom
ClippedView
öğesine aşağıdakidrawQuickRejectExample()
işlevini ekleyin.quickReject()
kodunu kullanmak için bilmeniz gereken her şeyi içerdiğinden kodu okuyun.
private fun drawQuickRejectExample(canvas: Canvas) {
val inClipRectangle = RectF(clipRectRight / 2,
clipRectBottom / 2,
clipRectRight * 2,
clipRectBottom * 2)
val notInClipRectangle = RectF(RectF(clipRectRight+1,
clipRectBottom+1,
clipRectRight * 2,
clipRectBottom * 2))
canvas.save()
canvas.translate(columnOne, rejectRow)
canvas.clipRect(
clipRectLeft,clipRectTop,
clipRectRight,clipRectBottom
)
if (canvas.quickReject(
inClipRectangle, Canvas.EdgeType.AA)) {
canvas.drawColor(Color.WHITE)
}
else {
canvas.drawColor(Color.BLACK)
canvas.drawRect(inClipRectangle, paint
)
}
canvas.restore()
}
onDraw()
içinde,drawQuickRejectExample()
çağrısının yorumunu kaldırın.- Uygulamanızı çalıştırdığınızda siyah bir dikdörtgen görürsünüz. Bu dikdörtgen, doldurulmuş kırpma bölgesi ve
inClipRectangle
ile temsil edilen iki dikdörtgenle çakıştığı içinquickReject()
false
veinClipRectangle
çizilir.
drawQuickRejectExample()
içinde kodu değiştirereknotInClipRectangle.
çalıştırmak içinquickReject()
kodunuquickReject()
true
döndürür ve kırpma bölgesi beyazla doldurulur.
Tamamlanan codelab'in kodunu indirin.
$ git clone https://github.com/googlecodelabs/android-kotlin-drawing-clipping
Alternatif olarak, veri havuzunu Zip dosyası olarak indirip sıkıştırılmış dosyayı Android Studio'da açabilirsiniz.
- Bir etkinliğin
Context
değeri,Canvas
için dönüşümleri ve kırpma bölgelerini koruyan bir durum sağlar. - Tuvalinizi çizmek ve orijinal durumuna dönmek için
canvas.save()
vecanvas.restore()
kullanın. - Bir tuvale birden fazla şekil çizmek için konumunu hesaplayabilir veya çizim yüzeyinizin kaynağını taşıyabilirsiniz (çevirebilirsiniz). İkincisi, yinelenen çizim dizileri için yardımcı program yöntemleri oluşturmayı kolaylaştırabilir.
- Kırpma bölgeleri, herhangi bir şekil veya şekil kombinasyonu olabilir.
- Kırpma bölgelerini tam olarak gerektiği şekilde almak için bu bölgeleri ekleyebilir, çıkarabilir ve kesişebilirsiniz.
- Tuvali dönüştürerek metne metin uygulayabilirsiniz.
quickReject()
Canvas
yöntemi, belirli bir dikdörtgenin veya yolun halihazırda görünür olan bölgelerin dışında tam olarak bulunup bulunmadığını kontrol etmenize olanak tanır.
Udacity kursu:
Android geliştirici dokümanları:
Canvas
sınıfıBitmap
sınıfıView
sınıfıPaint
sınıfıBitmap.config
yapılandırmalarıRegion.Op
operatörleriPath
sınıfıCanvas
sınıfıBitmap
sınıfıView
sınıfıPaint
sınıfıBitmap.config
yapılandırmalarıRegion.Op
operatörleriPath
sınıfıandroid.graphics
grafik araçlarıBitmap.Config
Canvas
yapılandırmaları- Tuval ve Çekmeceler
- Canvas.translate() ne yapar?
- Canvas bağlamı için Save() ve restore() komutunu anlama
- klips
- geçersiz kılın.
@JvmOverloads
Ayrıca, Android çerçevesinin ekrana nasıl geldiğine dair ayrıntılı bir açıklama için Grafik Mimari serisine de bakın.
Bu bölümde, bir eğitmen tarafından sunulan kurs kapsamında bu codelab üzerinden çalışan öğrenciler için olası ev ödevi ödevleri listelenmektedir. Öğretmenin şunları yapması gerekir:
- Gerekirse ev ödevini atayın.
- Öğrencilere ev ödevlerinin nasıl gönderileceğini bildirin.
- Ev ödevlerine not verin.
Öğretmenler bu önerileri istedikleri kadar kullanabilir veya uygun görebilir ve uygun olan diğer ev ödevlerini atayabilirler.
Bu codelab'de kendiniz çalışıyorsanız, bilginizi test etmek için bu ödevlerden yararlanabilirsiniz.
Bu soruları yanıtlayın
1. Soru
Şekillerin çizilmesinden etkili bir şekilde hariç tutmak için hangi yöntemi çağırıyorsunuz?
makbuz excludeFromDrawing()
makbuz quickReject()
makbuz onDraw()
makbuz clipRect()
2. Soru
Canvas.save()
ve Canvas.restore()
hangi bilgileri kaydedip geri yükler?
▢ Renk, çizgi genişliği vb.
▢ Yalnızca mevcut dönüşümler
▢ Mevcut dönüşümler ve kırpma bölgesi
▢ Yalnızca geçerli kırpma bölgesi
3. Soru
Paint.Align
şunları belirtir:
▢ Aşağıdaki çizim şekilleri nasıl hizalanır?
▢ Metnin kökenin hangi kenarından alındığı
▢ Kırpma bölgesinde nerede hizalanır?
▢ Metnin hangi tarafta başlangıç noktasına hizalanacağı
Bu kurstaki diğer codelab'lerin bağlantıları için Kotlin codelab'lerdeki Gelişmiş Android açılış sayfasına bakın.