
Saya suka Dribbble . Ada banyak proyek desain keren dan inspiratif. Tetapi jika Anda seorang pengembang, maka seringkali perasaan keindahan dengan cepat memberi jalan keputusasaan ketika Anda mulai berpikir tentang bagaimana menerapkan desain keren ini.
Pada artikel ini saya akan menunjukkan kepada Anda contoh desain dan implementasinya, tetapi sebelum itu, mari kita bicara tentang memecahkan masalah secara keseluruhan.
Cara termudah adalah dengan menggunakan semacam perpustakaan yang memenuhi kebutuhan kita. Sekarang jangan salah paham, saya pendukung besar pendekatan "jangan menemukan kembali roda". Ada perpustakaan open source yang hebat, dan ketika saya perlu mengunggah gambar atau mengimplementasikan REST API, Glide / Picasso dan Retrofit akan banyak membantu saya.
Tetapi ketika Anda perlu menerapkan beberapa desain yang tidak biasa, ini tidak selalu merupakan pilihan terbaik. Anda perlu menghabiskan waktu mencari perpustakaan yang baik dan didukung yang akan melakukan hal serupa. Maka Anda perlu melihat ke dalam kode untuk memastikan bahwa sesuatu yang memadai ditulis di sana. Anda perlu mencurahkan lebih banyak waktu untuk memahami pengaturan dan konfigurasi yang dapat Anda kelola untuk menggunakan perpustakaan dalam tugas-tugas Anda. Dan jujur saja, kemungkinan besar, perpustakaan tidak akan memenuhi kebutuhan Anda 100%, dan Anda harus membuat beberapa kompromi dengan desainer.
Karena itu, saya katakan bahwa sering kali lebih mudah dan lebih baik untuk membuat komponen View
Anda sendiri. Ketika saya mengatakan "komponen View
asli", maksud saya adalah ekstensi dari kelas View
, menimpa metode onDraw()
dan menggunakan Paint
and Canvas
untuk menggambar komponen View
. Ini mungkin tampak menakutkan jika Anda belum pernah melakukannya sebelumnya, karena kelas-kelas ini memiliki banyak metode dan properti, tetapi Anda dapat fokus pada yang utama:
canvas.drawRect()
- menentukan koordinat sudut dan menggambar persegi panjang;
canvas.drawRoundRect()
- opsional menentukan radius, dan sudut-sudut persegi panjang akan dibulatkan;
canvas.drawPath()
adalah cara yang lebih kompleks, tetapi juga lebih kuat untuk membuat bentuk Anda sendiri menggunakan garis dan kurva;
canvas.drawText()
- untuk menggambar teks di atas kanvas (menggunakan Paint
Anda dapat mengontrol ukuran, warna, dan properti lainnya);
canvas.drawCircle()
- tentukan titik pusat dan jari-jari dan dapatkan lingkaran;
canvas.drawArc()
- tentukan persegi panjang pembatas, serta sudut awal dan belok untuk menggambar busur;
paint.style
- menunjukkan apakah bentuk yang digambar akan diisi, dilingkari, atau keduanya;
paint.color
- menunjukkan warna (termasuk transparansi);
paint.strokeWidth
- mengontrol lebar untuk bentuk goresan;
paint.pathEffect
- memungkinkan Anda untuk mempengaruhi geometri gambar yang digambar;
paint.shader
- memungkinkan Anda menggambar gradien.
Ingat, kadang-kadang Anda mungkin perlu menggunakan API lain, tetapi bahkan setelah menguasai metode ini, Anda bisa menggambar bentuk yang sangat kompleks.
Contoh praktis
Berikut adalah desain yang Pepper tawarkan kepada kami:

Ada banyak hal menarik di sini, tapi mari kita semua menjadi potongan-potongan kecil.
Langkah 1. Hitung posisi penanda
private fun calcPositions(markers: List<Marker>) { val max = markers.maxBy { it.value } val min = markers.minBy { it.value } pxPerUnit = chartHeight / (max - min) zeroY = max * pxPerUnit + paddingTop val step = (width - 2 * padding - scalesWidth) / (markers.size - 1) for ((i, marker) in markers.withIndex()) { val x = step * i + paddingLeft val y = zeroY - entry.value * pxPerUnit marker.currentPos.x = x marker.currentPos.y = y } }
Kami menemukan nilai minimum dan maksimum, menghitung rasio piksel per unit, ukuran langkah horizontal antara marker dan posisi X dan Y.
Langkah 2. Gambar gradien

Kami membuat bentuk mulai dari tepi kiri, menggambar garis antara setiap penanda dan mengakhiri bentuk di titik awal. Kemudian gambar bentuk ini menggunakan cat dengan gradasi shader.
Langkah 3. Gambarlah sebuah kisi

Kami mengatur cat sehingga menarik dengan garis putus-putus. Kemudian kami menggunakan siklus bahasa Kotlin khusus, yang memungkinkan kami untuk mengulangi marker dalam langkah 7 (jumlah hari dalam seminggu). Untuk setiap penanda, kita ambil koordinat X dan menggambar garis putus-putus vertikal dari atas grafik ke zeroY
.
Langkah 4. Gambarlah sebuah grafik dan spidol

private fun drawLineAndMarkers(canvas: Canvas) { var previousMarker: Marker? = null for (marker in markers) { if (previousMarker != null) {
Kami pergi melalui penanda, menggambar lingkaran penuh untuk masing-masing dan garis sederhana dari penanda sebelumnya ke yang sekarang.
Langkah 5. Gambar tombol minggu

private fun drawWeeks(canvas: Canvas) { for ((i, week) in weeks.withIndex()) { textPaint.getTextBounds(week, 0, week.length, rect) val x = middle(i) val y = zeroY + rect.height() val halfWidth = rect.width() / 2f val halfHeight = rect.height() / 2f val left = x - halfWidth - padding val top = y - halfHeight - padding val right = x + halfWidth + padding val bottom = y + halfHeight + padding rect.set(left, top, right, bottom) paint.color = bgColor paint.style = FILL canvas.drawRoundRect(rect, radius, radius, paint) paint.color = strokeColor paint.style = STROKE canvas.drawRoundRect(rect, radius, radius, paint) canvas.drawText(week, x, keyY, textPaint) } }
Kita membahas tanda-tanda minggu, menemukan koordinat X tengah minggu dan mulai menggambar tombol berlapis-lapis: pertama kita menggambar latar belakang dengan sudut bulat, lalu perbatasan dan, akhirnya, teks. Kami menyesuaikan cat sebelum menggambar setiap lapisan.
Langkah 6. Gambar penanda angka di sebelah kanan

private fun drawGraduations(canvas: Canvas) { val x = markers.last().currentPos.x + padding for (value in graduations) { val y = zeroY - scale * pxPerUnit val formatted = NumberFormat.getIntegerInstance().format(value) canvas.drawText(formatted, x, y, textPaint) } }
Koordinat X adalah posisi marker terakhir ditambah beberapa lekukan. Koordinat Y dihitung menggunakan rasio piksel per unit. Kami memformat angka menjadi string (jika perlu, tambahkan pemisah ribuan) dan menggambar teks.
Itu saja, sekarang onDraw()
akan terlihat seperti ini:
override fun onDraw(canvas: Canvas) { drawGradient(canvas) drawGuidelines(canvas) drawLineAndMarkers(canvas) drawWeeks(canvas) drawGraduations(canvas) }
Dan menggabungkan layer akan memberi kita hasil yang diinginkan:

Ringkasan
- Jangan takut untuk membuat komponen
View
Anda sendiri (jika perlu). - Pelajari API
Canvas
dan Paint
dasar. - Hancurkan desain Anda menjadi lapisan-lapisan kecil dan gambar masing-masing secara independen.
Adapun poin terakhir, bagi saya ini adalah salah satu pelajaran pemrograman terbaik secara umum: ketika dihadapkan dengan tugas yang besar dan kompleks, pecah menjadi tugas yang lebih kecil, lebih sederhana.