Освой Kotlin играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Android KTX

Kotlin упростил написание кода по сравнению с Java, но нет предела совершенству. Благодаря гибкости Kotlin можно создавать расширения к существующим классам и сделать код ещё проще. Чтобы не изобретать велосипед каждый раз, наиболее удачные примеры решили выделить в отдельную группу, которая получила название Android KTX.

Подключаем библиотеку (один из вариантов).


// добавьте в секцию android
kotlinOptions {
    jvmTarget = JavaVersion.VERSION_1_8.toString()
}

// для секции dependencies
implementation 'androidx.core:core-ktx:1.2.0'

//fragment
implementation 'androidx.fragment:fragment-ktx:<version>'

// pallete
implementation 'androidx.pallete:palette-ktx:<version>'

//SQLite
implementation 'androidx.sqlite:sqlite-ktx:<version>'

// collections
implementation 'androidx.collection:collection-ktx:<version>'

Примеры

Несколько примеров для знакомства.

Uri

Если у вас есть строка, которую нужно перевести в Uri, то писали следующую конструкцию.


val uriString = "http://developer.alexanderklimov.ru/android"
val uriOld = Uri.parse(uriString)
Log.d("KTX", uri.host)

Теперь можно писать проще. Код стал читаемым.


val uriString = "http://developer.alexanderklimov.ru/android"
val uri = uriString.toUri()
Log.d("KTX", uri.host)

SharedPreferences

При работе с файлами настройки приходится писать однотипный код.


sharedPreferences.edit()
        .putBoolean(key, value)
        .apply()

Сокращаем код. Разница не слишком большая, но выглядит опрятнее.


sharedPreferences.edit { 
    putBoolean(key, value) 
}

Bitmap/Drawable


// get a drawable from resources
va myDrawable = ContextCompat.getDrawable(context, R.drawable.cat)

// convert the drawable to a bitmap
val bitmap = myDrawable.toBitmap()

Масштабируем Bitmap с помощью scale()

Удобная функция scale() поможет изменить размеры картинки.


// get bitmap from drawable resource
val bitmap = BitmapFactory.decodeResource(resources,R.drawable.table_cat)

// scale bitmap using android ktx
val scaledBitmap = bitmap.scale(
    300, // width
    300, // height
    false // filter
)

button.setOnClickListener {
    imageView.setImageBitmap(scaledBitmap)
}

Смотри также пример Пропорциональное изменение размеров по ширине или высоте

View.drawToBitmap

Конвертирует компонент в изображение. Создадим карточку CardView и созданное изображение карточки поместим в ImageView.


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.501"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button"
        tools:srcCompat="@tools:sample/avatars[13]" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:backgroundTint="#333399"
        android:text="Card To Bitmap"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/cardView" />

    <androidx.cardview.widget.CardView
        android:id="@+id/cardView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="24dp"
        android:layout_marginEnd="8dp"
        android:elevation="8dp"
        app:cardBackgroundColor="#3B2F2F"
        app:cardCornerRadius="4dp"
        app:contentPadding="12dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/textView"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:background="#B0BF1A"
                android:fontFamily="monospace"
                android:gravity="center"
                android:padding="16dp"
                android:text="View To Bitmap"
                android:textAppearance="@style/TextAppearance.AppCompat.Large"
                android:textSize="35sp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

Код для щелчка кнопки.


package ru.alexanderklimov.ktx

import android.graphics.Bitmap
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.drawToBitmap
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)

        button.setOnClickListener {
            // draw a bitmap from cardView
            val bitmap: Bitmap = cardView.drawToBitmap(Bitmap.Config.ARGB_8888)

            // show to generated bitmap to imageView
            imageView.setImageBitmap(bitmap)
        }
    }
}

Span


val string = buildSpannedString {
	append("no styling text")
	bold {
		append("bold")
		italic { append("bold and italic) }
	}
	inSpans(RelativeSizeSpan(2f), QuoteSpan()){
		append("double sized quote text")
	}
}

Bundle


val bundle = bundleOf(
    "KEY_INT" to 1,
	"KEY_LONG" to 2L,
	"KEY_BOOLEAN" to true,
	"KEY_NULL" to null,
	"KEY_ARRAY" to arrayOf(1, 2, 3)
)

Обратите внимание, что в примерах используется пакет androidx, это позволит не путать их с стандартными пакетами android.

Другие примеры из разных источников.


//default usage
supportFragmentManager
    .beginTransaction()
	.replace(
	    R.id.my_fragment_container,
		myFragment,
		FRAGMENT_TAG
		)
	.commitAllowingStateLoss()
	
// using androidx.fragment:fragment-ktx
supportFragmentManager.transaction(
    allowStateLosss = true
	) {
	    replace(
		    R.id.my_fragment_container,
			myFragment,
			FRAGMENT_TAG)
	}

// using androidx.core:core-ktx
val s = "Hello, Spans!".toSpannable()

val bold = StyleSpan(BOLD)
s += bolds[7..12] = ForegroundColorSpan(Color.RED)

// using androidx.core:core-ktx
menu.forEach{
  // do action
}

// check if an itme is in the menu and remove it
if(menuItem in menu) menu -= menuItem

// default usage
db.beginTransaction()
try{
 // insert data
 db.setTransactionSuccessful()
 } finally {
   db.endTransaction()
   }
   
// using androidx.sqlite:sqlite-ktx
db.transaction {
  // insert data
}

Дополнительные материалы

Недавно появилась отдельная страница со всеми классами с использованием KTX.

Реклама