Egendefinerte Views
Tegn egendefinerte brukergrensesnittkomponenter fra grunnen av. Utvid View, implementer onMeasure og onDraw med Canvas og Paint, definer egendefinerte XML-attributter, og bygg sammensatte visninger.
Egendefinerte Views er en gratis leksjon i Android Academy på CoddyKit. Dette er leksjon 3 av 5. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Android Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Android Academy inneholder totalt 5 leksjoner.
Hvorfor egendefinerte visninger?
Noen ganger gjør de innebygde Android-visningene ikke nøyaktig det De trenger. Egendefinerte visninger lar Dem:
- Tegne former, grafer, fremdriftsringer eller diagrammer som ikke finnes i SDK-et
- Opprette profilerte UI-komponenter som brukes konsekvent i hele appen
- Kombinere flere visninger til én gjenbrukbar komponent (Compound View)
- Oppnå bedre ytelse ved å fjerne nestede oppsetthierarkier
Utvide View
Opprett en egendefinert visning ved å utvide View (eller en underklasse som ImageView). Overstyr den nødvendige konstruktøren:
class CircleProgressView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
var progress: Float = 0f
set(value) {
field = value.coerceIn(0f, 100f)
invalidate() // trigger redraw
}
// onMeasure and onDraw go here
}onMeasure()
onMeasure() forteller den overordnede visningen hvor stor denne visningen ønsker å være. Kall alltid setMeasuredDimension() til slutt:
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val desiredSize = 200 // dp → pixels
val px = (desiredSize * resources.displayMetrics.density).toInt()
val width = resolveSize(px, widthMeasureSpec)
val height = resolveSize(px, heightMeasureSpec)
// Square: same width and height
val size = minOf(width, height)
setMeasuredDimension(size, size)
}Paint — tegneverktøyet
Et Paint-objekt inneholder stilinformasjon for tegning (farge, strekbredde, kantutjevning). Opprett det én gang — aldri inne i onDraw():
class CircleProgressView ... : View(...) {
// Create Paint in init, not in onDraw!
private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.LTGRAY
style = Paint.Style.STROKE
strokeWidth = 20f
strokeCap = Paint.Cap.ROUND
}
private val progressPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.parseColor("#6750A4")
style = Paint.Style.STROKE
strokeWidth = 20f
strokeCap = Paint.Cap.ROUND
}
}onDraw() — tegne visningen
onDraw(canvas) kalles hver gang visningen må tegnes på nytt. Bruk Canvas til å tegne former, tekst og punktgrafikk:
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val cx = width / 2f
val cy = height / 2f
val radius = (minOf(width, height) / 2f) - 30f
// Draw background circle
canvas.drawCircle(cx, cy, radius, backgroundPaint)
// Draw progress arc
val oval = RectF(cx - radius, cy - radius, cx + radius, cy + radius)
val sweepAngle = 360f * (progress / 100f)
canvas.drawArc(oval, -90f, sweepAngle, false, progressPaint)
}invalidate() kontra requestLayout()
To metoder for å utløse en oppdatering:
invalidate()— tegner visningen på nytt (kalleronDraw). Bruk denne når innholdet endres, men størrelsen er den samme.requestLayout()— måler og tegner visningen på nytt (kaller førstonMeasureog deretteronDraw). Bruk denne når visningens størrelse endres.
Egendefinerte attributter (attrs.xml)
Definer egendefinerte XML-attributter slik at visningen kan konfigureres fra oppsettsfiler:
<!-- res/values/attrs.xml -->
<resources>
<declare-styleable name="CircleProgressView">
<attr name="progressColor" format="color" />
<attr name="trackColor" format="color" />
<attr name="strokeWidth" format="dimension" />
<attr name="progress" format="float" />
</declare-styleable>
</resources>Lese egendefinerte attributter
Les attrs i konstruktøren ved hjelp av obtainStyledAttributes:
init {
context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView).use { ta ->
progressPaint.color = ta.getColor(
R.styleable.CircleProgressView_progressColor,
Color.parseColor("#6750A4")
)
backgroundPaint.color = ta.getColor(
R.styleable.CircleProgressView_trackColor,
Color.LTGRAY
)
val sw = ta.getDimension(R.styleable.CircleProgressView_strokeWidth, 20f)
progressPaint.strokeWidth = sw
backgroundPaint.strokeWidth = sw
progress = ta.getFloat(R.styleable.CircleProgressView_progress, 0f)
}
}Bruke den egendefinerte visningen i XML
Bruk den egendefinerte visningen i oppsett-XML med full klassenavnesti og egendefinerte attributter:
<!-- In any layout XML -->
<com.example.myapp.CircleProgressView
android:id="@+id/progressView"
android:layout_width="120dp"
android:layout_height="120dp"
app:progress="65"
app:progressColor="@color/primary"
app:trackColor="@color/surface_variant"
app:strokeWidth="12dp" />
<!-- Control in code: -->
binding.progressView.progress = 75fCompound Views
En compound view kombinerer eksisterende visninger til én gjenbrukbar komponent. Utvid en oppsettsklasse som LinearLayout:
class SearchBarView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : LinearLayout(context, attrs) {
private val binding = ViewSearchBarBinding.inflate(LayoutInflater.from(context), this)
init {
orientation = HORIZONTAL
binding.ivSearch.setOnClickListener {
onSearchClick?.invoke(binding.etSearch.text.toString())
}
}
var onSearchClick: ((String) -> Unit)? = null
fun setHint(hint: String) { binding.etSearch.hint = hint }
}Tegne tekst
Tegn tekst på et Canvas med drawText(). Sentrer den nøyaktig ved hjelp av Paint.getFontMetrics():
private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.BLACK
textSize = 48f
textAlign = Paint.Align.CENTER
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val cx = width / 2f
val cy = height / 2f
// Vertically center the text:
val fm = textPaint.fontMetrics
val textY = cy - (fm.ascent + fm.descent) / 2f
canvas.drawText("${progress.toInt()}%", cx, textY, textPaint)
}Hurtigsjekk
Hvilken metode bør De kalle for å tegne den egendefinerte visningen på nytt når dataene endres, men størrelsen forblir den samme?
Oppsummering: Egendefinerte visninger
De kan nå tegne hva som helst på skjermen:
- Utvid
Viewmed@JvmOverloads constructor onMeasure()— rapporter ønsket størrelse medsetMeasuredDimension()Paint— definer stil; opprett én gang, ikke inne ionDraw()onDraw(canvas)— tegn sirkler, buer, tekst og punktgrafikkinvalidate()for å tegne på nytt,requestLayout()for å måle på nytt- Egendefinerte attributter via
attrs.xmlfor XML-konfigurasjon - Compound view — utvid et oppsett for å kombinere eksisterende visninger
Neste: Gjør brukergrensesnittet levende med animasjoner og overganger.
Lær deg Kotlin med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 36
- Leksjoner
- 152
Ofte stilte spørsmål
Er leksjonen «Egendefinerte Views» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Android Academy, inkludert «Egendefinerte Views», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Android Academy inneholder totalt 5 leksjoner.
Hva lærer jeg i «Egendefinerte Views»?
Tegn egendefinerte brukergrensesnittkomponenter fra grunnen av. Utvid View, implementer onMeasure og onDraw med Canvas og Paint, definer egendefinerte XML-attributter, og bygg sammensatte visninger. Du øver på Android Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Android Academy?
Ingen tidligere erfaring er nødvendig. Android Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 5.
Hvor lang tid tar leksjonen «Egendefinerte Views»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Android Academy-leksjonen?
Ja. Alle Android Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Grunnleggende Material Design
- Temaer og stiler
- Egendefinerte Views
- Animasjoner og overganger
- Bunnnavigasjon og faner